tests added for new capture-by-reference closure semantics & errors

This commit is contained in:
Vern Paxson 2021-01-04 14:38:12 -08:00
parent 4884b191e8
commit 35421b07f1
8 changed files with 503 additions and 0 deletions

View file

@ -0,0 +1,10 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
error in <...>/closure-binding-errors.zeek, line 12: a is captured but not used inside lambda (function(){ print no a!})
error in <...>/closure-binding-errors.zeek, line 13: no such local identifier: a2
error in <...>/closure-binding-errors.zeek, line 14: b is used inside lambda but not captured (function(){ print b})
error in <...>/closure-binding-errors.zeek, line 14: a is captured but not used inside lambda (function(){ print b})
error in <...>/closure-binding-errors.zeek, line 15: a is captured but not used inside lambda (function(){ print b})
error in <...>/closure-binding-errors.zeek, line 16: b listed multiple times in capture (function(){ print b})
error in <...>/closure-binding-errors.zeek, line 18: cannot specify global in capture: c
error in <...>/closure-binding-errors.zeek, line 19: cannot specify type in capture: t
error in <...>/closure-binding-errors.zeek, line 9 and <...>/closure-binding-errors.zeek, line 20: already defined (a)

View file

@ -0,0 +1 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.

View file

@ -0,0 +1,46 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
4, 10
6, 8
7, 7
4, 10
5, 8
6, 7
4, 10
5, 9
6, 8
4, 10
5, 8
6, 7
4, 10
5, 9
6, 8
4
2, 10, 47
4
2, 8, 47
3
1, 7, 47
4
2, 10, 47
5
3, 8, 47
6
4, 7, 47
4
2, 10, 47
5
3, 9, 47
6
4, 8, 47
4
2, 10, 91
5
3, 9, 91
6
4, 9, 91
4
2, 10, 91
5
3, 10, 91
6
4, 10, 91

View file

@ -0,0 +1,27 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
hello :-)
peer added
receiver got ping: function 2
inside: 1 | outside: 11 | global: 100
77
receiver got ping: function 1
begin: 100 | base_step: 2
begin: 100 | base_step: 2 | step: 76
178
receiver got ping: function 2
inside: 3 | outside: 11 | global: 100
79
receiver got ping: function 1
begin: 100 | base_step: 4
begin: 100 | base_step: 4 | step: 76
180
receiver got ping: function 2
inside: 5 | outside: 11 | global: 100
81
receiver got ping: function 1
begin: 100 | base_step: 6
begin: 100 | base_step: 6 | step: 76
182
receiver got ping: function 2
inside: 7 | outside: 11 | global: 100
83

View file

@ -0,0 +1,32 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
hello :)
peer added
begin: 100 | base_step: 50
sender got pong: function 2
inside: 1 | outside: 11 | global: 10
77
begin: 100 | base_step: 50
sender got pong: function 1
begin: 100 | base_step: 2
begin: 100 | base_step: 2 | step: 76
178
begin: 100 | base_step: 50
sender got pong: function 2
inside: 3 | outside: 11 | global: 10
79
begin: 100 | base_step: 50
sender got pong: function 1
begin: 100 | base_step: 4
begin: 100 | base_step: 4 | step: 76
180
begin: 100 | base_step: 50
sender got pong: function 2
inside: 5 | outside: 11 | global: 10
81
begin: 100 | base_step: 50
sender got pong: function 1
begin: 100 | base_step: 6
begin: 100 | base_step: 6 | step: 76
182
begin: 100 | base_step: 50
peer lost

View file

@ -0,0 +1,21 @@
# @TEST-EXEC-FAIL: zeek -b %INPUT >out
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff .stderr
global c: string;
type t: addr;
event zeek_init()
{
local a = 3;
local b = "hi there";
local f1 = function[a]() { print "no a!"; };
local f2 = function[a2](a2: addr) { print a2; };
local f3 = function[a]() { print b; };
local f4 = function[a, b]() { print b; };
local f5 = function[b, b]() { print b; };
local f6 = function() { print c; }; # should be okay
local f7 = function[c]() { print c; };
local f8 = function[t]() { local t2: t; };
local f9 = function[a]() { local a = 4; }; # error due to shadowing
}

View file

@ -0,0 +1,199 @@
# @TEST-EXEC: zeek -b %INPUT >out
# @TEST-EXEC: btest-diff out
type mutable_aggregate: record { x: count; };
function reference_capture() : function()
{
local a = 3;
local b = mutable_aggregate($x=11);
local f = function() { print ++a, --b$x; };
f();
++a;
--b$x;
f();
return f;
}
function shallow_copy_capture() : function()
{
local a = 3;
local b = mutable_aggregate($x=11);
local f = function[a, b]() { print ++a, --b$x; };
f();
++a;
--b$x;
f();
return f;
}
function deep_copy_capture() : function()
{
local a = 3;
local b = mutable_aggregate($x=11);
local f = function[copy a, copy b]() { print ++a, --b$x; };
f();
++a;
--b$x;
f();
return f;
}
function mixed_copy_capture_a() : function()
{
local a = 3;
local b = mutable_aggregate($x=11);
local f = function[copy a, b]() { print ++a, --b$x; };
f();
++a;
--b$x;
f();
return f;
}
function mixed_copy_capture_b() : function()
{
local a = 3;
local b = mutable_aggregate($x=11);
local f = function[a, copy b]() { print ++a, --b$x; };
f();
++a;
--b$x;
f();
return f;
}
function reference_capture_double() : function() : function()
{
local a = 3;
local b = mutable_aggregate($x=11);
local f = function() : function() {
local c = mutable_aggregate($x=88);
print ++a;
local f2 = function() { print a -= 2, --b$x, c$x += 3; };
c$x = c$x / 2;
return f2;
};
f()();
++a;
--b$x;
f()();
return f;
}
function shallow_copy_capture_double() : function() : function()
{
local a = 3;
local b = mutable_aggregate($x=11);
local f = function[a,b]() : function() {
local c = mutable_aggregate($x=88);
print ++a;
local f2 = function[a, b, c]() { print a -= 2, --b$x, c$x += 3; };
c$x = c$x / 2;
return f2;
};
f()();
++a;
--b$x;
f()();
return f;
}
function deep_copy1_capture_double() : function() : function()
{
local a = 3;
local b = mutable_aggregate($x=11);
local f = function[copy a, copy b]() : function() {
local c = mutable_aggregate($x=88);
print ++a;
local f2 = function[a, b, c]() { print a -= 2, --b$x, c$x += 3; };
c$x = c$x / 2;
return f2;
};
f()();
++a;
--b$x;
f()();
return f;
}
function deep_copy2_capture_double() : function() : function()
{
local a = 3;
local b = mutable_aggregate($x=11);
local f = function[a, b]() : function() {
local c = mutable_aggregate($x=88);
print ++a;
local f2 = function[copy a, copy b, copy c]()
{ print a -= 2, --b$x, c$x += 3; };
c$x = c$x / 2;
return f2;
};
f()();
++a;
--b$x;
f()();
return f;
}
function deep_copy3_capture_double() : function() : function()
{
local a = 3;
local b = mutable_aggregate($x=11);
local f = function[copy a, copy b]() : function() {
local c = mutable_aggregate($x=88);
print ++a;
local f2 = function[copy a, copy b, copy c]()
{ print a -= 2, --b$x, c$x += 3; };
c$x = c$x / 2;
return f2;
};
f()();
++a;
--b$x;
f()();
return f;
}
event zeek_init()
{
local rc = reference_capture();
rc();
local scc = shallow_copy_capture();
scc();
local dcc = deep_copy_capture();
dcc();
local mcca = mixed_copy_capture_a();
mcca();
local mccb = mixed_copy_capture_b();
mccb();
local rc2 = reference_capture_double();
rc2()();
local scc2 = shallow_copy_capture_double();
scc2()();
local dcc2_1 = deep_copy1_capture_double();
dcc2_1()();
local dcc2_2 = deep_copy2_capture_double();
dcc2_2()();
local dcc2_3 = deep_copy3_capture_double();
dcc2_3()();
}

View file

@ -0,0 +1,167 @@
# @TEST-PORT: BROKER_PORT
#
# @TEST-EXEC: btest-bg-run recv "zeek -B broker -b ../recv.zeek >recv.out"
# @TEST-EXEC: btest-bg-run send "zeek -B broker -b ../send.zeek >send.out"
#
# @TEST-EXEC: btest-bg-wait 45
# @TEST-EXEC: btest-diff recv/recv.out
# @TEST-EXEC: btest-diff send/send.out
@TEST-START-FILE send.zeek
redef exit_only_after_terminate = T;
type myfunctype: function(c: count) : function(d: count) : count;
global global_with_same_name = 10;
global ping: event(msg: string, f: myfunctype);
event zeek_init()
{
print "hello :)";
Broker::subscribe("zeek/event/my_topic");
Broker::peer("127.0.0.1", to_port(getenv("BROKER_PORT")));
}
global n = 0;
function send_event()
{
# in this frame event_count has an offset of three.
# in the receiving frame it has an offset of one.
# this tests to ensure that id lookups are being routed properly.
local dog = 0;
local not_dog = 1;
local event_count = 11;
local log : myfunctype = function[event_count](c: count) : function(d: count) : count
{
print fmt("inside: %s | outside: %s | global: %s", c, event_count, global_with_same_name);
return function[c](d: count) : count { return d + c; };
};
local two_part_adder_maker = function (begin : count) : function (base_step : count) : function ( step : count) : count
{
return function [begin](base_step : count) : function (step : count) : count
{
print fmt("begin: %s | base_step: %s", begin, base_step);
return function[begin, base_step] (step : count) : count
{
print fmt("begin: %s | base_step: %s | step: %s", begin, base_step, step);
return (begin += base_step + step); }; }; };
local l = two_part_adder_maker(100);
local stepper = l(50);
++n;
++event_count;
if ( n % 2 == 0)
{
local e2 = Broker::make_event(ping, "function 1", l);
Broker::publish("zeek/event/my_topic", e2);
}
else
{
local e = Broker::make_event(ping, "function 2", log);
Broker::publish("zeek/event/my_topic", e);
}
}
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
{
print "peer added";
send_event();
}
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
{
print "peer lost";
terminate();
}
event pong(msg: string, f: myfunctype)
{
print fmt("sender got pong: %s", msg);
local adder = f(n);
print adder(76);
send_event();
}
@TEST-END-FILE
@TEST-START-FILE recv.zeek
redef exit_only_after_terminate = T;
const events_to_recv = 7;
type myfunctype: function(c: count) : function(d: count) : count;
# type myfunctype: function(c: count);
global global_with_same_name = 100;
global pong: event(msg: string, f: myfunctype);
# This is one, of many, ways to declare your functions that you plan to receive.
# All you are doing is giving the parser a version of their body, so they can be
# anywhere. This seems to work quite nicely because it keeps them scoped and stops
# them from ever being evaluated.
function my_funcs()
{
return;
local begin = 100;
local event_count = begin;
local l : myfunctype = function[event_count](c: count) : function(d: count) : count
{
print fmt("inside: %s | outside: %s | global: %s", c, event_count, global_with_same_name);
return function[c](d: count) : count { return d + c; };
};
local dog_fish = function [begin](base_step : count) : function (step : count) : count
{
# actual formatting doesn't matter for name resolution.
print fmt("begin: %s | base_step: %s", begin, base_step);
return function [begin, base_step](step : count) : count
{
print fmt("begin: %s | base_step: %s | step: %s", begin, base_step, step);
return (begin += base_step + step); }; };
}
event zeek_init()
{
print "hello :-)";
Broker::subscribe("zeek/event/my_topic");
Broker::listen("127.0.0.1", to_port(getenv("BROKER_PORT")));
}
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
{
print "peer added";
}
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
{
print "peer lost";
}
global n = 0;
event ping(msg: string, f: myfunctype)
{
print fmt("receiver got ping: %s", msg);
++n;
local adder = f(n);
print adder(76);
if ( n == events_to_recv )
{
terminate();
}
else
{
local e = Broker::make_event(pong, msg, f);
Broker::publish("zeek/event/my_topic", e);
}
}
@TEST-END-FILE