diff options
author | Rider Linden <rider@lindenlab.com> | 2015-07-07 19:41:27 +0100 |
---|---|---|
committer | Rider Linden <rider@lindenlab.com> | 2015-07-07 19:41:27 +0100 |
commit | 247eb0c9c3418c10be8f2a0e3c8116758efa702f (patch) | |
tree | d3a448c69f1ad241dc72662970d702c2aa618382 /indra/llcommon/tests/lleventcoro_test.cpp | |
parent | d785ec312bb7f4e77517eb44f46f276ba0129677 (diff) |
Backout selfles merge 738255dbbfd679d9e615baab3398e5e345bbb3c5
Diffstat (limited to 'indra/llcommon/tests/lleventcoro_test.cpp')
-rwxr-xr-x | indra/llcommon/tests/lleventcoro_test.cpp | 712 |
1 files changed, 365 insertions, 347 deletions
diff --git a/indra/llcommon/tests/lleventcoro_test.cpp b/indra/llcommon/tests/lleventcoro_test.cpp index da927038ab..2096807e53 100755 --- a/indra/llcommon/tests/lleventcoro_test.cpp +++ b/indra/llcommon/tests/lleventcoro_test.cpp @@ -82,7 +82,6 @@ #include "llevents.h" #include "tests/wrapllerrs.h" #include "stringize.h" -#include "llcoros.h" #include "lleventcoro.h" #include "../test/debug.h" @@ -122,6 +121,9 @@ typedef coroutine<std::string::iterator(void)> match_coroutine_type; /***************************************************************************** * Test helpers *****************************************************************************/ +// I suspect this will be typical of coroutines used in Linden software +typedef boost::dcoroutines::coroutine<void()> coroutine_type; + /// Simulate an event API whose response is immediate: sent on receipt of the /// initial request, rather than after some delay. This is the case that /// distinguishes postAndWait() from calling post(), then calling @@ -160,7 +162,306 @@ private: *****************************************************************************/ namespace tut { - struct coroutine_data {}; + struct coroutine_data + { + // Define coroutine bodies as methods here so they can use ensure*() + + void explicit_wait(coroutine_type::self& self) + { + BEGIN + { + // ... do whatever preliminary stuff must happen ... + + // declare the future + boost::dcoroutines::future<LLSD> future(self); + // tell the future what to wait for + LLTempBoundListener connection( + LLEventPumps::instance().obtain("source").listen("coro", voidlistener(boost::dcoroutines::make_callback(future)))); + ensure("Not yet", ! future); + // attempting to dereference ("resolve") the future causes the calling + // coroutine to wait for it + debug("about to wait"); + result = *future; + ensure("Got it", future); + } + END + } + + void waitForEventOn1(coroutine_type::self& self) + { + BEGIN + { + result = waitForEventOn(self, "source"); + } + END + } + + void waitForEventOn2(coroutine_type::self& self) + { + BEGIN + { + LLEventWithID pair = waitForEventOn(self, "reply", "error"); + result = pair.first; + which = pair.second; + debug(STRINGIZE("result = " << result << ", which = " << which)); + } + END + } + + void postAndWait1(coroutine_type::self& self) + { + BEGIN + { + result = postAndWait(self, + LLSDMap("value", 17), // request event + immediateAPI.getPump(), // requestPump + "reply1", // replyPump + "reply"); // request["reply"] = name + } + END + } + + void postAndWait2(coroutine_type::self& self) + { + BEGIN + { + LLEventWithID pair = ::postAndWait2(self, + LLSDMap("value", 18), + immediateAPI.getPump(), + "reply2", + "error2", + "reply", + "error"); + result = pair.first; + which = pair.second; + debug(STRINGIZE("result = " << result << ", which = " << which)); + } + END + } + + void postAndWait2_1(coroutine_type::self& self) + { + BEGIN + { + LLEventWithID pair = ::postAndWait2(self, + LLSDMap("value", 18)("fail", LLSD()), + immediateAPI.getPump(), + "reply2", + "error2", + "reply", + "error"); + result = pair.first; + which = pair.second; + debug(STRINGIZE("result = " << result << ", which = " << which)); + } + END + } + + void coroPump(coroutine_type::self& self) + { + BEGIN + { + LLCoroEventPump waiter; + replyName = waiter.getName(); + result = waiter.wait(self); + } + END + } + + void coroPumpPost(coroutine_type::self& self) + { + BEGIN + { + LLCoroEventPump waiter; + result = waiter.postAndWait(self, LLSDMap("value", 17), + immediateAPI.getPump(), "reply"); + } + END + } + + void coroPumps(coroutine_type::self& self) + { + BEGIN + { + LLCoroEventPumps waiter; + replyName = waiter.getName0(); + errorName = waiter.getName1(); + LLEventWithID pair(waiter.wait(self)); + result = pair.first; + which = pair.second; + } + END + } + + void coroPumpsNoEx(coroutine_type::self& self) + { + BEGIN + { + LLCoroEventPumps waiter; + replyName = waiter.getName0(); + errorName = waiter.getName1(); + result = waiter.waitWithException(self); + } + END + } + + void coroPumpsEx(coroutine_type::self& self) + { + BEGIN + { + LLCoroEventPumps waiter; + replyName = waiter.getName0(); + errorName = waiter.getName1(); + try + { + result = waiter.waitWithException(self); + debug("no exception"); + } + catch (const LLErrorEvent& e) + { + debug(STRINGIZE("exception " << e.what())); + errordata = e.getData(); + } + } + END + } + + void coroPumpsNoLog(coroutine_type::self& self) + { + BEGIN + { + LLCoroEventPumps waiter; + replyName = waiter.getName0(); + errorName = waiter.getName1(); + result = waiter.waitWithLog(self); + } + END + } + + void coroPumpsLog(coroutine_type::self& self) + { + BEGIN + { + LLCoroEventPumps waiter; + replyName = waiter.getName0(); + errorName = waiter.getName1(); + WrapLLErrs capture; + try + { + result = waiter.waitWithLog(self); + debug("no exception"); + } + catch (const WrapLLErrs::FatalException& e) + { + debug(STRINGIZE("exception " << e.what())); + threw = e.what(); + } + } + END + } + + void coroPumpsPost(coroutine_type::self& self) + { + BEGIN + { + LLCoroEventPumps waiter; + LLEventWithID pair(waiter.postAndWait(self, LLSDMap("value", 23), + immediateAPI.getPump(), "reply", "error")); + result = pair.first; + which = pair.second; + } + END + } + + void coroPumpsPost_1(coroutine_type::self& self) + { + BEGIN + { + LLCoroEventPumps waiter; + LLEventWithID pair( + waiter.postAndWait(self, LLSDMap("value", 23)("fail", LLSD()), + immediateAPI.getPump(), "reply", "error")); + result = pair.first; + which = pair.second; + } + END + } + + void coroPumpsPostNoEx(coroutine_type::self& self) + { + BEGIN + { + LLCoroEventPumps waiter; + result = waiter.postAndWaitWithException(self, LLSDMap("value", 8), + immediateAPI.getPump(), "reply", "error"); + } + END + } + + void coroPumpsPostEx(coroutine_type::self& self) + { + BEGIN + { + LLCoroEventPumps waiter; + try + { + result = waiter.postAndWaitWithException(self, + LLSDMap("value", 9)("fail", LLSD()), + immediateAPI.getPump(), "reply", "error"); + debug("no exception"); + } + catch (const LLErrorEvent& e) + { + debug(STRINGIZE("exception " << e.what())); + errordata = e.getData(); + } + } + END + } + + void coroPumpsPostNoLog(coroutine_type::self& self) + { + BEGIN + { + LLCoroEventPumps waiter; + result = waiter.postAndWaitWithLog(self, LLSDMap("value", 30), + immediateAPI.getPump(), "reply", "error"); + } + END + } + + void coroPumpsPostLog(coroutine_type::self& self) + { + BEGIN + { + LLCoroEventPumps waiter; + WrapLLErrs capture; + try + { + result = waiter.postAndWaitWithLog(self, + LLSDMap("value", 31)("fail", LLSD()), + immediateAPI.getPump(), "reply", "error"); + debug("no exception"); + } + catch (const WrapLLErrs::FatalException& e) + { + debug(STRINGIZE("exception " << e.what())); + threw = e.what(); + } + } + END + } + + void ensure_done(coroutine_type& coro) + { + ensure("coroutine complete", ! coro); + } + + ImmediateAPI immediateAPI; + std::string replyName, errorName, threw; + LLSD result, errordata; + int which; + }; typedef test_group<coroutine_data> coroutine_group; typedef coroutine_group::object object; coroutine_group coroutinegrp("coroutine"); @@ -210,57 +511,16 @@ namespace tut 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; - LLSD result, errordata; - int which; - - // reinit vars at the start of each test - void clear() - { - replyName.clear(); - errorName.clear(); - threw.clear(); - result = LLSD(); - errordata = LLSD(); - which = 0; - } - - void explicit_wait(boost::dcoroutines::coroutine<void()>::self& self) - { - BEGIN - { - // ... do whatever preliminary stuff must happen ... - - // declare the future - boost::dcoroutines::future<LLSD> future(self); - // tell the future what to wait for - LLTempBoundListener connection( - LLEventPumps::instance().obtain("source").listen("coro", voidlistener(boost::dcoroutines::make_callback(future)))); - ensure("Not yet", ! future); - // attempting to dereference ("resolve") the future causes the calling - // coroutine to wait for it - debug("about to wait"); - result = *future; - ensure("Got it", future); - } - END - } - template<> template<> void object::test<2>() { - clear(); set_test_name("explicit_wait"); DEBUG; // Construct the coroutine instance that will run explicit_wait. // Pass the ctor a callable that accepts the coroutine_type::self // param passed by the library. - boost::dcoroutines::coroutine<void()> - coro(explicit_wait); + coroutine_type coro(boost::bind(&coroutine_data::explicit_wait, this, _1)); // Start the coroutine coro(std::nothrow); // When the coroutine waits for the event pump, it returns here. @@ -268,56 +528,37 @@ namespace tut // Satisfy the wait. LLEventPumps::instance().obtain("source").post("received"); // Now wait for the coroutine to complete. - ensure("coroutine complete", ! coro); + ensure_done(coro); // ensure the coroutine ran and woke up again with the intended result ensure_equals(result.asString(), "received"); } - void waitForEventOn1() - { - BEGIN - { - result = waitForEventOn("source"); - } - END - } - template<> template<> void object::test<3>() { - clear(); set_test_name("waitForEventOn1"); DEBUG; - LLCoros::instance().launch("test<3>", waitForEventOn1); + coroutine_type coro(boost::bind(&coroutine_data::waitForEventOn1, this, _1)); + coro(std::nothrow); debug("about to send"); LLEventPumps::instance().obtain("source").post("received"); debug("back from send"); + ensure_done(coro); ensure_equals(result.asString(), "received"); } - void waitForEventOn2() - { - BEGIN - { - LLEventWithID pair = waitForEventOn("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); + coroutine_type coro(boost::bind(&coroutine_data::waitForEventOn2, this, _1)); + coro(std::nothrow); debug("about to send"); LLEventPumps::instance().obtain("reply").post("received"); debug("back from send"); + ensure_done(coro); } ensure_equals(result.asString(), "received"); ensure_equals("which pump", which, 0); @@ -326,65 +567,43 @@ namespace tut template<> template<> void object::test<5>() { - clear(); set_test_name("waitForEventOn2 error"); DEBUG; - LLCoros::instance().launch("test<5>", waitForEventOn2); + coroutine_type coro(boost::bind(&coroutine_data::waitForEventOn2, this, _1)); + coro(std::nothrow); debug("about to send"); LLEventPumps::instance().obtain("error").post("badness"); debug("back from send"); + ensure_done(coro); ensure_equals(result.asString(), "badness"); ensure_equals("which pump", which, 1); } - void coroPump() - { - BEGIN - { - LLCoroEventPump waiter; - replyName = waiter.getName(); - result = waiter.wait(); - } - END - } - template<> template<> void object::test<6>() { - clear(); set_test_name("coroPump"); DEBUG; - LLCoros::instance().launch("test<6>", coroPump); + coroutine_type coro(boost::bind(&coroutine_data::coroPump, this, _1)); + coro(std::nothrow); debug("about to send"); LLEventPumps::instance().obtain(replyName).post("received"); debug("back from send"); + ensure_done(coro); ensure_equals(result.asString(), "received"); } - void coroPumps() - { - BEGIN - { - LLCoroEventPumps waiter; - replyName = waiter.getName0(); - errorName = waiter.getName1(); - LLEventWithID pair(waiter.wait()); - 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); + coroutine_type coro(boost::bind(&coroutine_data::coroPumps, this, _1)); + coro(std::nothrow); debug("about to send"); LLEventPumps::instance().obtain(replyName).post("received"); debug("back from send"); + ensure_done(coro); ensure_equals(result.asString(), "received"); ensure_equals("which pump", which, 0); } @@ -392,389 +611,188 @@ namespace tut template<> template<> void object::test<8>() { - clear(); set_test_name("coroPumps error"); DEBUG; - LLCoros::instance().launch("test<8>", coroPumps); + coroutine_type coro(boost::bind(&coroutine_data::coroPumps, this, _1)); + coro(std::nothrow); debug("about to send"); LLEventPumps::instance().obtain(errorName).post("badness"); debug("back from send"); + ensure_done(coro); ensure_equals(result.asString(), "badness"); ensure_equals("which pump", which, 1); } - void coroPumpsNoEx() - { - BEGIN - { - LLCoroEventPumps waiter; - replyName = waiter.getName0(); - errorName = waiter.getName1(); - result = waiter.waitWithException(); - } - END - } - template<> template<> void object::test<9>() { - clear(); set_test_name("coroPumpsNoEx"); DEBUG; - LLCoros::instance().launch("test<9>", coroPumpsNoEx); + coroutine_type coro(boost::bind(&coroutine_data::coroPumpsNoEx, this, _1)); + coro(std::nothrow); debug("about to send"); LLEventPumps::instance().obtain(replyName).post("received"); debug("back from send"); + ensure_done(coro); ensure_equals(result.asString(), "received"); } - void coroPumpsEx() - { - BEGIN - { - LLCoroEventPumps waiter; - replyName = waiter.getName0(); - errorName = waiter.getName1(); - try - { - result = waiter.waitWithException(); - 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); + coroutine_type coro(boost::bind(&coroutine_data::coroPumpsEx, this, _1)); + coro(std::nothrow); debug("about to send"); LLEventPumps::instance().obtain(errorName).post("badness"); debug("back from send"); + ensure_done(coro); 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.waitWithLog(); - } - END - } - template<> template<> void object::test<11>() { - clear(); set_test_name("coroPumpsNoLog"); DEBUG; - LLCoros::instance().launch("test<11>", coroPumpsNoLog); + coroutine_type coro(boost::bind(&coroutine_data::coroPumpsNoLog, this, _1)); + coro(std::nothrow); debug("about to send"); LLEventPumps::instance().obtain(replyName).post("received"); debug("back from send"); + ensure_done(coro); ensure_equals(result.asString(), "received"); } - void coroPumpsLog() - { - BEGIN - { - LLCoroEventPumps waiter; - replyName = waiter.getName0(); - errorName = waiter.getName1(); - WrapLLErrs capture; - try - { - result = waiter.waitWithLog(); - debug("no exception"); - } - catch (const WrapLLErrs::FatalException& e) - { - debug(STRINGIZE("exception " << e.what())); - threw = e.what(); - } - } - END - } - template<> template<> void object::test<12>() { - clear(); set_test_name("coroPumpsLog"); DEBUG; - LLCoros::instance().launch("test<12>", coroPumpsLog); + coroutine_type coro(boost::bind(&coroutine_data::coroPumpsLog, this, _1)); + coro(std::nothrow); debug("about to send"); LLEventPumps::instance().obtain(errorName).post("badness"); debug("back from send"); + ensure_done(coro); ensure("no result", result.isUndefined()); ensure_contains("got error", threw, "badness"); } - void postAndWait1() - { - BEGIN - { - result = postAndWait(LLSDMap("value", 17), // request event - immediateAPI.getPump(), // requestPump - "reply1", // replyPump - "reply"); // request["reply"] = name - } - END - } - template<> template<> void object::test<13>() { - clear(); set_test_name("postAndWait1"); DEBUG; - LLCoros::instance().launch("test<13>", postAndWait1); + coroutine_type coro(boost::bind(&coroutine_data::postAndWait1, this, _1)); + coro(std::nothrow); + ensure_done(coro); ensure_equals(result.asInteger(), 18); } - void postAndWait2() - { - BEGIN - { - LLEventWithID pair = ::postAndWait2(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); + coroutine_type coro(boost::bind(&coroutine_data::postAndWait2, this, _1)); + coro(std::nothrow); + ensure_done(coro); ensure_equals(result.asInteger(), 19); ensure_equals(which, 0); } - void postAndWait2_1() - { - BEGIN - { - LLEventWithID pair = ::postAndWait2(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); + coroutine_type coro(boost::bind(&coroutine_data::postAndWait2_1, this, _1)); + coro(std::nothrow); + ensure_done(coro); ensure_equals(result.asInteger(), 19); ensure_equals(which, 1); } - void coroPumpPost() - { - BEGIN - { - LLCoroEventPump waiter; - result = waiter.postAndWait(LLSDMap("value", 17), - immediateAPI.getPump(), "reply"); - } - END - } - template<> template<> void object::test<16>() { - clear(); set_test_name("coroPumpPost"); DEBUG; - LLCoros::instance().launch("test<16>", coroPumpPost); + coroutine_type coro(boost::bind(&coroutine_data::coroPumpPost, this, _1)); + coro(std::nothrow); + ensure_done(coro); ensure_equals(result.asInteger(), 18); } - void coroPumpsPost() - { - BEGIN - { - LLCoroEventPumps waiter; - LLEventWithID pair(waiter.postAndWait(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); + coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPost, this, _1)); + coro(std::nothrow); + ensure_done(coro); ensure_equals(result.asInteger(), 24); ensure_equals("which pump", which, 0); } - void coroPumpsPost_1() - { - BEGIN - { - LLCoroEventPumps waiter; - LLEventWithID pair( - waiter.postAndWait(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); + coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPost_1, this, _1)); + coro(std::nothrow); + ensure_done(coro); ensure_equals(result.asInteger(), 24); ensure_equals("which pump", which, 1); } - void coroPumpsPostNoEx() - { - BEGIN - { - LLCoroEventPumps waiter; - result = waiter.postAndWaitWithException(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); + coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostNoEx, this, _1)); + coro(std::nothrow); + ensure_done(coro); ensure_equals(result.asInteger(), 9); } - void coroPumpsPostEx() - { - BEGIN - { - LLCoroEventPumps waiter; - try - { - result = waiter.postAndWaitWithException( - LLSDMap("value", 9)("fail", LLSD()), - immediateAPI.getPump(), "reply", "error"); - debug("no exception"); - } - catch (const LLErrorEvent& e) - { - debug(STRINGIZE("exception " << e.what())); - errordata = e.getData(); - } - } - END - } - template<> template<> void object::test<20>() { - clear(); set_test_name("coroPumpsPostEx"); DEBUG; - LLCoros::instance().launch("test<20>", coroPumpsPostEx); + coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostEx, this, _1)); + coro(std::nothrow); + ensure_done(coro); ensure("no result", result.isUndefined()); ensure_equals("got error", errordata.asInteger(), 10); } - void coroPumpsPostNoLog() - { - BEGIN - { - LLCoroEventPumps waiter; - result = waiter.postAndWaitWithLog(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); + coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostNoLog, this, _1)); + coro(std::nothrow); + ensure_done(coro); ensure_equals(result.asInteger(), 31); } - void coroPumpsPostLog() - { - BEGIN - { - LLCoroEventPumps waiter; - WrapLLErrs capture; - try - { - result = waiter.postAndWaitWithLog( - LLSDMap("value", 31)("fail", LLSD()), - immediateAPI.getPump(), "reply", "error"); - debug("no exception"); - } - catch (const WrapLLErrs::FatalException& e) - { - debug(STRINGIZE("exception " << e.what())); - threw = e.what(); - } - } - END - } - template<> template<> void object::test<22>() { - clear(); set_test_name("coroPumpsPostLog"); DEBUG; - LLCoros::instance().launch("test<22>", coroPumpsPostLog); + coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostLog, this, _1)); + coro(std::nothrow); + ensure_done(coro); ensure("no result", result.isUndefined()); ensure_contains("got error", threw, "32"); } |