From f7a38b5681ebf7429828fca9a9f7c109df853d54 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Fri, 31 May 2024 17:04:17 +0200 Subject: Some API changes * lanes.timers() can return nil, cancel_error if interrupted * linda:receive() always return a k,v, where k is nil when v is "timeout" or cancel_error * lanes.sleep returns nil, "timeout" during normal operations --- tests/basic.lua | 11 ++++++++--- tests/cancel.lua | 23 ++++++++++++++--------- tests/deadlock.lua | 7 ++++++- tests/ehynes.lua | 7 ++++++- tests/errhangtest.lua | 4 +++- tests/nameof.lua | 9 +++++++-- tests/objects.lua | 34 +++++++++++++++++----------------- tests/protect_allocator.lua | 9 +++++++-- tests/timer.lua | 2 +- tests/track_lanes.lua | 12 ++++++++---- 10 files changed, 77 insertions(+), 41 deletions(-) (limited to 'tests') diff --git a/tests/basic.lua b/tests/basic.lua index ab8a080..da7d756 100644 --- a/tests/basic.lua +++ b/tests/basic.lua @@ -29,6 +29,11 @@ local function PRINT(...) end end +local SLEEP = function(...) + local k, v = lanes.sleep(...) + assert(k == nil and v == "timeout") +end + local gc_cb = function(name_, status_) PRINT(" ---> lane '" .. name_ .. "' collected with status '" .. status_ .. "'") end @@ -256,7 +261,7 @@ SEND(3); WR("main ", "3 sent\n") SEND(setmetatable({"should be ignored"},{__lanesignore=true})); WR("main ", "__lanesignore table sent\n") for i=1,100 do WR "." - lanes.sleep(0.0001) + SLEEP(0.0001) assert(PEEK() == nil) -- nothing coming in, yet end SEND(nil); WR("\nmain ", "nil sent\n") @@ -293,7 +298,7 @@ comms_lane = nil collectgarbage() -- wait WR("waiting 1s") -lanes.sleep(1) +SLEEP(1) -- ################################################################################################## -- ################################################################################################## @@ -470,7 +475,7 @@ end) h= S { 12, 13, 14 } -- execution starts, h[1..3] will get the return values -- wait a bit so that the lane has a chance to set its debug name -lanes.sleep(0.5) +SLEEP(0.5) print("joining with '" .. h:get_debug_threadname() .. "'") local a,b,c,d= h:join() if h.status == "error" then diff --git a/tests/cancel.lua b/tests/cancel.lua index e39ad98..b75d085 100644 --- a/tests/cancel.lua +++ b/tests/cancel.lua @@ -9,6 +9,11 @@ end local lanes = require "lanes" .configure{ with_timers = false} +local SLEEP = function(...) + local k, v = lanes.sleep(...) + assert(k == nil and v == "timeout") +end + local linda = lanes.linda() -- a numeric value to read linda:set( "val", 33.0) @@ -51,7 +56,7 @@ local waitCancellation = function( h, expected_status) if expected_status ~= "running" then repeat -- print( "lane status:", h.status) - l:receive( 0.1, "yeah") -- wait a bit + SLEEP(0.1) -- wait a bit until h.status ~= "running" end print( "lane status:", h.status) @@ -80,8 +85,8 @@ local laneBody = function( mode_, payload_) -- linda mode io.stdout:write( " lane calling receive() ... ") local key, val = linda:receive( payload_, "boob") - print( lanes.cancel_error == key and "cancel_error" or tostring( key), tostring( val)) - if key == lanes.cancel_error then + print(tostring(key), val == lanes.cancel_error and "cancel_error" or tostring(val)) + if val == lanes.cancel_error then break -- gracefully abort loop end elseif mode_ == "get" then @@ -138,9 +143,9 @@ if not next(which_tests) or which_tests.linda then h = lanes.gen( "*", laneBody)( "receive", nil) -- start an infinite wait on the linda print "wait 1s" - linda:receive( 1, "yeah") + SLEEP(1) - -- linda cancel: linda:receive() returns cancel_error immediately + -- linda cancel: linda:receive() returns nil,cancel_error immediately print "cancelling" linda:cancel( "both") @@ -159,7 +164,7 @@ if not next(which_tests) or which_tests.soft then h = lanes.gen( "*", protectedBody)( "receive") -- start an infinite wait on the linda print "wait 1s" - linda:receive( 1, "yeah") + SLEEP(1) -- soft cancel, no awakening of waiting linda operations, should timeout local a, b = h:cancel( "soft", 1, false) @@ -182,7 +187,7 @@ if not next(which_tests) or which_tests.hook then print "\n\n####################################################################\nbegin hook cancel test\n" h = lanes.gen( "*", protectedBody)( "get", 300000) print "wait 2s" - linda:receive( 2, "yeah") + SLEEP(2) -- count hook cancel after some instruction instructions print "cancelling" @@ -201,7 +206,7 @@ if not next(which_tests) or which_tests.hard then -- wait 2s before cancelling the lane print "wait 2s" - linda:receive( 2, "yeah") + SLEEP(2) -- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it print "cancelling" @@ -220,7 +225,7 @@ if not next(which_tests) or which_tests.hard_unprotected then -- wait 2s before cancelling the lane print "wait 2s" - linda:receive( 2, "yeah") + SLEEP(2) -- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it print "cancelling" diff --git a/tests/deadlock.lua b/tests/deadlock.lua index c85d99f..c38ca13 100644 --- a/tests/deadlock.lua +++ b/tests/deadlock.lua @@ -4,6 +4,11 @@ local lanes = require('lanes').configure{with_timers=false} local linda = lanes.linda "deadlock_linda" +local SLEEP = function(...) + local k, v = lanes.sleep(...) + assert(k == nil and v == "timeout") +end + print "let's begin" local do_extra_stuff = true @@ -35,5 +40,5 @@ end -- With the bug not fixed, the linda keeper's mutex is still acquired, -- and the program hangs when the internal linda used for timers attempts to acquire the same keeper (there is only one by default) print('waiting a bit') -lanes.sleep(2) +SLEEP(2) print('we should reach here') \ No newline at end of file diff --git a/tests/ehynes.lua b/tests/ehynes.lua index e203a12..9436c7d 100644 --- a/tests/ehynes.lua +++ b/tests/ehynes.lua @@ -4,6 +4,11 @@ local lanes = require "lanes" lanes.configure() +local SLEEP = function(...) + local k, v = lanes.sleep(...) + assert(k == nil and v == "timeout") +end + local function PRINT_FMT( fmt, ... ) io.stderr:write( string.format(fmt,...).."\n" ) end @@ -36,7 +41,7 @@ local receiver2 = receiver_gen('another message') -- a function to pause and log the execution for debugging local function logf(s, f, ...) - linda:receive(1, "dummy") -- wait 1s + SLEEP(1) PRINT_FMT( "*** %s", s ) f(...) end diff --git a/tests/errhangtest.lua b/tests/errhangtest.lua index 84de8c6..99f44b2 100644 --- a/tests/errhangtest.lua +++ b/tests/errhangtest.lua @@ -24,8 +24,10 @@ if true then print "\n#### set 3 -> receive batched" local fun = function() print "function test ok" end print(pcall(linda.set, linda, 'test', true, nil, fun)) - local k,b,n,f = linda:receive(linda.batched, 'test', 3) -- read back the contents + -- read back the contents + local k,b,n,f = linda:receive(linda.batched, 'test', 3) assert(linda:get("test") == nil) + -- check they are ok print(k, b, n) f() print "OK" diff --git a/tests/nameof.lua b/tests/nameof.lua index 58df3e2..f48a971 100644 --- a/tests/nameof.lua +++ b/tests/nameof.lua @@ -1,5 +1,10 @@ local lanes = require "lanes".configure{nb_user_keepers = 100, on_state_create = function() end} +local SLEEP = function(...) + local k, v = lanes.sleep(...) + assert(k == nil and v == "timeout") +end + print("Name of table: ", lanes.nameof({})) print("Name of string.sub: ", lanes.nameof(string.sub)) print("Name of print: ", lanes.nameof(print)) @@ -14,12 +19,12 @@ end -- start the lane without any library local h = lanes.gen(nil, body)() -lanes.sleep(0.1) +SLEEP(0.1) print("Name of lane: ", lanes.nameof(h), "("..h.status..")") assert(h.status == "running") -- cancel the lane h:cancel("line", 1) -lanes.sleep(0.1) +SLEEP(0.1) print("Name of lane: ", lanes.nameof(h), "("..h.status..")") assert(h.status == "cancelled") print "TEST OK" diff --git a/tests/objects.lua b/tests/objects.lua index eed02bf..7668e45 100644 --- a/tests/objects.lua +++ b/tests/objects.lua @@ -9,27 +9,27 @@ lanes.configure() local linda= lanes.linda() -local start_lane= lanes.gen( "io", - function( obj1 ) +local start_lane= lanes.gen("io", + function(obj1 ) - assert( obj1.v ) - assert( obj1.print ) + assert(obj1.v ) + assert(obj1.print ) - assert( obj1 ) + assert(obj1 ) local mt1= getmetatable(obj1) assert(mt1) local k, obj2= linda:receive("") - assert( obj2 ) + assert(k == "" and obj2 ) local mt2= getmetatable(obj2) assert(mt2) - assert( mt1==mt2 ) + assert(mt1==mt2 ) local v= obj1:print() - assert( v=="aaa" ) + assert(v=="aaa" ) - v= obj2:print() - assert( v=="bbb" ) + v = obj2:print() + assert(v=="bbb" ) return true end @@ -37,7 +37,7 @@ local start_lane= lanes.gen( "io", local WR= function(str) - io.stderr:write( tostring(str).."\n") + io.stderr:write(tostring(str).."\n") end @@ -47,7 +47,7 @@ end -- having the methods 'fixed' in the object tables themselves. -- local o_mt= { - __index= function( me, key ) + __index= function(me, key ) if key=="print" then return function() WR(me.v); return me.v end end @@ -56,22 +56,22 @@ local o_mt= { local function obj_gen(v) local o= { v=v } - setmetatable( o, o_mt ) + setmetatable(o, o_mt ) return o end local a= obj_gen("aaa") local b= obj_gen("bbb") -assert( a and b ) +assert(a and b ) local mt_a= getmetatable(a) local mt_b= getmetatable(b) -assert( mt_a and mt_a==mt_b ) +assert(mt_a and mt_a==mt_b ) local h= start_lane(a) -- 1st object as parameter -linda:send( "", b ) -- 2nd object via Linda +linda:send("", b ) -- 2nd object via Linda -assert( h[1]==true ) -- wait for return +assert(h[1]==true ) -- wait for return diff --git a/tests/protect_allocator.lua b/tests/protect_allocator.lua index 5cbb1d8..994cb39 100644 --- a/tests/protect_allocator.lua +++ b/tests/protect_allocator.lua @@ -2,6 +2,11 @@ local print = print local lanes = require "lanes".configure{ with_timers = false, allocator="protected"} +local SLEEP = function(...) + local k, v = lanes.sleep(...) + assert(k == nil and v == "timeout") +end + local linda = lanes.linda() local body = function( id_) @@ -38,7 +43,7 @@ end -- wait a bit print "waiting a bit ..." -linda:receive( 2, "foo") +SLEEP(2) -- tell lanes to start running print "GO!" for i = 1, COUNT do @@ -49,5 +54,5 @@ end print "wait for completion" linda:receive( linda.batched, "key", COUNT) print "waiting a bit more ..." -linda:receive( 1, "foo") +SLEEP(1) print "SUCCESS" diff --git a/tests/timer.lua b/tests/timer.lua index a633286..4da1a50 100644 --- a/tests/timer.lua +++ b/tests/timer.lua @@ -100,7 +100,7 @@ assert( linda:get(T2) == nil ) PRINT "...making sure no ticks are coming..." local k,v= linda:receive( 10, T1,T2 ) -- should not get any -assert(v==nil) +assert(k==nil and v == "timeout") lanes.timer_lane:cancel() -- hard cancel, 0 timeout print (lanes.timer_lane[1], lanes.timer_lane[2]) \ No newline at end of file diff --git a/tests/track_lanes.lua b/tests/track_lanes.lua index daaa94c..5ea9a4e 100644 --- a/tests/track_lanes.lua +++ b/tests/track_lanes.lua @@ -1,5 +1,9 @@ local lanes = require "lanes" .configure{ with_timers = false, track_lanes = true} -local wait = lanes.sleep + +local SLEEP = function(...) + local k, v = lanes.sleep(...) + assert(k == nil and v == "timeout") +end print "hello" @@ -43,7 +47,7 @@ g( "forever", 'indefinitely') g( "two_seconds", 2) -- give a bit of time to reach the linda waiting call -wait( 0.1) +SLEEP(0.1) -- list the known lanes (should be living lanes) local threads = track( "============= START", 2) @@ -51,7 +55,7 @@ local threads = track( "============= START", 2) assert(threads[1].status == 'waiting' and threads[2].status == 'waiting') -- wait until "two_seconds has completed" -wait(2.1) +SLEEP(2.1) local threads = track( "============= two_seconds dead", 2) -- two_seconds forever @@ -61,7 +65,7 @@ assert(threads[1].status == 'done' and threads[2].status == 'waiting') g( "two_seconds", 2) -- give a bit of time to reach the linda waiting call -wait( 0.1) +SLEEP( 0.1) -- list the known lanes -- unless garbage collector cleaned it, we should have 3 lanes -- cgit v1.2.3-55-g6feb