diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2025-04-18 17:53:27 +0200 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2025-04-18 17:53:27 +0200 |
commit | 4c5d11823802175cfaf083a6fcd20a3006b27d51 (patch) | |
tree | 95ecb36d71620d5f61f5c06f3f022a3667181606 | |
parent | 022e40cc71beda874d0bad2cec227e472d5dd4af (diff) | |
download | lanes-4c5d11823802175cfaf083a6fcd20a3006b27d51.tar.gz lanes-4c5d11823802175cfaf083a6fcd20a3006b27d51.tar.bz2 lanes-4c5d11823802175cfaf083a6fcd20a3006b27d51.zip |
A unit test for linda wake_period
Diffstat (limited to '')
-rw-r--r-- | src/linda.cpp | 10 | ||||
-rw-r--r-- | src/macros_and_utils.hpp | 1 | ||||
-rw-r--r-- | tests/track_lanes.lua | 6 | ||||
-rw-r--r-- | unit_tests/UnitTests.vcxproj | 1 | ||||
-rw-r--r-- | unit_tests/UnitTests.vcxproj.filters | 3 | ||||
-rw-r--r-- | unit_tests/linda_tests.cpp | 17 | ||||
-rw-r--r-- | unit_tests/scripts/linda/wake_period.lua | 41 |
7 files changed, 64 insertions, 15 deletions
diff --git a/src/linda.cpp b/src/linda.cpp index a9ae61c..fa28385 100644 --- a/src/linda.cpp +++ b/src/linda.cpp | |||
@@ -1178,7 +1178,15 @@ LUAG_FUNC(linda) | |||
1178 | if (lua_isnil(L_, kIdxTop)) { | 1178 | if (lua_isnil(L_, kIdxTop)) { |
1179 | lua_pop(L_, 1); | 1179 | lua_pop(L_, 1); |
1180 | lua_pushnumber(L_, _U->lindaWakePeriod.count()); | 1180 | lua_pushnumber(L_, _U->lindaWakePeriod.count()); |
1181 | } else { | 1181 | } else if (luaG_type(L_, kIdxTop) == LuaType::STRING) { |
1182 | if (luaG_tostring(L_, kIdxTop) != "never") { | ||
1183 | luaL_argerror(L_, 1, "invalid wake_period"); | ||
1184 | } else { | ||
1185 | lua_pop(L_, 1); | ||
1186 | lua_pushnumber(L_, 0); | ||
1187 | } | ||
1188 | } | ||
1189 | else { | ||
1182 | luaL_argcheck(L_, luaL_optnumber(L_, 2, 0) > 0, 1, "wake_period must be > 0"); | 1190 | luaL_argcheck(L_, luaL_optnumber(L_, 2, 0) > 0, 1, "wake_period must be > 0"); |
1183 | } | 1191 | } |
1184 | 1192 | ||
diff --git a/src/macros_and_utils.hpp b/src/macros_and_utils.hpp index 16011f7..1aca818 100644 --- a/src/macros_and_utils.hpp +++ b/src/macros_and_utils.hpp | |||
@@ -21,6 +21,7 @@ inline void STACK_GROW(lua_State* const L_, int const n_) | |||
21 | 21 | ||
22 | // ################################################################################################# | 22 | // ################################################################################################# |
23 | 23 | ||
24 | // 1 unit of lua_Duration lasts 1 second (using default period of std::ratio<1>) | ||
24 | using lua_Duration = std::chrono::template duration<lua_Number>; | 25 | using lua_Duration = std::chrono::template duration<lua_Number>; |
25 | 26 | ||
26 | // ################################################################################################# | 27 | // ################################################################################################# |
diff --git a/tests/track_lanes.lua b/tests/track_lanes.lua index d1670ae..ef2ca06 100644 --- a/tests/track_lanes.lua +++ b/tests/track_lanes.lua | |||
@@ -59,8 +59,10 @@ local threads = track( "============= START", 2) | |||
59 | -- two_seconds forever | 59 | -- two_seconds forever |
60 | assert(threads[1].status == 'waiting' and threads[2].status == 'waiting') | 60 | assert(threads[1].status == 'waiting' and threads[2].status == 'waiting') |
61 | 61 | ||
62 | -- wait until ephemeral1 has completed | 62 | -- wait until ephemeral1 has completed, should take about 2 seconds |
63 | SLEEP(2.1) | 63 | repeat |
64 | SLEEP(0.1) | ||
65 | until ephemeral1.status == "done" | ||
64 | 66 | ||
65 | local threads = track( "============= two_seconds dead", 2) | 67 | local threads = track( "============= two_seconds dead", 2) |
66 | -- two_seconds forever | 68 | -- two_seconds forever |
diff --git a/unit_tests/UnitTests.vcxproj b/unit_tests/UnitTests.vcxproj index e1370c3..8c22653 100644 --- a/unit_tests/UnitTests.vcxproj +++ b/unit_tests/UnitTests.vcxproj | |||
@@ -968,6 +968,7 @@ | |||
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="scripts\lane\tasking_cancelling_with_hook.lua" /> |
971 | <None Include="scripts\linda\wake_period.lua" /> | ||
971 | <None Include="UnitTests.makefile" /> | 972 | <None Include="UnitTests.makefile" /> |
972 | <None Include="scripts\coro\basics.lua" /> | 973 | <None Include="scripts\coro\basics.lua" /> |
973 | <None Include="scripts\coro\error_handling.lua" /> | 974 | <None Include="scripts\coro\error_handling.lua" /> |
diff --git a/unit_tests/UnitTests.vcxproj.filters b/unit_tests/UnitTests.vcxproj.filters index b0ce216..ce8cb58 100644 --- a/unit_tests/UnitTests.vcxproj.filters +++ b/unit_tests/UnitTests.vcxproj.filters | |||
@@ -116,5 +116,8 @@ | |||
116 | <None Include="scripts\lane\tasking_cancelling_with_hook.lua"> | 116 | <None Include="scripts\lane\tasking_cancelling_with_hook.lua"> |
117 | <Filter>Scripts\lane</Filter> | 117 | <Filter>Scripts\lane</Filter> |
118 | </None> | 118 | </None> |
119 | <None Include="scripts\linda\wake_period.lua"> | ||
120 | <Filter>Scripts\linda</Filter> | ||
121 | </None> | ||
119 | </ItemGroup> | 122 | </ItemGroup> |
120 | </Project> \ No newline at end of file | 123 | </Project> \ No newline at end of file |
diff --git a/unit_tests/linda_tests.cpp b/unit_tests/linda_tests.cpp index 9dbaa85..d956ae2 100644 --- a/unit_tests/linda_tests.cpp +++ b/unit_tests/linda_tests.cpp | |||
@@ -104,16 +104,7 @@ TEST_CASE("linda.single_keeper.creation/wake_period") | |||
104 | S.requireFailure("lanes.linda{wake_period = -1}"); | 104 | S.requireFailure("lanes.linda{wake_period = -1}"); |
105 | S.requireFailure("lanes.linda{wake_period = 0}"); | 105 | S.requireFailure("lanes.linda{wake_period = 0}"); |
106 | S.requireSuccess("lanes.linda{wake_period = 0.0001}"); | 106 | S.requireSuccess("lanes.linda{wake_period = 0.0001}"); |
107 | } | 107 | S.requireSuccess("lanes.linda{wake_period = 'never'}"); |
108 | |||
109 | // ################################################################################################# | ||
110 | |||
111 | TEST_CASE("linda.single_keeper.wake_period") | ||
112 | { | ||
113 | FAIL("TODO: check that wake_period works as expected"); | ||
114 | // - use configure default if not provided | ||
115 | // - overrides default when provided | ||
116 | // - blocking operation wakes at the specified period | ||
117 | } | 108 | } |
118 | 109 | ||
119 | // ################################################################################################# | 110 | // ################################################################################################# |
@@ -397,17 +388,19 @@ TEST_CASE("scripted_tests." #DIR "." #FILE) \ | |||
397 | _runner.performTest(FileRunnerParam{ #DIR "/" #FILE, TestType::AssertNoLuaError }); \ | 388 | _runner.performTest(FileRunnerParam{ #DIR "/" #FILE, TestType::AssertNoLuaError }); \ |
398 | } | 389 | } |
399 | 390 | ||
391 | MAKE_TEST_CASE(linda, multiple_keepers) | ||
400 | MAKE_TEST_CASE(linda, send_receive) | 392 | MAKE_TEST_CASE(linda, send_receive) |
401 | MAKE_TEST_CASE(linda, send_registered_userdata) | 393 | MAKE_TEST_CASE(linda, send_registered_userdata) |
402 | MAKE_TEST_CASE(linda, multiple_keepers) | 394 | MAKE_TEST_CASE(linda, wake_period) |
403 | 395 | ||
404 | /* | 396 | /* |
405 | TEST_CASE("linda.scripted_tests") | 397 | TEST_CASE("linda.scripted_tests") |
406 | { | 398 | { |
407 | auto const& _testParam = GENERATE( | 399 | auto const& _testParam = GENERATE( |
400 | FileRunnerParam{ "linda/multiple_keepers", TestType::AssertNoLuaError }, | ||
408 | FileRunnerParam{ "linda/send_receive", TestType::AssertNoLuaError }, | 401 | FileRunnerParam{ "linda/send_receive", TestType::AssertNoLuaError }, |
409 | FileRunnerParam{ "linda/send_registered_userdata", TestType::AssertNoLuaError }, | 402 | FileRunnerParam{ "linda/send_registered_userdata", TestType::AssertNoLuaError }, |
410 | FileRunnerParam{ "linda/multiple_keepers", TestType::AssertNoLuaError } | 403 | FileRunnerParam{ "linda/wake_period", TestType::AssertNoLuaError } |
411 | ); | 404 | ); |
412 | 405 | ||
413 | FileRunner _runner(R"(.\unit_tests\scripts)"); | 406 | FileRunner _runner(R"(.\unit_tests\scripts)"); |
diff --git a/unit_tests/scripts/linda/wake_period.lua b/unit_tests/scripts/linda/wake_period.lua new file mode 100644 index 0000000..e4a900d --- /dev/null +++ b/unit_tests/scripts/linda/wake_period.lua | |||
@@ -0,0 +1,41 @@ | |||
1 | -- default wake period is 0.5 seconds | ||
2 | local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure{linda_wake_period = 0.5} | ||
3 | local lanes = require_lanes_result_1 | ||
4 | |||
5 | -- a lane that performs a blocking operation for 2 seconds | ||
6 | local body = function(linda_) | ||
7 | -- a blocking read that lasts longer than the tested wake_period values | ||
8 | linda_:receive(2, "empty_slot") | ||
9 | return true | ||
10 | end | ||
11 | |||
12 | -- if we don't cancel the lane, we should wait the whole duration | ||
13 | local function check_wake_duration(linda_, expected_, do_cancel_) | ||
14 | local h = lanes.gen(body)(linda_) | ||
15 | -- wait until the linda is blocked | ||
16 | repeat until h.status == "waiting" | ||
17 | local t0 = lanes.now_secs() | ||
18 | -- soft cancel, no timeout, no waking | ||
19 | if do_cancel_ then | ||
20 | local result, reason = h:cancel('soft', 0, false) | ||
21 | -- should say there was a timeout, since the lane didn't actually cancel (normal since we did not wake it) | ||
22 | assert(result == false and reason == 'timeout', "unexpected cancel result") | ||
23 | end | ||
24 | -- this should wait until the linda wakes by itself before the actual receive timeout and sees the cancel request | ||
25 | h:join() | ||
26 | local t1 = lanes.now_secs() | ||
27 | local delta = t1 - t0 | ||
28 | -- the linda should check for cancellation at about the expected period, not earlier | ||
29 | assert(delta >= expected_, tostring(linda_) .. " woke too early:" .. delta) | ||
30 | -- the lane shouldn't terminate too long after cancellation was processed | ||
31 | assert(delta <= expected_ * 1.1, tostring(linda_) .. " woke too late: " .. delta) | ||
32 | end | ||
33 | |||
34 | -- legacy behavior: linda waits until operation timeout | ||
35 | check_wake_duration(lanes.linda{name = "A", wake_period = 'never'}, 2, true) | ||
36 | -- early wake behavior: linda wakes after the expected time, sees a cancellation requests, and aborts the operation early | ||
37 | check_wake_duration(lanes.linda{name = "B", wake_period = 0.25}, 0.25, true) | ||
38 | check_wake_duration(lanes.linda{name = "C"}, 0.5, true) -- wake_period defaults to 0.5 (see above) | ||
39 | check_wake_duration(lanes.linda{name = "D", wake_period = 1}, 1, true) | ||
40 | -- even when there is a wake_period, the operation should reach full timeout if not cancelled early | ||
41 | check_wake_duration(lanes.linda{name = "E", wake_period = 0.1}, 2, false) | ||