Stmt: Rework assertion hooks break semantics

Using break in either of the hooks allows to suppress the default reporter
error message rather than suppressing solely based on the existence of an
assertion_failure() handler.
This commit is contained in:
Arne Welzel 2023-06-13 15:23:45 +02:00
parent 25ea678626
commit 0b0f6e509f
9 changed files with 40 additions and 26 deletions

View file

@ -944,11 +944,10 @@ type Backtrace: vector of BacktraceElement;
## A hook that is invoked when an assert statement fails. ## A hook that is invoked when an assert statement fails.
## ##
## If no such hook is implemented, a default reporter error message is ## By default, a reporter error message is logged describing the failing
## logged similar to how scripting errors are reported. ## assert similarly to how scripting errors are reported after invoking
## ## this hook. Using the :zeek:see:`break` statement in an assertion_failure
## If assertion_failure hook handlers exist, the default reporter error ## hook handler allows to suppress this message.
## message is suppressed to allow for customized error messaging.
## ##
## cond: The string representation of the condition. ## cond: The string representation of the condition.
## ##
@ -964,7 +963,11 @@ type assertion_failure: hook(cond: string, msg: string, bt: Backtrace);
## ##
## This is a potentially expensive hook meant to be used by testing ## This is a potentially expensive hook meant to be used by testing
## frameworks to summarize assert results. In a production setup, ## frameworks to summarize assert results. In a production setup,
## this hook is likely deterimental to performance. ## this hook is likely detrimental to performance.
##
## Using the :zeek:see:`break` statement within an assertion_failure hook
## handler allows to suppress the reporter error message generated for
## failing assert statements.
## ##
## result: The result of evaluating **cond**. ## result: The result of evaluating **cond**.
## ##

View file

@ -1928,16 +1928,22 @@ ValPtr AssertStmt::Exec(Frame* f, StmtFlowType& flow)
bt->Insert(0, assert_elem); bt->Insert(0, assert_elem);
} }
// Breaking from either the assertion_failure() or assertion_result()
// hook can be used to suppress the default log message.
bool report_error = true;
if ( run_result_hook ) if ( run_result_hook )
assertion_result_hook->Invoke(zeek::val_mgr->Bool(assert_result), cond_val, msg_val, bt); report_error &= assertion_result_hook
->Invoke(zeek::val_mgr->Bool(assert_result), cond_val, msg_val, bt)
->AsBool();
if ( assert_result ) if ( assert_result )
return Val::nil; return Val::nil;
// Run the installed failure hooks, or log a default message.
if ( run_failure_hook ) if ( run_failure_hook )
assertion_failure_hook->Invoke(cond_val, msg_val, bt); report_error &= assertion_failure_hook->Invoke(cond_val, msg_val, bt)->AsBool();
else
if ( report_error )
{ {
std::string reporter_msg = util::fmt("assertion failure: %s", cond_val->CheckString()); std::string reporter_msg = util::fmt("assertion failure: %s", cond_val->CheckString());
if ( msg_val->Len() > 0 ) if ( msg_val->Len() > 0 )

View file

@ -1,7 +1,7 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
assertion_failure, to_count("5") == 4, 5 is not 4 assertion_failure, to_count("5") == 4, 5 is not 4
assert <...>/assert-hook.zeek:19 assert <...>/assert-hook.zeek:21
f <...>/assert-hook.zeek:23 f <...>/assert-hook.zeek:25
g <...>/assert-hook.zeek:24 g <...>/assert-hook.zeek:26
h <...>/assert-hook.zeek:28 h <...>/assert-hook.zeek:30
zeek_init <none>:0 zeek_init <none>:0

View file

@ -1,2 +1,3 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
error in <...>/assert-hook.zeek, line 12: assertion failure: F (terminate me!)
received termination signal received termination signal

View file

@ -1,8 +1,8 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
assertion_result T at <...>/assert-hook.zeek:24: md5_hash("") == "d41d8cd98f00b204e9800998ecf8427e" assertion_result T at <...>/assert-hook.zeek:25: md5_hash("") == "d41d8cd98f00b204e9800998ecf8427e"
assertion_result T at <...>/assert-hook.zeek:29: sha1_hash("") == "da39a3ee5e6b4b0d3255bfef95601890afd80709" assertion_result T at <...>/assert-hook.zeek:30: sha1_hash("") == "da39a3ee5e6b4b0d3255bfef95601890afd80709"
assertion_result F at <...>/assert-hook.zeek:34: sha1_hash("") == "wrong" assertion_result F at <...>/assert-hook.zeek:35: sha1_hash("") == "wrong"
assertion_failure at <...>/assert-hook.zeek:34: sha1_hash("") == "wrong" assertion_failure at <...>/assert-hook.zeek:35: sha1_hash("") == "wrong"
assertion_result F at <...>/assert-hook.zeek:39: md5_hash("") == "wrong" assertion_result F at <...>/assert-hook.zeek:40: md5_hash("") == "wrong"
assertion_failure at <...>/assert-hook.zeek:39: md5_hash("") == "wrong" assertion_failure at <...>/assert-hook.zeek:40: md5_hash("") == "wrong"
2 of 4 assertions failed 2 of 4 assertions failed

View file

@ -1,3 +1,5 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
expression error in <...>/assert-hook.zeek, line 15: field value missing (get_current_packet_header()$ip) expression error in <...>/assert-hook.zeek, line 15: field value missing (get_current_packet_header()$ip)
expression error in <...>/assert-hook.zeek, line 17: field value missing (get_current_packet_header()$ip) expression error in <...>/assert-hook.zeek, line 17: field value missing (get_current_packet_header()$ip)
error in <...>/assert-hook.zeek, line 17: assertion failure: 2 + 2 == 5 (<error eval cat(get_current_packet_header()$ip)>)
error in <...>/assert-hook.zeek, line 22: assertion failure: 2 + 2 == 5 ({"msg":"false and works"})

View file

@ -1,3 +1 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
error in <...>/assert-hook.zeek, line 12: assertion failure: 2 + 2 == 5 (this is false)
error in <...>/assert-hook.zeek, line 18: assertion failure: 2 + 2 == 5 (this is false)

View file

@ -1 +1,2 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
error in <...>/assert-hook.zeek, line 15: assertion failure: 1 != 1

View file

@ -4,7 +4,7 @@
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out # @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff .stderr # @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff .stderr
# Hook calls break after logging out some information. # Hook is not calling break: Reporter log is produced.
hook assertion_failure(cond: string, msg: string, bt: Backtrace) hook assertion_failure(cond: string, msg: string, bt: Backtrace)
{ {
print "assertion_failure", cond, msg, bt[0]$file_location, bt[0]$line_location; print "assertion_failure", cond, msg, bt[0]$file_location, bt[0]$line_location;
@ -17,7 +17,7 @@ event zeek_init()
} }
@TEST-START-NEXT @TEST-START-NEXT
# Test the backtrace location # Test the backtrace location, also calling break to suppress reporter log.
hook assertion_failure(cond: string, msg: string, bt: Backtrace) hook assertion_failure(cond: string, msg: string, bt: Backtrace)
{ {
print "assertion_failure", cond, msg; print "assertion_failure", cond, msg;
@ -29,6 +29,8 @@ hook assertion_failure(cond: string, msg: string, bt: Backtrace)
print fmt("%s%s %s:%s", indent, e$function_name, file_name, line_number); print fmt("%s%s %s:%s", indent, e$function_name, file_name, line_number);
indent = fmt("%s ", indent); indent = fmt("%s ", indent);
} }
break;
} }
@ -102,6 +104,7 @@ hook assertion_failure(cond: string, msg: string, bt: Backtrace)
cond, |msg| > 0 ? " - " : "", msg); cond, |msg| > 0 ? " - " : "", msg);
++assertion_failures; ++assertion_failures;
break;
} }
hook assertion_result(result: bool, cond: string, msg: string, bt: Backtrace) hook assertion_result(result: bool, cond: string, msg: string, bt: Backtrace)
@ -170,11 +173,11 @@ event zeek_done()
} }
@TEST-START-NEXT @TEST-START-NEXT
# Only implementing assertion_result() falls back to default # Breaking in assertion_result() also suppresses the reporter errors.
# reporter errors.
hook assertion_result(result: bool, cond: string, msg: string, bt: Backtrace) hook assertion_result(result: bool, cond: string, msg: string, bt: Backtrace)
{ {
print "assertion_result", result, cond, msg, bt[0]$file_location, bt[0]$line_location; print "assertion_result", result, cond, msg, bt[0]$file_location, bt[0]$line_location;
break;
} }
event zeek_init() event zeek_init()