summaryrefslogtreecommitdiff
path: root/indra/llcommon/tests/lleventcoro_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/tests/lleventcoro_test.cpp')
-rw-r--r--indra/llcommon/tests/lleventcoro_test.cpp728
1 files changed, 136 insertions, 592 deletions
diff --git a/indra/llcommon/tests/lleventcoro_test.cpp b/indra/llcommon/tests/lleventcoro_test.cpp
index fa02d2bb1a..032923a108 100644
--- a/indra/llcommon/tests/lleventcoro_test.cpp
+++ b/indra/llcommon/tests/lleventcoro_test.cpp
@@ -26,102 +26,33 @@
* $/LicenseInfo$
*/
-/*****************************************************************************/
-// test<1>() is cloned from a Boost.Coroutine example program whose copyright
-// info is reproduced here:
-/*---------------------------------------------------------------------------*/
-// Copyright (c) 2006, Giovanni P. Deretta
-//
-// This code may be used under either of the following two licences:
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE. OF SUCH DAMAGE.
-//
-// Or:
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-/*****************************************************************************/
-
#define BOOST_RESULT_OF_USE_TR1 1
-// On some platforms, Boost.Coroutine must #define magic symbols before
-// #including platform-API headers. Naturally, that's ineffective unless the
-// Boost.Coroutine #include is the *first* #include of the platform header.
-// That means that client code must generally #include Boost.Coroutine headers
-// before anything else.
-#include <boost/dcoroutine/coroutine.hpp>
#include <boost/bind.hpp>
#include <boost/range.hpp>
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
+#include <boost/make_shared.hpp>
#include "linden_common.h"
#include <iostream>
#include <string>
+#include <typeinfo>
#include "../test/lltut.h"
+#include "../test/lltestapp.h"
#include "llsd.h"
#include "llsdutil.h"
#include "llevents.h"
-#include "tests/wrapllerrs.h"
-#include "stringize.h"
#include "llcoros.h"
+#include "lleventfilter.h"
#include "lleventcoro.h"
#include "../test/debug.h"
+#include "../test/sync.h"
using namespace llcoro;
/*****************************************************************************
-* from the banana.cpp example program borrowed for test<1>()
-*****************************************************************************/
-namespace coroutines = boost::dcoroutines;
-using coroutines::coroutine;
-
-template<typename Iter>
-bool match(Iter first, Iter last, std::string match) {
- std::string::iterator i = match.begin();
- for(; (first != last) && (i != match.end()); ++i) {
- if (*first != *i)
- return false;
- ++first;
- }
- return i == match.end();
-}
-
-template<typename BidirectionalIterator>
-BidirectionalIterator
-match_substring(BidirectionalIterator begin,
- BidirectionalIterator end,
- std::string xmatch,
- BOOST_DEDUCED_TYPENAME coroutine<BidirectionalIterator(void)>::self& self) {
-//BidirectionalIterator begin_ = begin;
- for(; begin != end; ++begin)
- if(match(begin, end, xmatch)) {
- self.yield(begin);
- }
- return end;
-}
-
-typedef coroutine<std::string::iterator(void)> match_coroutine_type;
-
-/*****************************************************************************
* Test helpers
*****************************************************************************/
/// Simulate an event API whose response is immediate: sent on receipt of the
@@ -131,8 +62,9 @@ typedef coroutine<std::string::iterator(void)> match_coroutine_type;
class ImmediateAPI
{
public:
- ImmediateAPI():
- mPump("immediate", true)
+ ImmediateAPI(Sync& sync):
+ mPump("immediate", true),
+ mSync(sync)
{
mPump.listen("API", boost::bind(&ImmediateAPI::operator(), this, _1));
}
@@ -141,20 +73,18 @@ public:
// Invoke this with an LLSD map containing:
// ["value"]: Integer value. We will reply with ["value"] + 1.
- // ["reply"]: Name of LLEventPump on which to send success response.
- // ["error"]: Name of LLEventPump on which to send error response.
- // ["fail"]: Presence of this key selects ["error"], else ["success"] as
- // the name of the pump on which to send the response.
+ // ["reply"]: Name of LLEventPump on which to send response.
bool operator()(const LLSD& event) const
{
+ mSync.bump();
LLSD::Integer value(event["value"]);
- LLSD::String replyPumpName(event.has("fail")? "error" : "reply");
- LLEventPumps::instance().obtain(event[replyPumpName]).post(value + 1);
+ LLEventPumps::instance().obtain(event["reply"]).post(value + 1);
return false;
}
private:
LLEventStream mPump;
+ Sync& mSync;
};
/*****************************************************************************
@@ -162,633 +92,247 @@ private:
*****************************************************************************/
namespace tut
{
- struct coroutine_data {};
- typedef test_group<coroutine_data> coroutine_group;
+ struct test_data
+ {
+ Sync mSync;
+ ImmediateAPI immediateAPI{mSync};
+ std::string replyName, errorName, threw, stringdata;
+ LLSD result, errordata;
+ int which;
+ LLTestApp testApp;
+
+ void explicit_wait(boost::shared_ptr<LLCoros::Promise<std::string>>& cbp);
+ void waitForEventOn1();
+ void coroPump();
+ void postAndWait1();
+ void coroPumpPost();
+ };
+ typedef test_group<test_data> coroutine_group;
typedef coroutine_group::object object;
coroutine_group coroutinegrp("coroutine");
- template<> template<>
- void object::test<1>()
- {
- set_test_name("From banana.cpp example program in Boost.Coroutine distro");
- std::string buffer = "banananana";
- std::string match = "nana";
- std::string::iterator begin = buffer.begin();
- std::string::iterator end = buffer.end();
-
-#if defined(BOOST_CORO_POSIX_IMPL)
-// std::cout << "Using Boost.Coroutine " << BOOST_CORO_POSIX_IMPL << '\n';
-#else
-// std::cout << "Using non-Posix Boost.Coroutine implementation" << std::endl;
-#endif
-
- typedef std::string::iterator signature(std::string::iterator,
- std::string::iterator,
- std::string,
- match_coroutine_type::self&);
-
- coroutine<std::string::iterator(void)> matcher
- (boost::bind(static_cast<signature*>(match_substring),
- begin,
- end,
- match,
- _1));
-
- std::string::iterator i = matcher();
-/*==========================================================================*|
- while(matcher && i != buffer.end()) {
- std::cout <<"Match at: "<< std::distance(buffer.begin(), i)<<'\n';
- i = matcher();
- }
-|*==========================================================================*/
- size_t matches[] = { 2, 4, 6 };
- for (size_t *mi(boost::begin(matches)), *mend(boost::end(matches));
- mi != mend; ++mi, i = matcher())
- {
- ensure("more", matcher);
- ensure("found", i != buffer.end());
- ensure_equals("value", std::distance(buffer.begin(), i), *mi);
- }
- ensure("done", ! matcher);
- }
-
- // use static data so we can intersperse coroutine functions with the
- // tests that engage them
- ImmediateAPI immediateAPI;
- std::string replyName, errorName, threw, stringdata;
- LLSD result, errordata;
- int which;
-
- // reinit vars at the start of each test
- void clear()
- {
- replyName.clear();
- errorName.clear();
- threw.clear();
- stringdata.clear();
- result = LLSD();
- errordata = LLSD();
- which = 0;
- }
-
- void explicit_wait(boost::shared_ptr<LLCoros::Future<std::string>::callback_t>& cbp)
+ void test_data::explicit_wait(boost::shared_ptr<LLCoros::Promise<std::string>>& cbp)
{
BEGIN
{
+ mSync.bump();
// The point of this test is to verify / illustrate suspending a
// coroutine for something other than an LLEventPump. In other
// words, this shows how to adapt to any async operation that
// provides a callback-style notification (and prove that it
// works).
- LLCoros::Future<std::string> future;
- // get the callback from that future
- LLCoros::Future<std::string>::callback_t callback(future.make_callback());
-
// Perhaps we would send a request to a remote server and arrange
- // for 'callback' to be called on response. Of course that might
- // involve an adapter object from the actual callback signature to
- // the signature of 'callback' -- in this case, void(std::string).
- // For test purposes, instead of handing 'callback' (or the
+ // for cbp->set_value() to be called on response.
+ // For test purposes, instead of handing 'callback' (or an
// adapter) off to some I/O subsystem, we'll just pass it back to
// our caller.
- cbp.reset(new LLCoros::Future<std::string>::callback_t(callback));
+ cbp = boost::make_shared<LLCoros::Promise<std::string>>();
+ LLCoros::Future<std::string> future = LLCoros::getFuture(*cbp);
- ensure("Not yet", ! future);
// calling get() on the future causes us to suspend
debug("about to suspend");
stringdata = future.get();
- ensure("Got it", bool(future));
+ mSync.bump();
+ ensure_equals("Got it", stringdata, "received");
}
END
}
template<> template<>
- void object::test<2>()
+ void object::test<1>()
{
- clear();
set_test_name("explicit_wait");
DEBUG;
// Construct the coroutine instance that will run explicit_wait.
- boost::shared_ptr<LLCoros::Future<std::string>::callback_t> respond;
- LLCoros::instance().launch("test<2>",
- boost::bind(explicit_wait, boost::ref(respond)));
+ boost::shared_ptr<LLCoros::Promise<std::string>> respond;
+ LLCoros::instance().launch("test<1>",
+ [this, &respond](){ explicit_wait(respond); });
+ mSync.bump();
// When the coroutine waits for the future, it returns here.
debug("about to respond");
- // Now we're the I/O subsystem delivering a result. This immediately
- // transfers control back to the coroutine.
- (*respond)("received");
+ // Now we're the I/O subsystem delivering a result. This should make
+ // the coroutine ready.
+ respond->set_value("received");
+ // but give it a chance to wake up
+ mSync.yield();
// ensure the coroutine ran and woke up again with the intended result
ensure_equals(stringdata, "received");
}
- void waitForEventOn1()
+ void test_data::waitForEventOn1()
{
BEGIN
{
+ mSync.bump();
result = suspendUntilEventOn("source");
+ mSync.bump();
}
END
}
template<> template<>
- void object::test<3>()
+ void object::test<2>()
{
- clear();
set_test_name("waitForEventOn1");
DEBUG;
- LLCoros::instance().launch("test<3>", waitForEventOn1);
+ LLCoros::instance().launch("test<2>", [this](){ waitForEventOn1(); });
+ mSync.bump();
debug("about to send");
LLEventPumps::instance().obtain("source").post("received");
+ // give waitForEventOn1() a chance to run
+ mSync.yield();
debug("back from send");
ensure_equals(result.asString(), "received");
}
- void waitForEventOn2()
- {
- BEGIN
- {
- LLEventWithID pair = suspendUntilEventOn("reply", "error");
- result = pair.first;
- which = pair.second;
- debug(STRINGIZE("result = " << result << ", which = " << which));
- }
- END
- }
-
- template<> template<>
- void object::test<4>()
- {
- clear();
- set_test_name("waitForEventOn2 reply");
- {
- DEBUG;
- LLCoros::instance().launch("test<4>", waitForEventOn2);
- debug("about to send");
- LLEventPumps::instance().obtain("reply").post("received");
- debug("back from send");
- }
- ensure_equals(result.asString(), "received");
- ensure_equals("which pump", which, 0);
- }
-
- template<> template<>
- void object::test<5>()
- {
- clear();
- set_test_name("waitForEventOn2 error");
- DEBUG;
- LLCoros::instance().launch("test<5>", waitForEventOn2);
- debug("about to send");
- LLEventPumps::instance().obtain("error").post("badness");
- debug("back from send");
- ensure_equals(result.asString(), "badness");
- ensure_equals("which pump", which, 1);
- }
-
- void coroPump()
+ void test_data::coroPump()
{
BEGIN
{
+ mSync.bump();
LLCoroEventPump waiter;
replyName = waiter.getName();
result = waiter.suspend();
+ mSync.bump();
}
END
}
template<> template<>
- void object::test<6>()
+ void object::test<3>()
{
- clear();
set_test_name("coroPump");
DEBUG;
- LLCoros::instance().launch("test<6>", coroPump);
+ LLCoros::instance().launch("test<3>", [this](){ coroPump(); });
+ mSync.bump();
debug("about to send");
LLEventPumps::instance().obtain(replyName).post("received");
+ // give coroPump() a chance to run
+ mSync.yield();
debug("back from send");
ensure_equals(result.asString(), "received");
}
- void coroPumps()
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- replyName = waiter.getName0();
- errorName = waiter.getName1();
- LLEventWithID pair(waiter.suspend());
- result = pair.first;
- which = pair.second;
- }
- END
- }
-
- template<> template<>
- void object::test<7>()
- {
- clear();
- set_test_name("coroPumps reply");
- DEBUG;
- LLCoros::instance().launch("test<7>", coroPumps);
- debug("about to send");
- LLEventPumps::instance().obtain(replyName).post("received");
- debug("back from send");
- ensure_equals(result.asString(), "received");
- ensure_equals("which pump", which, 0);
- }
-
- template<> template<>
- void object::test<8>()
- {
- clear();
- set_test_name("coroPumps error");
- DEBUG;
- LLCoros::instance().launch("test<8>", coroPumps);
- debug("about to send");
- LLEventPumps::instance().obtain(errorName).post("badness");
- debug("back from send");
- ensure_equals(result.asString(), "badness");
- ensure_equals("which pump", which, 1);
- }
-
- void coroPumpsNoEx()
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- replyName = waiter.getName0();
- errorName = waiter.getName1();
- result = waiter.suspendWithException();
- }
- END
- }
-
- template<> template<>
- void object::test<9>()
- {
- clear();
- set_test_name("coroPumpsNoEx");
- DEBUG;
- LLCoros::instance().launch("test<9>", coroPumpsNoEx);
- debug("about to send");
- LLEventPumps::instance().obtain(replyName).post("received");
- debug("back from send");
- ensure_equals(result.asString(), "received");
- }
-
- void coroPumpsEx()
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- replyName = waiter.getName0();
- errorName = waiter.getName1();
- try
- {
- result = waiter.suspendWithException();
- debug("no exception");
- }
- catch (const LLErrorEvent& e)
- {
- debug(STRINGIZE("exception " << e.what()));
- errordata = e.getData();
- }
- }
- END
- }
-
- template<> template<>
- void object::test<10>()
- {
- clear();
- set_test_name("coroPumpsEx");
- DEBUG;
- LLCoros::instance().launch("test<10>", coroPumpsEx);
- debug("about to send");
- LLEventPumps::instance().obtain(errorName).post("badness");
- debug("back from send");
- ensure("no result", result.isUndefined());
- ensure_equals("got error", errordata.asString(), "badness");
- }
-
- void coroPumpsNoLog()
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- replyName = waiter.getName0();
- errorName = waiter.getName1();
- result = waiter.suspendWithLog();
- }
- END
- }
-
- template<> template<>
- void object::test<11>()
- {
- clear();
- set_test_name("coroPumpsNoLog");
- DEBUG;
- LLCoros::instance().launch("test<11>", coroPumpsNoLog);
- debug("about to send");
- LLEventPumps::instance().obtain(replyName).post("received");
- debug("back from send");
- ensure_equals(result.asString(), "received");
- }
-
- void coroPumpsLog()
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- replyName = waiter.getName0();
- errorName = waiter.getName1();
- WrapLLErrs capture;
- threw = capture.catch_llerrs([&waiter, &debug](){
- result = waiter.suspendWithLog();
- debug("no exception");
- });
- }
- END
- }
-
- template<> template<>
- void object::test<12>()
- {
- clear();
- set_test_name("coroPumpsLog");
- DEBUG;
- LLCoros::instance().launch("test<12>", coroPumpsLog);
- debug("about to send");
- LLEventPumps::instance().obtain(errorName).post("badness");
- debug("back from send");
- ensure("no result", result.isUndefined());
- ensure_contains("got error", threw, "badness");
- }
-
- void postAndWait1()
+ void test_data::postAndWait1()
{
BEGIN
{
+ mSync.bump();
result = postAndSuspend(LLSDMap("value", 17), // request event
immediateAPI.getPump(), // requestPump
"reply1", // replyPump
"reply"); // request["reply"] = name
+ mSync.bump();
}
END
}
template<> template<>
- void object::test<13>()
+ void object::test<4>()
{
- clear();
set_test_name("postAndWait1");
DEBUG;
- LLCoros::instance().launch("test<13>", postAndWait1);
+ LLCoros::instance().launch("test<4>", [this](){ postAndWait1(); });
ensure_equals(result.asInteger(), 18);
}
- void postAndWait2()
- {
- BEGIN
- {
- LLEventWithID pair = ::postAndSuspend2(LLSDMap("value", 18),
- immediateAPI.getPump(),
- "reply2",
- "error2",
- "reply",
- "error");
- result = pair.first;
- which = pair.second;
- debug(STRINGIZE("result = " << result << ", which = " << which));
- }
- END
- }
-
- template<> template<>
- void object::test<14>()
- {
- clear();
- set_test_name("postAndWait2");
- DEBUG;
- LLCoros::instance().launch("test<14>", postAndWait2);
- ensure_equals(result.asInteger(), 19);
- ensure_equals(which, 0);
- }
-
- void postAndWait2_1()
- {
- BEGIN
- {
- LLEventWithID pair = ::postAndSuspend2(LLSDMap("value", 18)("fail", LLSD()),
- immediateAPI.getPump(),
- "reply2",
- "error2",
- "reply",
- "error");
- result = pair.first;
- which = pair.second;
- debug(STRINGIZE("result = " << result << ", which = " << which));
- }
- END
- }
-
- template<> template<>
- void object::test<15>()
- {
- clear();
- set_test_name("postAndWait2_1");
- DEBUG;
- LLCoros::instance().launch("test<15>", postAndWait2_1);
- ensure_equals(result.asInteger(), 19);
- ensure_equals(which, 1);
- }
-
- void coroPumpPost()
+ void test_data::coroPumpPost()
{
BEGIN
{
+ mSync.bump();
LLCoroEventPump waiter;
result = waiter.postAndSuspend(LLSDMap("value", 17),
immediateAPI.getPump(), "reply");
+ mSync.bump();
}
END
}
template<> template<>
- void object::test<16>()
+ void object::test<5>()
{
- clear();
set_test_name("coroPumpPost");
DEBUG;
- LLCoros::instance().launch("test<16>", coroPumpPost);
+ LLCoros::instance().launch("test<5>", [this](){ coroPumpPost(); });
ensure_equals(result.asInteger(), 18);
}
- void coroPumpsPost()
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- LLEventWithID pair(waiter.postAndSuspend(LLSDMap("value", 23),
- immediateAPI.getPump(), "reply", "error"));
- result = pair.first;
- which = pair.second;
- }
- END
- }
-
- template<> template<>
- void object::test<17>()
- {
- clear();
- set_test_name("coroPumpsPost reply");
- DEBUG;
- LLCoros::instance().launch("test<17>", coroPumpsPost);
- ensure_equals(result.asInteger(), 24);
- ensure_equals("which pump", which, 0);
- }
-
- void coroPumpsPost_1()
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- LLEventWithID pair(
- waiter.postAndSuspend(LLSDMap("value", 23)("fail", LLSD()),
- immediateAPI.getPump(), "reply", "error"));
- result = pair.first;
- which = pair.second;
- }
- END
- }
-
- template<> template<>
- void object::test<18>()
- {
- clear();
- set_test_name("coroPumpsPost error");
- DEBUG;
- LLCoros::instance().launch("test<18>", coroPumpsPost_1);
- ensure_equals(result.asInteger(), 24);
- ensure_equals("which pump", which, 1);
- }
-
- void coroPumpsPostNoEx()
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- result = waiter.postAndSuspendWithException(LLSDMap("value", 8),
- immediateAPI.getPump(), "reply", "error");
- }
- END
- }
-
- template<> template<>
- void object::test<19>()
- {
- clear();
- set_test_name("coroPumpsPostNoEx");
- DEBUG;
- LLCoros::instance().launch("test<19>", coroPumpsPostNoEx);
- ensure_equals(result.asInteger(), 9);
- }
-
- void coroPumpsPostEx()
- {
- BEGIN
+ 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)
{
- LLCoroEventPumps waiter;
- try
- {
- result = waiter.postAndSuspendWithException(
- LLSDMap("value", 9)("fail", LLSD()),
- immediateAPI.getPump(), "reply", "error");
- debug("no exception");
- }
- catch (const LLErrorEvent& e)
- {
- debug(STRINGIZE("exception " << e.what()));
- errordata = e.getData();
- }
+ LL_DEBUGS() << "test() waiting for coro done" << LL_ENDL;
+ llcoro::suspendUntilTimeout(0.1);
}
- END
+ // 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<20>()
- {
- clear();
- set_test_name("coroPumpsPostEx");
- DEBUG;
- LLCoros::instance().launch("test<20>", coroPumpsPostEx);
- ensure("no result", result.isUndefined());
- ensure_equals("got error", errordata.asInteger(), 10);
- }
-
- void coroPumpsPostNoLog()
- {
- BEGIN
- {
- LLCoroEventPumps waiter;
- result = waiter.postAndSuspendWithLog(LLSDMap("value", 30),
- immediateAPI.getPump(), "reply", "error");
- }
- END
- }
-
- template<> template<>
- void object::test<21>()
- {
- clear();
- set_test_name("coroPumpsPostNoLog");
- DEBUG;
- LLCoros::instance().launch("test<21>", coroPumpsPostNoLog);
- ensure_equals(result.asInteger(), 31);
- }
-
- void coroPumpsPostLog()
+ void object::test<6>()
{
- BEGIN
- {
- LLCoroEventPumps waiter;
- WrapLLErrs capture;
- threw = capture.catch_llerrs(
- [&waiter, &debug](){
- result = waiter.postAndSuspendWithLog(
- LLSDMap("value", 31)("fail", LLSD()),
- immediateAPI.getPump(), "reply", "error");
- debug("no exception");
- });
- }
- END
+ set_test_name("LLEventMailDrop");
+ tut::test<LLEventMailDrop>();
}
template<> template<>
- void object::test<22>()
+ void object::test<7>()
{
- clear();
- set_test_name("coroPumpsPostLog");
- DEBUG;
- LLCoros::instance().launch("test<22>", coroPumpsPostLog);
- ensure("no result", result.isUndefined());
- ensure_contains("got error", threw, "32");
+ set_test_name("LLEventLogProxyFor<LLEventMailDrop>");
+ tut::test< LLEventLogProxyFor<LLEventMailDrop> >();
}
}
-
-/*==========================================================================*|
-#include <boost/context/guarded_stack_allocator.hpp>
-
-namespace tut
-{
- template<> template<>
- void object::test<23>()
- {
- set_test_name("stacksize");
- std::cout << "default_stacksize: " << boost::context::guarded_stack_allocator::default_stacksize() << '\n';
- }
-} // namespace tut
-|*==========================================================================*/