diff options
Diffstat (limited to 'indra/llcommon/tests/lleventcoro_test.cpp')
-rw-r--r-- | indra/llcommon/tests/lleventcoro_test.cpp | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/indra/llcommon/tests/lleventcoro_test.cpp b/indra/llcommon/tests/lleventcoro_test.cpp index 4e774b27d9..c13920eefd 100644 --- a/indra/llcommon/tests/lleventcoro_test.cpp +++ b/indra/llcommon/tests/lleventcoro_test.cpp @@ -37,12 +37,14 @@ #include <iostream> #include <string> +#include <typeinfo> #include "../test/lltut.h" #include "llsd.h" #include "llsdutil.h" #include "llevents.h" #include "llcoros.h" +#include "lleventfilter.h" #include "lleventcoro.h" #include "../test/debug.h" #include "../test/sync.h" @@ -255,4 +257,80 @@ namespace tut LLCoros::instance().launch("test<5>", [this](){ coroPumpPost(); }); ensure_equals(result.asInteger(), 18); } + + template <class PUMP> + void test() + { + PUMP pump(typeid(PUMP).name()); + bool running{false}; + LLSD data{LLSD::emptyArray()}; + // start things off by posting once before even starting the listener + // coro + LL_DEBUGS() << "test() posting first" << LL_ENDL; + LLSD first{LLSDMap("desc", "first")("value", 0)}; + bool consumed = pump.post(first); + ensure("should not have consumed first", ! consumed); + // now launch the coro + LL_DEBUGS() << "test() launching listener coro" << LL_ENDL; + running = true; + LLCoros::instance().launch( + "listener", + [&pump, &running, &data](){ + // important for this test that we consume posted values + LLCoros::instance().set_consuming(true); + // should immediately retrieve 'first' without waiting + LL_DEBUGS() << "listener coro waiting for first" << LL_ENDL; + data.append(llcoro::suspendUntilEventOnWithTimeout(pump, 0.1, LLSD())); + // Don't use ensure() from within the coro -- ensure() failure + // throws tut::fail, which won't propagate out to the main + // test driver, which will result in an odd failure. + // Wait for 'second' because it's not already pending. + LL_DEBUGS() << "listener coro waiting for second" << LL_ENDL; + data.append(llcoro::suspendUntilEventOnWithTimeout(pump, 0.1, LLSD())); + // and wait for 'third', which should involve no further waiting + LL_DEBUGS() << "listener coro waiting for third" << LL_ENDL; + data.append(llcoro::suspendUntilEventOnWithTimeout(pump, 0.1, LLSD())); + LL_DEBUGS() << "listener coro done" << LL_ENDL; + running = false; + }); + // back from coro at the point where it's waiting for 'second' + LL_DEBUGS() << "test() posting second" << LL_ENDL; + LLSD second{llsd::map("desc", "second", "value", 1)}; + consumed = pump.post(second); + ensure("should have consumed second", consumed); + // This is a key point: even though we've post()ed the value for which + // the coroutine is waiting, it's actually still suspended until we + // pause for some other reason. The coroutine will only pick up one + // value at a time from our 'pump'. It's important to exercise the + // case when we post() two values before it picks up either. + LL_DEBUGS() << "test() posting third" << LL_ENDL; + LLSD third{llsd::map("desc", "third", "value", 2)}; + consumed = pump.post(third); + ensure("should NOT yet have consumed third", ! consumed); + // now just wait for coro to finish -- which it eventually will, given + // that all its suspend calls have short timeouts. + while (running) + { + LL_DEBUGS() << "test() waiting for coro done" << LL_ENDL; + llcoro::suspendUntilTimeout(0.1); + } + // okay, verify expected results + ensure_equals("should have received three values", data, + llsd::array(first, second, third)); + LL_DEBUGS() << "test() done" << LL_ENDL; + } + + template<> template<> + void object::test<6>() + { + set_test_name("LLEventMailDrop"); + tut::test<LLEventMailDrop>(); + } + + template<> template<> + void object::test<7>() + { + set_test_name("LLEventLogProxyFor<LLEventMailDrop>"); + tut::test< LLEventLogProxyFor<LLEventMailDrop> >(); + } } |