summaryrefslogtreecommitdiff
path: root/indra/newview/tests
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2024-02-07 22:50:03 -0500
committerNat Goodspeed <nat@lindenlab.com>2024-02-07 22:50:03 -0500
commit0c14c8a372a5d4639de3365f69e566962493fe78 (patch)
treebea2dd4376a66286874df1991b8e242d502c9d0c /indra/newview/tests
parent4ecfd706bce5c45556eaf2833f89fd9f2f5b07a9 (diff)
Fix tests broken by switching from Lua 5.4 to Luau.
Add a new test<1>() that tests returning values from a Lua chunk using LLLUAmanager::waitScriptLine(). This exercises lua_tollsd() without yet involving LLEventPump machinery. For that purpose, extract from test<2>() the sequence of (description, expression, LLSD expected) triples into a static C array. The new test<1>() returns each such expression as a result; test<2>() posts each such expression to a test LLEventPump. test<2>() now uses waitScriptLine() instead of pumping the coroutine scheduler a few times and hoping. The pump-and-hope tactic worked before, but no longer does. waitScriptLine() is more robust anyway. Move the former test<1>() to test<3>() because it exercises still more machinery, specifically listen_events() and await_event(). Because this test involves a handshake with C++ code, use startScriptLine() to launch the Lua coroutine while providing a definite way to wait for completion later. Again, startScriptLine() followed by get() on the returned future is more robust than the previous pump-and-hope code. Similarly, the former test<3>(), now renamed test<4>(), uses startScriptLine() and Future::get() instead of pump-and-hope.
Diffstat (limited to 'indra/newview/tests')
-rw-r--r--indra/newview/tests/llluamanager_test.cpp143
1 files changed, 78 insertions, 65 deletions
diff --git a/indra/newview/tests/llluamanager_test.cpp b/indra/newview/tests/llluamanager_test.cpp
index 98a2726af7..1f25fd5f3b 100644
--- a/indra/newview/tests/llluamanager_test.cpp
+++ b/indra/newview/tests/llluamanager_test.cpp
@@ -27,6 +27,7 @@
#include "llsdutil.h"
#include "lluri.h"
#include "lluuid.h"
+#include "lua_function.h"
#include "stringize.h"
class LLTestApp : public LLApp
@@ -64,14 +65,80 @@ namespace tut
typedef llluamanager_group::object object;
llluamanager_group llluamanagergrp("llluamanager");
+ static struct LuaExpr
+ {
+ std::string desc, expr;
+ LLSD expect;
+ } lua_expressions[] = {
+ { "nil", "nil", LLSD() },
+ { "true", "true", true },
+ { "false", "false", false },
+ { "int", "17", 17 },
+ { "real", "3.14", 3.14 },
+ { "string", "'string'", "string" },
+ // can't synthesize Lua userdata in Lua code: that can only be
+ // constructed by a C function
+ { "empty table", "{}", LLSD() },
+ { "nested empty table", "{ 1, 2, 3, {}, 5 }",
+ llsd::array(1, 2, 3, LLSD(), 5) },
+ { "nested non-empty table", "{ 1, 2, 3, {a=0, b=1}, 5 }",
+ llsd::array(1, 2, 3, llsd::map("a", 0, "b", 1), 5) },
+ };
+
template<> template<>
void object::test<1>()
{
+ set_test_name("test Lua results");
+ LuaState L;
+ for (auto& luax : lua_expressions)
+ {
+ auto [count, result] =
+ LLLUAmanager::waitScriptLine(L, "return " + luax.expr);
+ auto desc{ stringize("waitScriptLine(", luax.desc, ")") };
+ ensure_equals(desc + ".count", count, 1);
+ ensure_equals(desc + ".result", result, luax.expect);
+ }
+ }
+
+ void from_lua(const std::string& desc, const std::string_view& construct, const LLSD& expect)
+ {
+ LLSD fromlua;
+ LLEventStream replypump("testpump");
+ LLTempBoundListener conn(
+ replypump.listen("llluamanager_test",
+ listener([&fromlua](const LLSD& data){ fromlua = data; })));
+ const std::string lua(stringize(
+ "-- test LLSD synthesized by Lua\n",
+ "data = ", construct, "\n"
+ "post_on('testpump', data)\n"
+ ));
+ LuaState L;
+ auto [count, result] = LLLUAmanager::waitScriptLine(L, lua);
+ // We woke up again ourselves because the coroutine running Lua has
+ // finished. But our Lua chunk didn't actually return anything, so we
+ // expect count to be 0 and result to be undefined.
+ ensure_equals(desc + " count", count, 0);
+ ensure_equals(desc, fromlua, expect);
+ }
+
+ template<> template<>
+ void object::test<2>()
+ {
+ set_test_name("LLSD from post_on()");
+ for (auto& luax : lua_expressions)
+ {
+ from_lua(luax.desc, luax.expr, luax.expect);
+ }
+ }
+
+ template<> template<>
+ void object::test<3>()
+ {
set_test_name("test post_on(), listen_events(), await_event()");
StringVec posts;
LLEventStream replypump("testpump");
LLTempBoundListener conn(
- replypump.listen("test<1>",
+ replypump.listen("test<3>",
listener([&posts](const LLSD& data)
{ posts.push_back(data.asString()); })));
const std::string lua(
@@ -88,7 +155,11 @@ namespace tut
"await_event(replypump)\n"
"post_on('testpump', 'exit')\n"
);
- LLLUAmanager::runScriptLine(lua);
+ LuaState L;
+ // It's important to let the startScriptLine() coroutine run
+ // concurrently with ours until we've had a chance to post() our
+ // reply.
+ auto future = LLLUAmanager::startScriptLine(L, lua);
StringVec expected{
"entry",
"listen_events()",
@@ -97,10 +168,6 @@ namespace tut
"message",
"exit"
};
- for (int i = 0; i < 10 && posts.size() <= 2 && posts[2].empty(); ++i)
- {
- llcoro::suspend();
- }
expected[2] = posts.at(2);
LL_DEBUGS() << "Found pumpname '" << expected[2] << "'" << LL_ENDL;
LLEventPump& luapump{ LLEventPumps::instance().obtain(expected[2]) };
@@ -108,57 +175,10 @@ namespace tut
<< LLError::Log::classname(luapump)
<< "': post('" << expected[4] << "')" << LL_ENDL;
luapump.post(expected[4]);
- llcoro::suspend();
+ auto [count, result] = future.get();
ensure_equals("post_on() sequence", posts, expected);
}
- void from_lua(const std::string& desc, const std::string_view& construct, const LLSD& expect)
- {
- LLSD fromlua;
- LLEventStream replypump("testpump");
- LLTempBoundListener conn(
- replypump.listen("llluamanager_test",
- listener([&fromlua](const LLSD& data){ fromlua = data; })));
- const std::string lua(stringize(
- "-- test LLSD synthesized by Lua\n",
- // we expect the caller's Lua snippet to construct a Lua object
- // called 'data'
- construct, "\n"
- "post_on('testpump', data)\n"
- ));
- LLLUAmanager::runScriptLine(lua);
- // At this point LLLUAmanager::runScriptLine() has launched a new C++
- // coroutine to run the passed Lua snippet, but that coroutine hasn't
- // yet had a chance to run. Poke the coroutine scheduler until the Lua
- // script has sent its data.
- for (int i = 0; i < 10 && fromlua.isUndefined(); ++i)
- {
- llcoro::suspend();
- }
- // We woke up again ourselves because the coroutine running Lua has
- // finished.
- ensure_equals(desc, fromlua, expect);
- }
-
- template<> template<>
- void object::test<2>()
- {
- set_test_name("LLSD from Lua");
- from_lua("nil", "data = nil", LLSD());
- from_lua("true", "data = true", true);
- from_lua("false", "data = false", false);
- from_lua("int", "data = 17", 17);
- from_lua("real", "data = 3.14", 3.14);
- from_lua("string", "data = 'string'", "string");
- // can't synthesize Lua userdata in Lua code: that can only be
- // constructed by a C function
- from_lua("empty table", "data = {}", LLSD());
- from_lua("nested empty table", "data = { 1, 2, 3, {}, 5 }",
- llsd::array(1, 2, 3, LLSD(), 5));
- from_lua("nested non-empty table", "data = { 1, 2, 3, {a=0, b=1}, 5 }",
- llsd::array(1, 2, 3, llsd::map("a", 0, "b", 1), 5));
- }
-
void round_trip(const std::string& desc, const LLSD& send, const LLSD& expect)
{
LLSD reply;
@@ -176,15 +196,8 @@ namespace tut
"post_on('testpump', replypump)\n"
"await_event(replypump)\n"
);
- LLLUAmanager::runScriptLine(lua);
- // At this point LLLUAmanager::runScriptLine() has launched a new C++
- // coroutine to run the passed Lua snippet, but that coroutine hasn't
- // yet had a chance to run. Poke the coroutine scheduler until the Lua
- // script has sent its reply pump name.
- for (int i = 0; i < 10 && reply.isUndefined(); ++i)
- {
- llcoro::suspend();
- }
+ LuaState L;
+ auto future = LLLUAmanager::startScriptLine(L, lua);
// We woke up again ourselves because the coroutine running Lua has
// reached the await_event() call, which suspends the calling C++
// coroutine (including the Lua code running on it) until we post
@@ -194,7 +207,7 @@ namespace tut
LLEventPumps::instance().post(luapump, send);
// The C++ coroutine running the Lua script is now ready to run. Run
// it so it will echo the LLSD back to us.
- llcoro::suspend();
+ auto [count, result] = future.get();
ensure_equals(desc, reply, expect);
}
@@ -219,7 +232,7 @@ namespace tut
};
template<> template<>
- void object::test<3>()
+ void object::test<4>()
{
set_test_name("LLSD round trip");
LLSD::Binary binary{ 3, 1, 4, 1, 5, 9, 2, 6, 5 };