-
Notifications
You must be signed in to change notification settings - Fork 206
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
In #[test]
s, stop assert();
swallowing all println();
output, add assert();
template message strings and default parameter output
#3207
Comments
For the given Noir code: fn check_bb_from_fen(board: Board, check_bbs: [u64; 8]) {
let mut idx = 0;
for bb in board.pieces {
// FIXME: No expressions in template strings so pollution with temp
// values is required.
let bb_data = bb.data;
let check_bb = check_bbs[idx];
// assert(bb_data == check_bb);
if bb_data == check_bb {
println(f"t-0x01");
} else {
println(f"t-0x00 Expected values to be equal: '{bb_data}' == '{check_bb}' / bb index: u-{idx}");
}
idx += 1;
}
} The output if using that commented Remember, any print-based debugging is destroyed by the assertion failure. What values are My wrapping script which I hope is temporary only shows this output: Now I can actually see what is going on. |
I think the main issue here is for asserts we issue an error if the constraint is known to always be false before running the program. Since printlns are only run at execution time, their output will only show if the assert in question is using values known only at runtime (execution time). We can probably move the failed assert message to a warning (if at all?) at compile time and keep the runtime error for these asserts. That way the program will still run after the warning and any printlns will be issued. |
When I create a new file containing the example: #[test]
fn main() {
let foo = 5;
let bar = 2;
println("Blah blah");
println(f"My foo is {foo} and my bar is {bar}");
assert(foo == bar);
} And run it via
Running with |
I suppose my first followup is this: why is Secondly that works if your circuit is a
Hiding the output without passing |
Because in my example I named the function
The answer is yes, actually. Unless a function is actually called in your program it will never be in your resulting circuit. The reasoning is when compiling a program to a circuit, there is no such thing as functions in our ACIR backend circuit representation. Thus, to compile a program we are forced to inline every single function call (also unroll all loops). This is why loops and recursion must be known to terminate at compile-time and you'll get an error otherwise (the "error" for unbounded recursion is just a panic though, unfortunately).
Hmm, I think I was wrong in my last test. I'm getting that the output was eaten in a bin target as well now. For context I was originally able to replicate this and had a fix in a pull request, but seemed to have been getting the output again even after reverting the changes, so I closed the pull request. Sometimes the caching of the program in the target directly can make things more difficult to test. I'll re-open the PR since trying it again now it does bring back the output for me.
Right - I don't dispute this. It looks like it's being hidden for the same reason as the bin target was, so my PR should fix both cases once merged. As for why |
Problem
I feel using
assert();
in#[test]
s and generally testing in Noir is frustrating currently in all but the most trivial of cases, context:assert();
swallows all printable output before it prints meaning the only way to inspect intermediate values is to comment theassert();
and stub the test with something likeassert(0 == 0);
. This may be fine for very trivial cases but if tests are done over arrays of data it results in a lot of noise. Proposed fix:assert();
should NOT stopprintln();
from outputting and should respect it's place within source files instead of being (what I assume is) optimistically executed and/or blocking said output regardless.assert();
can now take optional assertion messages. These are nice but I posit only useful in trivial circumstances because they only accept literal string values. This is intimately tied to the next problem.assert();
does not show the failed constraint values in tests. This is the big one. Swallowingprintln();
statements would be fine, andassert();
only accepting string literal message values would be fine if it showed the values that failed assertion. If you have a literal assert as follows:assert(5 == 2);
then this is no issue as it is extremely obvious that 5 does not equal 2. Now imagine one of those values is a parameter or a variableassert(foo == 2);
. Still mostly fine, it's obvious thatfoo
does not equal 2. What value isfoo
though? You cannot get this information. You cannotprintln();
this information without commenting out the assert. You cannot message this information viaassert(foo == 2, f"Expected {foo} to equal 2");
as that's not a string literal. Now imagine you have two computed valuesassert(foo == bar);
. What values are these? Impossible to tell unless you make aforementioned significant modifications to your code simply to inspect a failing test case where said modifications are mutually exclusive with having a test in the first place! Proposed fix: when anassert();
fails in a#[test]
it should print the values of it's parameters.Happy Case
Template assertion messages
This code:
Should compile and print in the existing assertion error format:
and NOT:
Assertion parameter values output by default
Should print in the existing assertion error format:
and NOT:
Assertion should NOT swallow println output
Should print a better assertion failure as already described and keep the println output:
and NOT:
Alternatives Considered
I augment a script I have to produce saner Noir output but it requires stubbing out
assert()
since usingassert()
destroys everything. Script here: https://github.com/tsujp/tikan/blob/master/circuit/lib/test.shAdditional Context
No response
Would you like to submit a PR for this Issue?
Maybe
Support Needs
No response
The text was updated successfully, but these errors were encountered: