From fde7dad001d588e972cd49f5c41c5014f86f646e Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 2 Apr 2020 15:00:17 -0400 Subject: DRTVWR-476: Make LoginListener::waitFor() take arbitrary predicate. This allows one of the tests to specifically waitFor() the completion status update from LLLogin, rather than the next status update to come along: the coroutine potentially emits a whole sequence of status updates before completion. Then the waitFor() overload that merely waits for the next status update is implemented by passing that specific predicate to the other overload. --- .../viewer_components/login/tests/lllogin_test.cpp | 35 ++++++++++++++-------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/indra/viewer_components/login/tests/lllogin_test.cpp b/indra/viewer_components/login/tests/lllogin_test.cpp index 0d933a3d64..f9267533ff 100644 --- a/indra/viewer_components/login/tests/lllogin_test.cpp +++ b/indra/viewer_components/login/tests/lllogin_test.cpp @@ -36,16 +36,16 @@ #include "../lllogin.h" // STL headers // std headers -#include #include +#include // external library headers // other Linden headers -#include "llsd.h" -#include "../../../test/lltut.h" -#include "../../../test/lltestapp.h" #include "../../../test/debug.h" +#include "../../../test/lltestapp.h" +#include "../../../test/lltut.h" #include "llevents.h" #include "lleventcoro.h" +#include "llsd.h" #include "stringize.h" #if LL_WINDOWS @@ -96,21 +96,24 @@ public: size_t getCalls() const { return mCalls; } - LLSD waitFor(size_t prevcalls, F32 seconds) const + // wait for arbitrary predicate to become true + template + LLSD waitFor(const std::string& desc, PRED&& pred, double seconds=2.0) const { // remember when we started waiting auto start = std::chrono::system_clock::now(); - // Break loop when the LLEventPump on which we're listening calls call() - while (getCalls() <= prevcalls) + // Break loop when the passed predicate returns true + while (! std::forward(pred)()) { // but if we've been spinning here too long, test failed // how long have we been here, anyway? auto now = std::chrono::system_clock::now(); // the default ratio for duration is seconds - std::chrono::duration elapsed = (now - start); + std::chrono::duration elapsed = (now - start); if (elapsed.count() > seconds) { - tut::fail("LoginListener::waitFor() timed out"); + tut::fail(STRINGIZE("LoginListener::waitFor() took more than " + << seconds << " seconds waiting for " << desc)); } // haven't yet received the new call, nor have we timed out -- // just wait @@ -120,6 +123,14 @@ public: return lastEvent(); } + // wait for any call() calls beyond prevcalls + LLSD waitFor(size_t prevcalls, double seconds) const + { + return waitFor(STRINGIZE("more than " << prevcalls << " calls"), + [this, prevcalls]()->bool{ return getCalls() > prevcalls; }, + seconds); + } + friend std::ostream& operator<<(std::ostream& out, const LoginListener& listener) { return out << "LoginListener(" << listener.mName << ')'; @@ -234,9 +245,9 @@ namespace tut credentials["passwd"] = "secret"; login.connect("login.bar.com", credentials); - llcoro::suspend(); - - ensure_equals("Online state", listener.lastEvent()["state"].asString(), "online"); + listener.waitFor( + "online state", + [&listener]()->bool{ return listener.lastEvent()["state"].asString() == "online"; }); } template<> template<> -- cgit v1.2.3