Skip to content
Snippets Groups Projects
Commit fde7dad0 authored by Nat Goodspeed's avatar Nat Goodspeed
Browse files

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.
parent 5ced20b1
No related branches found
No related tags found
No related merge requests found
...@@ -36,16 +36,16 @@ ...@@ -36,16 +36,16 @@
#include "../lllogin.h" #include "../lllogin.h"
// STL headers // STL headers
// std headers // std headers
#include <iostream>
#include <chrono> #include <chrono>
#include <iostream>
// external library headers // external library headers
// other Linden headers // other Linden headers
#include "llsd.h"
#include "../../../test/lltut.h"
#include "../../../test/lltestapp.h"
#include "../../../test/debug.h" #include "../../../test/debug.h"
#include "../../../test/lltestapp.h"
#include "../../../test/lltut.h"
#include "llevents.h" #include "llevents.h"
#include "lleventcoro.h" #include "lleventcoro.h"
#include "llsd.h"
#include "stringize.h" #include "stringize.h"
#if LL_WINDOWS #if LL_WINDOWS
...@@ -96,21 +96,24 @@ class LoginListener: public LLEventTrackable ...@@ -96,21 +96,24 @@ class LoginListener: public LLEventTrackable
size_t getCalls() const { return mCalls; } size_t getCalls() const { return mCalls; }
LLSD waitFor(size_t prevcalls, F32 seconds) const // wait for arbitrary predicate to become true
template <typename PRED>
LLSD waitFor(const std::string& desc, PRED&& pred, double seconds=2.0) const
{ {
// remember when we started waiting // remember when we started waiting
auto start = std::chrono::system_clock::now(); auto start = std::chrono::system_clock::now();
// Break loop when the LLEventPump on which we're listening calls call() // Break loop when the passed predicate returns true
while (getCalls() <= prevcalls) while (! std::forward<PRED>(pred)())
{ {
// but if we've been spinning here too long, test failed // but if we've been spinning here too long, test failed
// how long have we been here, anyway? // how long have we been here, anyway?
auto now = std::chrono::system_clock::now(); auto now = std::chrono::system_clock::now();
// the default ratio for duration is seconds // the default ratio for duration is seconds
std::chrono::duration<F32> elapsed = (now - start); std::chrono::duration<double> elapsed = (now - start);
if (elapsed.count() > seconds) 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 -- // haven't yet received the new call, nor have we timed out --
// just wait // just wait
...@@ -120,6 +123,14 @@ class LoginListener: public LLEventTrackable ...@@ -120,6 +123,14 @@ class LoginListener: public LLEventTrackable
return lastEvent(); 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) friend std::ostream& operator<<(std::ostream& out, const LoginListener& listener)
{ {
return out << "LoginListener(" << listener.mName << ')'; return out << "LoginListener(" << listener.mName << ')';
...@@ -234,9 +245,9 @@ namespace tut ...@@ -234,9 +245,9 @@ namespace tut
credentials["passwd"] = "secret"; credentials["passwd"] = "secret";
login.connect("login.bar.com", credentials); login.connect("login.bar.com", credentials);
llcoro::suspend(); listener.waitFor(
"online state",
ensure_equals("Online state", listener.lastEvent()["state"].asString(), "online"); [&listener]()->bool{ return listener.lastEvent()["state"].asString() == "online"; });
} }
template<> template<> template<> template<>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment