mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
tests added for new capture-by-reference closure semantics & errors
This commit is contained in:
parent
4884b191e8
commit
35421b07f1
8 changed files with 503 additions and 0 deletions
|
@ -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)
|
|
@ -0,0 +1 @@
|
|||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
46
testing/btest/Baseline/language.closure-binding/out
Normal file
46
testing/btest/Baseline/language.closure-binding/out
Normal 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
|
|
@ -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
|
|
@ -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
|
21
testing/btest/language/closure-binding-errors.zeek
Normal file
21
testing/btest/language/closure-binding-errors.zeek
Normal 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
|
||||
}
|
199
testing/btest/language/closure-binding.zeek
Normal file
199
testing/btest/language/closure-binding.zeek
Normal 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()();
|
||||
}
|
167
testing/btest/language/closure-sending2.zeek
Normal file
167
testing/btest/language/closure-sending2.zeek
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue