diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2025-04-15 12:00:23 +0200 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2025-04-15 12:00:23 +0200 |
| commit | c0ac37c79f3d9fbc12b99541f58caaca8667182c (patch) | |
| tree | e943eaff22945dd2941773f7b0ed73ce27d43cd0 /unit_tests | |
| parent | 9cc30ff72ba25ceb3a1fdef0d8c4a6efc910d777 (diff) | |
| download | lanes-c0ac37c79f3d9fbc12b99541f58caaca8667182c.tar.gz lanes-c0ac37c79f3d9fbc12b99541f58caaca8667182c.tar.bz2 lanes-c0ac37c79f3d9fbc12b99541f58caaca8667182c.zip | |
Fix some tests (kinda)
* split tasking_cancelling in two
* add a timer in basic and tasking_cancelling as a temporary workaround for a deadlock in mingw ucrt64 builds
Diffstat (limited to 'unit_tests')
| -rw-r--r-- | unit_tests/UnitTests.vcxproj | 1 | ||||
| -rw-r--r-- | unit_tests/UnitTests.vcxproj.filters | 3 | ||||
| -rw-r--r-- | unit_tests/lane_tests.cpp | 2 | ||||
| -rw-r--r-- | unit_tests/scripts/lane/tasking_cancelling.lua | 89 | ||||
| -rw-r--r-- | unit_tests/scripts/lane/tasking_cancelling_with_hook.lua | 68 |
5 files changed, 96 insertions, 67 deletions
diff --git a/unit_tests/UnitTests.vcxproj b/unit_tests/UnitTests.vcxproj index e78e32a..e1370c3 100644 --- a/unit_tests/UnitTests.vcxproj +++ b/unit_tests/UnitTests.vcxproj | |||
| @@ -967,6 +967,7 @@ | |||
| 967 | </ItemGroup> | 967 | </ItemGroup> |
| 968 | <ItemGroup> | 968 | <ItemGroup> |
| 969 | <None Include="..\.runsettings" /> | 969 | <None Include="..\.runsettings" /> |
| 970 | <None Include="scripts\lane\tasking_cancelling_with_hook.lua" /> | ||
| 970 | <None Include="UnitTests.makefile" /> | 971 | <None Include="UnitTests.makefile" /> |
| 971 | <None Include="scripts\coro\basics.lua" /> | 972 | <None Include="scripts\coro\basics.lua" /> |
| 972 | <None Include="scripts\coro\error_handling.lua" /> | 973 | <None Include="scripts\coro\error_handling.lua" /> |
diff --git a/unit_tests/UnitTests.vcxproj.filters b/unit_tests/UnitTests.vcxproj.filters index 3b45009..b0ce216 100644 --- a/unit_tests/UnitTests.vcxproj.filters +++ b/unit_tests/UnitTests.vcxproj.filters | |||
| @@ -113,5 +113,8 @@ | |||
| 113 | <None Include="..\.runsettings"> | 113 | <None Include="..\.runsettings"> |
| 114 | <Filter>Catch2</Filter> | 114 | <Filter>Catch2</Filter> |
| 115 | </None> | 115 | </None> |
| 116 | <None Include="scripts\lane\tasking_cancelling_with_hook.lua"> | ||
| 117 | <Filter>Scripts\lane</Filter> | ||
| 118 | </None> | ||
| 116 | </ItemGroup> | 119 | </ItemGroup> |
| 117 | </Project> \ No newline at end of file | 120 | </Project> \ No newline at end of file |
diff --git a/unit_tests/lane_tests.cpp b/unit_tests/lane_tests.cpp index 0a392d8..1367ae5 100644 --- a/unit_tests/lane_tests.cpp +++ b/unit_tests/lane_tests.cpp | |||
| @@ -332,6 +332,7 @@ MAKE_TEST_CASE(lane, cooperative_shutdown, AssertNoLuaError) | |||
| 332 | MAKE_TEST_CASE(lane, uncooperative_shutdown, AssertWarns) | 332 | MAKE_TEST_CASE(lane, uncooperative_shutdown, AssertWarns) |
| 333 | #endif // LUA_VERSION_NUM | 333 | #endif // LUA_VERSION_NUM |
| 334 | MAKE_TEST_CASE(lane, tasking_basic, AssertNoLuaError) | 334 | MAKE_TEST_CASE(lane, tasking_basic, AssertNoLuaError) |
| 335 | MAKE_TEST_CASE(lane, tasking_cancelling_with_hook, AssertNoLuaError) | ||
| 335 | MAKE_TEST_CASE(lane, tasking_cancelling, AssertNoLuaError) | 336 | MAKE_TEST_CASE(lane, tasking_cancelling, AssertNoLuaError) |
| 336 | MAKE_TEST_CASE(lane, tasking_comms_criss_cross, AssertNoLuaError) | 337 | MAKE_TEST_CASE(lane, tasking_comms_criss_cross, AssertNoLuaError) |
| 337 | MAKE_TEST_CASE(lane, tasking_communications, AssertNoLuaError) | 338 | MAKE_TEST_CASE(lane, tasking_communications, AssertNoLuaError) |
| @@ -352,6 +353,7 @@ TEST_CASE("lanes.scripted_tests") | |||
| 352 | FileRunnerParam{ PUC_LUA_ONLY("lane/cooperative_shutdown"), TestType::AssertNoLuaError }, // 0 | 353 | FileRunnerParam{ PUC_LUA_ONLY("lane/cooperative_shutdown"), TestType::AssertNoLuaError }, // 0 |
| 353 | FileRunnerParam{ "lane/uncooperative_shutdown", TestType::AssertWarns }, | 354 | FileRunnerParam{ "lane/uncooperative_shutdown", TestType::AssertWarns }, |
| 354 | FileRunnerParam{ "lane/tasking_basic", TestType::AssertNoLuaError }, // 2 | 355 | FileRunnerParam{ "lane/tasking_basic", TestType::AssertNoLuaError }, // 2 |
| 356 | FileRunnerParam{ "lane/tasking_cancelling_with_hook", TestType::AssertNoLuaError }, // 3 | ||
| 355 | FileRunnerParam{ "lane/tasking_cancelling", TestType::AssertNoLuaError }, // 3 | 357 | FileRunnerParam{ "lane/tasking_cancelling", TestType::AssertNoLuaError }, // 3 |
| 356 | FileRunnerParam{ "lane/tasking_comms_criss_cross", TestType::AssertNoLuaError }, // 4 | 358 | FileRunnerParam{ "lane/tasking_comms_criss_cross", TestType::AssertNoLuaError }, // 4 |
| 357 | FileRunnerParam{ "lane/tasking_communications", TestType::AssertNoLuaError }, | 359 | FileRunnerParam{ "lane/tasking_communications", TestType::AssertNoLuaError }, |
diff --git a/unit_tests/scripts/lane/tasking_cancelling.lua b/unit_tests/scripts/lane/tasking_cancelling.lua index 85600ab..8bee3a6 100644 --- a/unit_tests/scripts/lane/tasking_cancelling.lua +++ b/unit_tests/scripts/lane/tasking_cancelling.lua | |||
| @@ -15,69 +15,12 @@ local lanes_linda = assert(lanes.linda) | |||
| 15 | -- ################################################################################################## | 15 | -- ################################################################################################## |
| 16 | -- ################################################################################################## | 16 | -- ################################################################################################## |
| 17 | 17 | ||
| 18 | local function task(a, b, c) | ||
| 19 | lane_threadname("task("..a..","..b..","..c..")") | ||
| 20 | --error "111" -- testing error messages | ||
| 21 | assert(hey) | ||
| 22 | local v=0 | ||
| 23 | for i=a,b,c do | ||
| 24 | v= v+i | ||
| 25 | end | ||
| 26 | return v, hey | ||
| 27 | end | ||
| 28 | |||
| 29 | local gc_cb = function(name_, status_) | ||
| 30 | PRINT(" ---> lane '" .. name_ .. "' collected with status '" .. status_ .. "'") | ||
| 31 | end | ||
| 32 | |||
| 33 | -- ################################################################################################## | ||
| 34 | -- ################################################################################################## | ||
| 35 | -- ################################################################################################## | ||
| 36 | |||
| 37 | PRINT("\n\n", "---=== Tasking (cancelling) ===---", "\n\n") | ||
| 38 | |||
| 39 | local task_launch2 = lanes_gen("", { name = 'auto', globals={hey=true}, gc_cb = gc_cb }, task) | ||
| 40 | |||
| 41 | local N=999999999 | ||
| 42 | local lane9= task_launch2(1,N,1) -- huuuuuuge... | ||
| 43 | |||
| 44 | -- Wait until state changes "pending"->"running" | ||
| 45 | -- | ||
| 46 | local st | ||
| 47 | local t0= os.time() | ||
| 48 | while os.time()-t0 < 5 do | ||
| 49 | st= lane9.status | ||
| 50 | io.stderr:write((i==1) and st.." " or '.') | ||
| 51 | if st~="pending" then break end | ||
| 52 | end | ||
| 53 | PRINT(" "..st) | ||
| 54 | |||
| 55 | if st=="error" then | ||
| 56 | local _= lane9[0] -- propagate the error here | ||
| 57 | end | ||
| 58 | if st=="done" then | ||
| 59 | error("Looping to "..N.." was not long enough (cannot test cancellation)") | ||
| 60 | end | ||
| 61 | assert(st=="running", "st == " .. st) | ||
| 62 | |||
| 63 | -- when running under luajit, the function is JIT-ed, and the instruction count isn't hit, so we need a different hook | ||
| 64 | lane9:cancel(jit and "line" or "count", 100) -- 0 timeout, hook triggers cancelslation when reaching the specified count | ||
| 65 | |||
| 66 | local t0= os.time() | ||
| 67 | while os.time()-t0 < 5 do | ||
| 68 | st= lane9.status | ||
| 69 | io.stderr:write((i==1) and st.." " or '.') | ||
| 70 | if st~="running" then break end | ||
| 71 | end | ||
| 72 | PRINT(" "..st) | ||
| 73 | assert(st == "cancelled", "st is '" .. st .. "' instead of 'cancelled'") | ||
| 74 | |||
| 75 | -- cancellation of lanes waiting on a linda | 18 | -- cancellation of lanes waiting on a linda |
| 76 | local limited = lanes_linda("limited") | 19 | local limited = lanes_linda("limited") |
| 77 | assert.fails(function() limited:limit("key", -1) end) | 20 | assert.fails(function() limited:limit("key", -1) end) |
| 78 | assert.failsnot(function() limited:limit("key", 1) end) | 21 | assert.failsnot(function() limited:limit("key", 1) end) |
| 79 | -- [[################################################ | 22 | -- [[################################################ |
| 80 | limited:send("key", "hello") -- saturate linda | 23 | limited:send("key", "hello") -- saturate linda, so that subsequent sends will block |
| 81 | for k, v in pairs(limited:dump()) do | 24 | for k, v in pairs(limited:dump()) do |
| 82 | PRINT("limited[" .. tostring(k) .. "] = " .. tostring(v)) | 25 | PRINT("limited[" .. tostring(k) .. "] = " .. tostring(v)) |
| 83 | end | 26 | end |
| @@ -88,11 +31,15 @@ local wait_send = function() | |||
| 88 | end | 31 | end |
| 89 | 32 | ||
| 90 | local wait_send_lane = lanes_gen("*", { name = 'auto' }, wait_send)() | 33 | local wait_send_lane = lanes_gen("*", { name = 'auto' }, wait_send)() |
| 91 | repeat until wait_send_lane.status == "waiting" | 34 | repeat |
| 92 | print "wait_send_lane is waiting" | 35 | io.stderr:write('!') |
| 36 | -- currently mingw64 builds can deadlock if we cancel the lane too early (before the linda blocks, at it causes the linda condvar not to be signalled) | ||
| 37 | lanes.sleep(0.1) | ||
| 38 | until wait_send_lane.status == "waiting" | ||
| 39 | PRINT "wait_send_lane is waiting" | ||
| 93 | wait_send_lane:cancel() -- hard cancel, 0 timeout | 40 | wait_send_lane:cancel() -- hard cancel, 0 timeout |
| 94 | repeat until wait_send_lane.status == "cancelled" | 41 | repeat until wait_send_lane.status == "cancelled" |
| 95 | print "wait_send_lane is cancelled" | 42 | PRINT "wait_send_lane is cancelled" |
| 96 | --################################################]] | 43 | --################################################]] |
| 97 | local wait_receive = function() | 44 | local wait_receive = function() |
| 98 | local k, v | 45 | local k, v |
| @@ -101,11 +48,15 @@ local wait_receive = function() | |||
| 101 | end | 48 | end |
| 102 | 49 | ||
| 103 | local wait_receive_lane = lanes_gen("*", { name = 'auto' }, wait_receive)() | 50 | local wait_receive_lane = lanes_gen("*", { name = 'auto' }, wait_receive)() |
| 104 | repeat until wait_receive_lane.status == "waiting" | 51 | repeat |
| 105 | print "wait_receive_lane is waiting" | 52 | io.stderr:write('!') |
| 53 | -- currently mingw64 builds can deadlock if we cancel the lane too early (before the linda blocks, at it causes the linda condvar not to be signalled) | ||
| 54 | lanes.sleep(0.1) | ||
| 55 | until wait_receive_lane.status == "waiting" | ||
| 56 | PRINT "wait_receive_lane is waiting" | ||
| 106 | wait_receive_lane:cancel() -- hard cancel, 0 timeout | 57 | wait_receive_lane:cancel() -- hard cancel, 0 timeout |
| 107 | repeat until wait_receive_lane.status == "cancelled" | 58 | repeat until wait_receive_lane.status == "cancelled" |
| 108 | print "wait_receive_lane is cancelled" | 59 | PRINT "wait_receive_lane is cancelled" |
| 109 | --################################################]] | 60 | --################################################]] |
| 110 | local wait_receive_batched = function() | 61 | local wait_receive_batched = function() |
| 111 | local k, v1, v2 | 62 | local k, v1, v2 |
| @@ -114,9 +65,13 @@ local wait_receive_batched = function() | |||
| 114 | end | 65 | end |
| 115 | 66 | ||
| 116 | local wait_receive_batched_lane = lanes_gen("*", { name = 'auto' }, wait_receive_batched)() | 67 | local wait_receive_batched_lane = lanes_gen("*", { name = 'auto' }, wait_receive_batched)() |
| 117 | repeat until wait_receive_batched_lane.status == "waiting" | 68 | repeat |
| 118 | print "wait_receive_batched_lane is waiting" | 69 | io.stderr:write('!') |
| 70 | -- currently mingw64 builds can deadlock if we cancel the lane too early (before the linda blocks, at it causes the linda condvar not to be signalled) | ||
| 71 | lanes.sleep(0.1) | ||
| 72 | until wait_receive_batched_lane.status == "waiting" | ||
| 73 | PRINT "wait_receive_batched_lane is waiting" | ||
| 119 | wait_receive_batched_lane:cancel() -- hard cancel, 0 timeout | 74 | wait_receive_batched_lane:cancel() -- hard cancel, 0 timeout |
| 120 | repeat until wait_receive_batched_lane.status == "cancelled" | 75 | repeat until wait_receive_batched_lane.status == "cancelled" |
| 121 | print "wait_receive_batched_lane is cancelled" | 76 | PRINT "wait_receive_batched_lane is cancelled" |
| 122 | --################################################]] | 77 | --################################################]] |
diff --git a/unit_tests/scripts/lane/tasking_cancelling_with_hook.lua b/unit_tests/scripts/lane/tasking_cancelling_with_hook.lua new file mode 100644 index 0000000..56b934f --- /dev/null +++ b/unit_tests/scripts/lane/tasking_cancelling_with_hook.lua | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure(config).configure() | ||
| 2 | print("require_lanes_result:", require_lanes_result_1, require_lanes_result_2) | ||
| 3 | local lanes = require_lanes_result_1 | ||
| 4 | |||
| 5 | local require_assert_result_1, require_assert_result_2 = require "_assert" | ||
| 6 | print("require_assert_result:", require_assert_result_1, require_assert_result_2) | ||
| 7 | |||
| 8 | local utils = lanes.require "_utils" | ||
| 9 | local PRINT = utils.MAKE_PRINT() | ||
| 10 | |||
| 11 | -- ################################################################################################## | ||
| 12 | -- ################################################################################################## | ||
| 13 | -- ################################################################################################## | ||
| 14 | |||
| 15 | local function task(a, b, c) | ||
| 16 | lane_threadname("task("..a..","..b..","..c..")") | ||
| 17 | --error "111" -- testing error messages | ||
| 18 | assert(hey) | ||
| 19 | local v=0 | ||
| 20 | for i=a,b,c do | ||
| 21 | v= v+i | ||
| 22 | end | ||
| 23 | return v, hey | ||
| 24 | end | ||
| 25 | |||
| 26 | local gc_cb = function(name_, status_) | ||
| 27 | PRINT(" ---> lane '" .. name_ .. "' collected with status '" .. status_ .. "'") | ||
| 28 | end | ||
| 29 | |||
| 30 | -- ################################################################################################## | ||
| 31 | -- ################################################################################################## | ||
| 32 | -- ################################################################################################## | ||
| 33 | |||
| 34 | local generator = lanes.gen("", { name = 'auto', globals={hey=true}, gc_cb = gc_cb }, task) | ||
| 35 | |||
| 36 | local N = 999999999 | ||
| 37 | local lane_h = generator(1,N,1) -- huuuuuuge... | ||
| 38 | |||
| 39 | -- Wait until state changes "pending"->"running" | ||
| 40 | -- | ||
| 41 | local st | ||
| 42 | local t0 = os.time() | ||
| 43 | while os.time()-t0 < 5 do | ||
| 44 | st = lane_h.status | ||
| 45 | io.stderr:write((i==1) and st.." " or '.') | ||
| 46 | if st~="pending" then break end | ||
| 47 | end | ||
| 48 | PRINT(" "..st) | ||
| 49 | |||
| 50 | if st == "error" then | ||
| 51 | local _ = lane_h[0] -- propagate the error here | ||
| 52 | end | ||
| 53 | if st == "done" then | ||
| 54 | error("Looping to "..N.." was not long enough (cannot test cancellation)") | ||
| 55 | end | ||
| 56 | assert(st == "running", "st == " .. st) | ||
| 57 | |||
| 58 | -- when running under luajit, the function is JIT-ed, and the instruction count isn't hit, so we need a different hook | ||
| 59 | lane_h:cancel(jit and "line" or "count", 100) -- 0 timeout, hook triggers cancelslation when reaching the specified count | ||
| 60 | |||
| 61 | local t0 = os.time() | ||
| 62 | while os.time()-t0 < 5 do | ||
| 63 | st = lane_h.status | ||
| 64 | io.stderr:write((i==1) and st.." " or '.') | ||
| 65 | if st~="running" then break end | ||
| 66 | end | ||
| 67 | PRINT(" "..st) | ||
| 68 | assert(st == "cancelled", "st is '" .. st .. "' instead of 'cancelled'") | ||
