zeek/testing/btest/language/table-iterate-record-key-default.zeek

103 lines
2 KiB
Text

# @TEST-DOC: Iterating over tables with record keys would previously evaluate &default during each iteration. Ensure this isn't happening. Regression test for #3267.
# @TEST-EXEC: zeek -b %INPUT >output
# @TEST-EXEC: btest-diff output
global seq = 0;
function my_seq(): count {
print seq, "my_seq() invoked";
return ++seq;
}
type R: record {
id: count &default=my_seq();
};
global tbl: table[R] of count;
print seq, "populating table, expecting 4 my_seq() invocations";
tbl[R()] = 1;
tbl[R()] = 2;
tbl[R()] = 3;
tbl[R()] = 4;
print seq, "iterating table, expecting no my_seq() invocations";
for ( [r], c in tbl )
print seq, "it", r, c;
print seq, "done";
# @TEST-START-NEXT
#
# This acts subtly different - my_seq() is called maybe for the [r] local
# in the for loop?!
global seq = 0;
function my_seq(): count {
print seq, "my_seq() invoked";
return ++seq;
}
type R: record {
id: count &default=my_seq();
};
global tbl: table[R] of count;
event zeek_init()
{
print seq, "populating table, expecting 4 my_seq() invocations";
tbl[R()] = 1;
tbl[R()] = 2;
tbl[R()] = 3;
tbl[R()] = 4;
print seq, "iterating table, expecting no my_seq() invocations";
for ( [r], c in tbl )
print seq, "it", r, c;
print seq, "done";
}
print seq, "done parsing";
# @TEST-START-NEXT
#
# table[R] of R
global seq = 0;
function my_seq(): count {
print seq, "my_seq() invoked";
return ++seq;
}
type R: record {
id: count &default=my_seq();
};
global tbl: table[R] of R;
event zeek_init()
{
print seq, "populating table, expecting 8 my_seq() invocations";
# The following structure is used to avoid order-of-evaluation
# ambiguity. If we use "tbl[R()] = R()" statements then script
# optimization might create different table indices/values than
# interpreted execution.
local v = R();
tbl[R()] = v;
v = R();
tbl[R()] = v;
v = R();
tbl[R()] = v;
v = R();
tbl[R()] = v;
print seq, "iterating table, expecting no my_seq() invocations";
for ( [r1], r2 in tbl )
print seq, "it", r1, r2;
print seq, "done";
}
print seq, "done parsing";