Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a #[test_case] attribute #6816

Open
aakoshh opened this issue Dec 14, 2024 · 0 comments
Open

Add a #[test_case] attribute #6816

aakoshh opened this issue Dec 14, 2024 · 0 comments
Labels
enhancement New feature or request

Comments

@aakoshh
Copy link
Contributor

aakoshh commented Dec 14, 2024

Problem

I wanted to test the behaviour of the ACIR optimisers using a #[test] in #6781 by making an integration test and put it under test_programs/noir_test_success, writing a test such as this:

fn main(a: Field, b: Field, e: Field) {
    let c = <complex expression using a and b>;
    assert_eq(c, e, "oh no, foo!");
}

#[test(should_fail_with = "foo")]
fn test_foo() {
  main(10, 20, 100);
}

My goal was to see some of optimisations reorder the expressions and lose track of where the assertion message was.
However, when I looked at the final ACIR there was just nothing to reorder as it all became just 1 ACIR opcode.

If instead of nargo test I used nargo compile, I could see there were multiple ACIR opcodes, but because test_foo gives the compiler extra information about a, b and e, it was able to perform deeper optimisations on it. But that meant I was testing a different circuit, although the side effects should be the same.

Ideally we want the option to test the code as it would be if it was invoked with execute. I can see the value in #[test] resulting in a circuit that is optimised for the exact code that appears in the test itself, but I would also like the option of writing a unit test to verify the behaviour of the actual circuit, without having to write a full integration test that takes its inputs from Prover.toml; in this instance that would not have worked anyway because I wanted to the execution to fail with an expected message, and I don't think the test_programs/execute_success handles that case.

NB the SSA was the same in both cases, it was the ACIR optimisation that worked differently. The std::hint::black_box hint also doesn't work on this, because its effect is limited to the SSA pass.

Happy Case

My proposal is to add an attribute similar to test_case which would be handled by nargo test to:

  1. Find these like other test functions that take input
  2. Instead of passing them to the fuzzer, parse the ABI encoded inputs from the attribute and invoke the test with those

In the above example, it would look something like this:

#[test(should_fail_with = "foo")]
#[test_case("10", "20", "100")]
fn test_foo(a: Field, b: Field, c: Field) {
  main(a, b, c);
}

It could also support multiple such attributes (with an optional description), to invoke the test with multiple scenarios, similar to the Rust crate.

I left the #[test] there so that it can still provide the place for should_fail_with; this is different from the Rust version. The Rust version is also macro based, but in our case it would need to be supported by the framework itself, so that the compiler would treat the inputs as opaque witnesses.

Workaround

Yes

Workaround Description

The workaround in this case was to move the a, b and e variables into an input position so they don't get eliminated by the merge expression optimiser. When I did, the test was handled by the fuzzer, but then that one executes it 100 times, which I don't need, and I cannot specify the inputs.

Additional Context

No response

Project Impact

None

Blocker Context

No response

Would you like to submit a PR for this Issue?

Maybe

Support Needs

No response

@aakoshh aakoshh added the enhancement New feature or request label Dec 14, 2024
@github-project-automation github-project-automation bot moved this to 📋 Backlog in Noir Dec 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: 📋 Backlog
Development

No branches or pull requests

1 participant