summaryrefslogtreecommitdiff
path: root/indra/llcommon/tests
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2019-10-16 09:15:47 -0400
committerNat Goodspeed <nat@lindenlab.com>2020-03-25 18:58:16 -0400
commit53aeea4d82801f5d624a4f6a62090195d3a24f2f (patch)
treecb44db71ccdf56ef1f430e981c4fc58f73085db9 /indra/llcommon/tests
parent6945755e5299e071e46d53f09821ac73993f7afe (diff)
DRTVWR-476: Add LLEventLogProxy, LLEventLogProxyFor<T>.
LLEventLogProxy can be introduced to serve as a logging proxy for an existing LLEventPump subclass instance. Access through the LLEventLogProxy will be logged; access directly to the underlying LLEventPump will not. LLEventLogProxyFor<LLEventPumpSubclass> functions as a drop-in replacement for the original LLEventPumpSubclass instance. It internally instantiates LLEventPumpSubclass and serves as a proxy for that instance. Add unit tests for LLEventMailDrop and LLEventLogProxyFor<LLEventMailDrop>, both "plain" (events only) and via lleventcoro.h synchronization.
Diffstat (limited to 'indra/llcommon/tests')
-rw-r--r--indra/llcommon/tests/lleventcoro_test.cpp78
-rw-r--r--indra/llcommon/tests/lleventfilter_test.cpp75
2 files changed, 153 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> >();
+ }
}
diff --git a/indra/llcommon/tests/lleventfilter_test.cpp b/indra/llcommon/tests/lleventfilter_test.cpp
index 1875013794..fa2cb03e95 100644
--- a/indra/llcommon/tests/lleventfilter_test.cpp
+++ b/indra/llcommon/tests/lleventfilter_test.cpp
@@ -36,9 +36,12 @@
// other Linden headers
#include "../test/lltut.h"
#include "stringize.h"
+#include "llsdutil.h"
#include "listener.h"
#include "tests/wrapllerrs.h"
+#include <typeinfo>
+
/*****************************************************************************
* Test classes
*****************************************************************************/
@@ -401,6 +404,78 @@ namespace tut
throttle.post(";17");
ensure_equals("17", cat.result, "136;12;17"); // "17" delivered
}
+
+ template<class PUMP>
+ void test()
+ {
+ PUMP pump(typeid(PUMP).name());
+ LLSD data{LLSD::emptyArray()};
+ bool consumed{true};
+ // listener that appends to 'data'
+ // but that also returns the current value of 'consumed'
+ // Instantiate this separately because we're going to listen()
+ // multiple times with the same lambda: LLEventMailDrop only replays
+ // queued events on a new listen() call.
+ auto lambda =
+ [&data, &consumed](const LLSD& event)->bool
+ {
+ data.append(event);
+ return consumed;
+ };
+ {
+ LLTempBoundListener conn = pump.listen("lambda", lambda);
+ pump.post("first");
+ }
+ // first post() should certainly be received by listener
+ ensure_equals("first", data, llsd::array("first"));
+ // the question is, since consumed was true, did it queue the value?
+ data = LLSD::emptyArray();
+ {
+ // if it queued the value, it would be delivered on subsequent
+ // listen() call
+ LLTempBoundListener conn = pump.listen("lambda", lambda);
+ }
+ ensure_equals("empty1", data, LLSD::emptyArray());
+ data = LLSD::emptyArray();
+ // now let's NOT consume the posted data
+ consumed = false;
+ {
+ LLTempBoundListener conn = pump.listen("lambda", lambda);
+ pump.post("second");
+ pump.post("third");
+ }
+ // the two events still arrive
+ ensure_equals("second,third1", data, llsd::array("second", "third"));
+ data = LLSD::emptyArray();
+ {
+ // when we reconnect, these should be delivered again
+ // but this time they should be consumed
+ consumed = true;
+ LLTempBoundListener conn = pump.listen("lambda", lambda);
+ }
+ // unconsumed events were delivered again
+ ensure_equals("second,third2", data, llsd::array("second", "third"));
+ data = LLSD::emptyArray();
+ {
+ // when we reconnect this time, no more unconsumed events
+ LLTempBoundListener conn = pump.listen("lambda", lambda);
+ }
+ ensure_equals("empty2", data, LLSD::emptyArray());
+ }
+
+ template<> template<>
+ void filter_object::test<6>()
+ {
+ set_test_name("LLEventMailDrop");
+ tut::test<LLEventMailDrop>();
+ }
+
+ template<> template<>
+ void filter_object::test<7>()
+ {
+ set_test_name("LLEventLogProxyFor<LLEventMailDrop>");
+ tut::test< LLEventLogProxyFor<LLEventMailDrop> >();
+ }
} // namespace tut
/*****************************************************************************