aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2025-03-10 14:34:16 +0100
committerBenoit Germain <benoit.germain@ubisoft.com>2025-03-10 14:34:16 +0100
commitd290acf78ad4291099ebccdf94d81aa60ce866bb (patch)
treea26ce9141df136862c862c6f30524652b8eb7ab0
parentb35f8f264d806b0a614588e75f9b7c2712c860a4 (diff)
downloadlanes-d290acf78ad4291099ebccdf94d81aa60ce866bb.tar.gz
lanes-d290acf78ad4291099ebccdf94d81aa60ce866bb.tar.bz2
lanes-d290acf78ad4291099ebccdf94d81aa60ce866bb.zip
Fix/disable some unit tests against LuaJIT until the failure reason is discovered
* cancel.lua fails when using lanes.coro * coro/basics.lua fails because an error message is different * coro/error_handling fails for an unknown reason * a lanes.finally test crashes inside lua_close
-rw-r--r--tests/cancel.lua3
-rw-r--r--unit_tests/init_and_shutdown.cpp129
-rw-r--r--unit_tests/lane_tests.cpp3
-rw-r--r--unit_tests/scripts/coro/basics.lua7
-rw-r--r--unit_tests/scripts/coro/error_handling.lua2
5 files changed, 76 insertions, 68 deletions
diff --git a/tests/cancel.lua b/tests/cancel.lua
index 84203f1..5862c85 100644
--- a/tests/cancel.lua
+++ b/tests/cancel.lua
@@ -27,7 +27,8 @@ local linda = lanes.linda()
27linda:set("val", 33.0) 27linda:set("val", 33.0)
28 28
29-- so that we can easily swap between lanes.gen and lanes.coro, to try stuff 29-- so that we can easily swap between lanes.gen and lanes.coro, to try stuff
30local generator = lanes.coro 30-- TODO: looks like the result changes when using LuaJIT and coro together. to be investigated
31local generator = lanes.gen
31 32
32-- ################################################################################################## 33-- ##################################################################################################
33 34
diff --git a/unit_tests/init_and_shutdown.cpp b/unit_tests/init_and_shutdown.cpp
index 7450a80..7e4c215 100644
--- a/unit_tests/init_and_shutdown.cpp
+++ b/unit_tests/init_and_shutdown.cpp
@@ -668,75 +668,76 @@ TEST_CASE("lanes.configure")
668// ################################################################################################# 668// #################################################################################################
669// ################################################################################################# 669// #################################################################################################
670 670
671TEST_CASE("lanes.finally") 671#if LUAJIT_FLAVOR() == 0
672// TODO: this test crashes inside S.close() against LuaJIT. to be investigated
673TEST_CASE("lanes.finally.no fixture")
672{ 674{
673 SECTION("no fixture") 675 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } };
674 { 676 // we need Lanes to be up. Since we run several 'scripts', we store it as a global
675 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; 677 S.requireSuccess("lanes = require 'lanes'.configure()");
676 // we need Lanes to be up. Since we run several 'scripts', we store it as a global 678 // we can set a function
677 S.requireSuccess("lanes = require 'lanes'.configure()"); 679 S.requireSuccess("lanes.finally(function() end)");
678 // we can set a function 680 // we can clear it
679 S.requireSuccess("lanes.finally(function() end)"); 681 S.requireSuccess("lanes.finally(nil)");
680 // we can clear it 682 // we can set a new one
681 S.requireSuccess("lanes.finally(nil)"); 683 S.requireSuccess("lanes.finally(function() end)");
682 // we can set a new one 684 // we can replace an existing function
683 S.requireSuccess("lanes.finally(function() end)"); 685 S.requireSuccess("lanes.finally(error)");
684 // we can replace an existing function 686 // even if the finalizer throws a Lua error, it shouldn't crash anything
685 S.requireSuccess("lanes.finally(error)"); 687 REQUIRE_NOTHROW(S.close()); // TODO: use lua_atpanic to catch errors during close()
686 // even if the finalizer throws a Lua error, it shouldn't crash anything 688 REQUIRE_FALSE(S.finalizerWasCalled);
687 REQUIRE_NOTHROW(S.close()); // TODO: use lua_atpanic to catch errors during close() 689}
688 REQUIRE_FALSE(S.finalizerWasCalled); 690#endif // LUAJIT_FLAVOR
689 }
690 691
691 // --------------------------------------------------------------------------------------------- 692// #################################################################################################
692 693
693 SECTION("with fixture") 694TEST_CASE("lanes.finally.with fixture")
694 { 695{
695 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } }; 696 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
696 697
697 // we need Lanes to be up. Since we run several 'scripts', we store it as a global 698 // we need Lanes to be up. Since we run several 'scripts', we store it as a global
698 S.requireSuccess("lanes = require 'lanes'.configure()"); 699 S.requireSuccess("lanes = require 'lanes'.configure()");
699 // works because we have package.preload.fixture = luaopen_fixture 700 // works because we have package.preload.fixture = luaopen_fixture
700 S.requireSuccess("fixture = require 'fixture'"); 701 S.requireSuccess("fixture = require 'fixture'");
701 // set our detectable finalizer 702 // set our detectable finalizer
702 S.requireSuccess("lanes.finally(fixture.throwing_finalizer)"); 703 S.requireSuccess("lanes.finally(fixture.throwing_finalizer)");
703 // even if the finalizer can request a C++ exception, it shouldn't do it just now since we have no dangling lane 704 // even if the finalizer can request a C++ exception, it shouldn't do it just now since we have no dangling lane
704 REQUIRE_NOTHROW(S.close()); 705 REQUIRE_NOTHROW(S.close());
705 // the finalizer should be called 706 // the finalizer should be called
706 REQUIRE(S.finalizerWasCalled); 707 REQUIRE(S.finalizerWasCalled);
707 } 708}
708 709
709 // --------------------------------------------------------------------------------------------- 710// #################################################################################################
710 711
711 SECTION("shutdown with an uncooperative lane") 712TEST_CASE("lanes.finally.shutdown with an uncooperative lane")
712 { 713{
713 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } }; 714 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
714 S.requireSuccess("lanes = require 'lanes'.configure()"); 715 S.requireSuccess("lanes = require 'lanes'.configure()");
715 716
716 // prepare a callback for lanes.finally() 717 // prepare a callback for lanes.finally()
717 static bool _wasCalled{}; 718 static bool _wasCalled{};
718 static bool _allLanesTerminated{}; 719 static bool _allLanesTerminated{};
719 auto _finallyCB{ +[](lua_State* const L_) { _wasCalled = true; _allLanesTerminated = lua_toboolean(L_, 1); return 0; } }; 720 auto _finallyCB{ +[](lua_State* const L_) { _wasCalled = true; _allLanesTerminated = lua_toboolean(L_, 1); return 0; } };
720 lua_pushcfunction(S, _finallyCB); 721 lua_pushcfunction(S, _finallyCB);
721 lua_setglobal(S, "finallyCB"); 722 lua_setglobal(S, "finallyCB");
722 // start a lane that lasts a long time 723 // start a lane that lasts a long time
723 std::string_view const _script{ 724 std::string_view const _script{
724 " lanes.finally(finallyCB)" 725 " lanes.finally(finallyCB)"
725 " g = lanes.gen('*'," 726 " g = lanes.gen('*',"
726 " {name = 'auto'}," 727 " {name = 'auto'},"
727 " function()" 728 " function()"
728 " for i = 1,1e37 do end" // no cooperative cancellation checks here! 729 " local f = require 'fixture'"
729 " end)" 730 " for i = 1,1e37 do f.give_me_back() end" // no cooperative cancellation checks here, but opportunities for the cancellation hook to trigger
730 " g()" 731 " end)"
731 }; 732 " g()"
732 S.requireSuccess(_script); 733 };
733 // close the state before the lane ends. 734 S.requireSuccess(_script);
734 // since we don't wait at all, it is possible that the OS thread for the lane hasn't even started at that point 735 // close the state before the lane ends.
735 S.close(); 736 // since we don't wait at all, it is possible that the OS thread for the lane hasn't even started at that point
736 // the finally handler should have been called, and told all lanes are stopped 737 S.close();
737 REQUIRE(_wasCalled); 738 // the finally handler should have been called, and told all lanes are stopped
738 REQUIRE(_allLanesTerminated); 739 REQUIRE(_wasCalled);
739 } 740 REQUIRE(_allLanesTerminated);
740} 741}
741 742
742// ################################################################################################# 743// #################################################################################################
diff --git a/unit_tests/lane_tests.cpp b/unit_tests/lane_tests.cpp
index a6c6514..f1411fb 100644
--- a/unit_tests/lane_tests.cpp
+++ b/unit_tests/lane_tests.cpp
@@ -275,7 +275,10 @@ MAKE_TEST_CASE(lane, tasking_join_test, AssertNoLuaError)
275MAKE_TEST_CASE(lane, tasking_send_receive_code, AssertNoLuaError) 275MAKE_TEST_CASE(lane, tasking_send_receive_code, AssertNoLuaError)
276MAKE_TEST_CASE(lane, stdlib_naming, AssertNoLuaError) 276MAKE_TEST_CASE(lane, stdlib_naming, AssertNoLuaError)
277MAKE_TEST_CASE(coro, basics, AssertNoLuaError) 277MAKE_TEST_CASE(coro, basics, AssertNoLuaError)
278#if LUAJIT_FLAVOR() == 0
279// TODO: for some reason, the test fails with LuaJIT. To be investigated
278MAKE_TEST_CASE(coro, error_handling, AssertNoLuaError) 280MAKE_TEST_CASE(coro, error_handling, AssertNoLuaError)
281#endif // LUAJIT_FLAVOR()
279 282
280/* 283/*
281TEST_CASE("lanes.scripted tests") 284TEST_CASE("lanes.scripted tests")
diff --git a/unit_tests/scripts/coro/basics.lua b/unit_tests/scripts/coro/basics.lua
index 4444e87..dc74b7c 100644
--- a/unit_tests/scripts/coro/basics.lua
+++ b/unit_tests/scripts/coro/basics.lua
@@ -47,14 +47,17 @@ if true then
47 local err, status, stack = h:join() 47 local err, status, stack = h:join()
48 PRINT(err, status, stack) 48 PRINT(err, status, stack)
49 -- the actual error message is not the same for Lua 5.1 49 -- the actual error message is not the same for Lua 5.1
50 -- of course, it also has to be different for LuaJIT as well
51 -- also, LuaJIT prepends a file:line to the actual error message, which Lua5.1 does not.
50 local msgs = { 52 local msgs = {
51 ["Lua 5.1"] = "attempt to yield across metamethod/C-call boundary", 53 ["Lua 5.1"] = jit and "attempt to yield across C-call boundary" or "attempt to yield across metamethod/C-call boundary",
52 ["Lua 5.2"] = "attempt to yield from outside a coroutine", 54 ["Lua 5.2"] = "attempt to yield from outside a coroutine",
53 ["Lua 5.3"] = "attempt to yield from outside a coroutine", 55 ["Lua 5.3"] = "attempt to yield from outside a coroutine",
54 ["Lua 5.4"] = "attempt to yield from outside a coroutine" 56 ["Lua 5.4"] = "attempt to yield from outside a coroutine"
55 } 57 }
56 local expected_msg = msgs[_VERSION] 58 local expected_msg = msgs[_VERSION]
57 assert(err == nil and status == expected_msg and stack == nil, "status = " .. status) 59 PRINT("expected_msg = " .. expected_msg)
60 assert(err == nil and string.find(status, expected_msg, 1, true) and stack == nil, "status = " .. status)
58end 61end
59 62
60-- the generator 63-- the generator
diff --git a/unit_tests/scripts/coro/error_handling.lua b/unit_tests/scripts/coro/error_handling.lua
index 3b50c7f..ba6cff6 100644
--- a/unit_tests/scripts/coro/error_handling.lua
+++ b/unit_tests/scripts/coro/error_handling.lua
@@ -60,5 +60,5 @@ if true then
60 local a, b, c = h:join() 60 local a, b, c = h:join()
61 -- we get the expected error back 61 -- we get the expected error back
62 PRINT("non_string_thrower:", a, b, c) 62 PRINT("non_string_thrower:", a, b, c)
63 assert(a == nil and type(b) == "table" and b[1] == "string in table" and c == nil) 63 assert(a == nil and type(b) == "table" and b[1] == "string in table" and c == nil, "a=" .. tostring(a) .. " b=" .. tostring(b))
64end 64end