Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Unified Diff: mojo/edk/system/wait_set_dispatcher_unittest.cc

Issue 2093763002: Implement WaitSetDispatcher::WaitSetWaitImpl(). (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: doh Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/edk/system/wait_set_dispatcher.cc ('k') | mojo/public/c/system/wait_set.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/edk/system/wait_set_dispatcher_unittest.cc
diff --git a/mojo/edk/system/wait_set_dispatcher_unittest.cc b/mojo/edk/system/wait_set_dispatcher_unittest.cc
index 41b6f59a3177f045bb1bd70dfc7f826a44326dbc..0c891e0591a0297bac347ad2d9b48f1cde749d03 100644
--- a/mojo/edk/system/wait_set_dispatcher_unittest.cc
+++ b/mojo/edk/system/wait_set_dispatcher_unittest.cc
@@ -13,38 +13,84 @@ namespace mojo {
namespace system {
namespace {
+// Helper to check if an array of |MojoWaitSetResult|s has a result |r| for the
+// given cookie, in which case:
+// - |r.wait_result| must equal |wait_result|.
+// - If |wait_result| is |MOJO_RESULT_OK| or
+// |MOJO_RESULT_FAILED_PRECONDITION|, then
+// - |r.signals_state.satisfied_signals & signals| must equal
+// |signals_state.satisfied_signals & signals|, and
+// - |r.signals_state.satisfiable & signals| must equal
+// |signals_state.satisfiable_signals & signals|.
+// - Otherwise, |r.signals_state| must equals |signals_state|.
+// (This doesn't check that the result is unique; you should check |num_results|
+// versus the expect number and exhaustively check every expected result.)
+bool CheckHasResult(uint32_t num_results,
+ const MojoWaitSetResult* results,
+ uint64_t cookie,
+ MojoHandleSignals signals,
+ MojoResult wait_result,
+ const MojoHandleSignalsState& signals_state) {
+ for (uint32_t i = 0; i < num_results; i++) {
+ if (results[i].cookie == cookie) {
+ EXPECT_EQ(wait_result, results[i].wait_result) << cookie;
+ EXPECT_EQ(0u, results[i].reserved) << cookie;
+ if (wait_result == MOJO_RESULT_OK ||
+ wait_result == MOJO_RESULT_FAILED_PRECONDITION) {
+ EXPECT_EQ(signals_state.satisfied_signals & signals,
+ results[i].signals_state.satisfied_signals & signals)
+ << cookie;
+ EXPECT_EQ(signals_state.satisfiable_signals & signals,
+ results[i].signals_state.satisfiable_signals & signals)
+ << cookie;
+ } else {
+ EXPECT_EQ(signals_state.satisfied_signals,
+ results[i].signals_state.satisfied_signals)
+ << cookie;
+ EXPECT_EQ(signals_state.satisfiable_signals,
+ results[i].signals_state.satisfiable_signals)
+ << cookie;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
TEST(WaitSetDispatcherTest, Basic) {
+ static constexpr auto kR = MOJO_HANDLE_SIGNAL_READABLE;
+ static constexpr auto kW = MOJO_HANDLE_SIGNAL_WRITABLE;
+
+ static constexpr auto kIndefinite = MOJO_DEADLINE_INDEFINITE;
+ static constexpr auto k10ms = static_cast<MojoDeadline>(10 * 1000u);
+
auto d = WaitSetDispatcher::Create(WaitSetDispatcher::kDefaultCreateOptions);
// These will be members of our wait set.
- auto d_member0 = MakeRefCounted<test::MockSimpleDispatcher>(
- MOJO_HANDLE_SIGNAL_NONE,
- MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE);
- auto d_member1 = MakeRefCounted<test::MockSimpleDispatcher>(
- MOJO_HANDLE_SIGNAL_READABLE, MOJO_HANDLE_SIGNAL_READABLE);
+ auto d_member0 = MakeRefCounted<test::MockSimpleDispatcher>(kW, kR | kW);
+ auto d_member1 = MakeRefCounted<test::MockSimpleDispatcher>(kR, kR);
// Add |d_member0|, for something not satisfied, but satisfiable.
- const uint64_t kCookie0 = 0x123456789abcdef0ULL;
- EXPECT_EQ(MOJO_RESULT_OK,
- d->WaitSetAdd(NullUserPointer(), d_member0.Clone(),
- MOJO_HANDLE_SIGNAL_READABLE, kCookie0));
+ static constexpr uint64_t kCookie0 = 0x123456789abcdef0ULL;
+ static constexpr auto kSignals0 = kR;
+ EXPECT_EQ(MOJO_RESULT_OK, d->WaitSetAdd(NullUserPointer(), d_member0.Clone(),
+ kSignals0, kCookie0));
// Add |d_member1|, for something satisfied.
- const uint64_t kCookie1 = 0x23456789abcdef01ULL;
- EXPECT_EQ(MOJO_RESULT_OK,
- d->WaitSetAdd(NullUserPointer(), d_member1.Clone(),
- MOJO_HANDLE_SIGNAL_READABLE, kCookie1));
+ static constexpr uint64_t kCookie1 = 0x23456789abcdef01ULL;
+ static constexpr auto kSignals1 = kR;
+ EXPECT_EQ(MOJO_RESULT_OK, d->WaitSetAdd(NullUserPointer(), d_member1.Clone(),
+ kSignals1, kCookie1));
- // Can add |d_member0| again, with a different cookie.
- const uint64_t kCookie2 = 0x3456789abcdef012ULL;
- EXPECT_EQ(MOJO_RESULT_OK,
- d->WaitSetAdd(NullUserPointer(), d_member0.Clone(),
- MOJO_HANDLE_SIGNAL_WRITABLE, kCookie2));
+ // Can add |d_member0| again (satisfied), with a different cookie.
+ static constexpr uint64_t kCookie2 = 0x3456789abcdef012ULL;
+ static constexpr auto kSignals2 = kW;
+ EXPECT_EQ(MOJO_RESULT_OK, d->WaitSetAdd(NullUserPointer(), d_member0.Clone(),
+ kSignals2, kCookie2));
// Adding something with the same cookie yields "already exists".
EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
- d->WaitSetAdd(NullUserPointer(), d_member1.Clone(),
- MOJO_HANDLE_SIGNAL_READABLE, kCookie2));
+ d->WaitSetAdd(NullUserPointer(), d_member1.Clone(), kR, kCookie2));
// Can remove something based on a cookie.
EXPECT_EQ(MOJO_RESULT_OK, d->WaitSetRemove(kCookie0));
@@ -52,17 +98,134 @@ TEST(WaitSetDispatcherTest, Basic) {
// Trying to remove the same cookie again should fail.
EXPECT_EQ(MOJO_RESULT_NOT_FOUND, d->WaitSetRemove(kCookie0));
- // Can re-add it.
+ // Can re-add it (still not satisfied, but satisfiable).
EXPECT_EQ(MOJO_RESULT_OK,
- d->WaitSetAdd(NullUserPointer(), d_member0.Clone(),
- MOJO_HANDLE_SIGNAL_READABLE, kCookie0));
-
- // TODO(vtl): Test waiting here.
-
- // Can close a dispatcher that's "in" the wait set.
+ d->WaitSetAdd(NullUserPointer(), d_member0.Clone(), kR, kCookie0));
+
+ // Wait. Recall:
+ // - |kCookie0| is for |d_member0| and is not satisfied (but satisfiable).
+ // - |kCookie1| is for |d_member1| and is satisfied.
+ // - |kCookie2| is for |d_member0| and is satisfied.
+ {
+ uint32_t num_results = 10u;
+ MojoWaitSetResult results[10] = {};
+ uint32_t max_results = static_cast<uint32_t>(-1);
+ EXPECT_EQ(MOJO_RESULT_OK,
+ d->WaitSetWait(k10ms, MakeUserPointer(&num_results),
+ MakeUserPointer(results),
+ MakeUserPointer(&max_results)));
+ EXPECT_EQ(2u, num_results);
+ EXPECT_EQ(2u, max_results);
+
+ EXPECT_TRUE(CheckHasResult(num_results, results, kCookie1, kSignals1,
+ MOJO_RESULT_OK,
+ d_member1->GetHandleSignalsState()));
+ EXPECT_TRUE(CheckHasResult(num_results, results, kCookie2, kSignals2,
+ MOJO_RESULT_OK,
+ d_member0->GetHandleSignalsState()));
+ }
+
+ // Do the same, but test the "indefinite" (forever) wait code path and only
+ // allow one result.
+ {
+ uint32_t num_results = 1u;
+ MojoWaitSetResult results[1] = {};
+ uint32_t max_results = static_cast<uint32_t>(-1);
+ EXPECT_EQ(MOJO_RESULT_OK,
+ d->WaitSetWait(kIndefinite, MakeUserPointer(&num_results),
+ MakeUserPointer(results),
+ MakeUserPointer(&max_results)));
+ EXPECT_EQ(1u, num_results);
+ EXPECT_EQ(2u, max_results);
+
+ // We should have *one* of the results.
+ EXPECT_TRUE(
+ CheckHasResult(num_results, results, kCookie1, kSignals1,
+ MOJO_RESULT_OK, d_member1->GetHandleSignalsState()) ||
+ CheckHasResult(num_results, results, kCookie2, kSignals2,
+ MOJO_RESULT_OK, d_member0->GetHandleSignalsState()));
+ }
+
+ // Change the state of |d_member0|. This makes |kCookie0| satisfied.
+ d_member0->SetSatisfiedSignals(kR | kW);
+
+ // Wait.
+ {
+ uint32_t num_results = 3u;
+ MojoWaitSetResult results[3] = {};
+ uint32_t max_results = static_cast<uint32_t>(-1);
+ EXPECT_EQ(MOJO_RESULT_OK,
+ d->WaitSetWait(k10ms, MakeUserPointer(&num_results),
+ MakeUserPointer(results),
+ MakeUserPointer(&max_results)));
+ EXPECT_EQ(3u, num_results);
+ EXPECT_EQ(3u, max_results);
+
+ EXPECT_TRUE(CheckHasResult(num_results, results, kCookie0, kSignals0,
+ MOJO_RESULT_OK,
+ d_member0->GetHandleSignalsState()));
+ EXPECT_TRUE(CheckHasResult(num_results, results, kCookie1, kSignals1,
+ MOJO_RESULT_OK,
+ d_member1->GetHandleSignalsState()));
+ EXPECT_TRUE(CheckHasResult(num_results, results, kCookie2, kSignals2,
+ MOJO_RESULT_OK,
+ d_member0->GetHandleSignalsState()));
+ }
+
+ // Change the state of |d_member0| in two steps. |kCookie0| remains satisfied,
+ // but |kCookie2| becomes unsatisfiable.
+ d_member0->SetSatisfiedSignals(kR);
+ d_member0->SetSatisfiableSignals(kR);
+
+ // Wait.
+ {
+ uint32_t num_results = 10u;
+ MojoWaitSetResult results[10] = {};
+ uint32_t max_results = static_cast<uint32_t>(-1);
+ EXPECT_EQ(MOJO_RESULT_OK,
+ d->WaitSetWait(k10ms, MakeUserPointer(&num_results),
+ MakeUserPointer(results),
+ MakeUserPointer(&max_results)));
+ EXPECT_EQ(3u, num_results);
+ EXPECT_EQ(3u, max_results);
+
+ EXPECT_TRUE(CheckHasResult(num_results, results, kCookie0, kSignals0,
+ MOJO_RESULT_OK,
+ d_member0->GetHandleSignalsState()));
+ EXPECT_TRUE(CheckHasResult(num_results, results, kCookie1, kSignals1,
+ MOJO_RESULT_OK,
+ d_member1->GetHandleSignalsState()));
+ EXPECT_TRUE(CheckHasResult(num_results, results, kCookie2, kSignals2,
+ MOJO_RESULT_FAILED_PRECONDITION,
+ d_member0->GetHandleSignalsState()));
+ }
+
+ // Can close a dispatcher that's "in" the wait set. This should make
+ // |kCookie1| "cancelled".
EXPECT_EQ(MOJO_RESULT_OK, d_member1->Close());
- // TODO(vtl): Test waiting here.
+ // Wait.
+ {
+ uint32_t num_results = 10u;
+ MojoWaitSetResult results[10] = {};
+ uint32_t max_results = static_cast<uint32_t>(-1);
+ EXPECT_EQ(MOJO_RESULT_OK,
+ d->WaitSetWait(k10ms, MakeUserPointer(&num_results),
+ MakeUserPointer(results),
+ MakeUserPointer(&max_results)));
+ EXPECT_EQ(3u, num_results);
+ EXPECT_EQ(3u, max_results);
+
+ EXPECT_TRUE(CheckHasResult(num_results, results, kCookie0, kSignals0,
+ MOJO_RESULT_OK,
+ d_member0->GetHandleSignalsState()));
+ EXPECT_TRUE(CheckHasResult(num_results, results, kCookie1, kSignals1,
+ MOJO_RESULT_CANCELLED,
+ MojoHandleSignalsState()));
+ EXPECT_TRUE(CheckHasResult(num_results, results, kCookie2, kSignals2,
+ MOJO_RESULT_FAILED_PRECONDITION,
+ d_member0->GetHandleSignalsState()));
+ }
// Can remove something whose dispatcher has been closed.
EXPECT_EQ(MOJO_RESULT_OK, d->WaitSetRemove(kCookie1));
« no previous file with comments | « mojo/edk/system/wait_set_dispatcher.cc ('k') | mojo/public/c/system/wait_set.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698