1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // NOTE(vtl): Some of these tests are inherently flaky (e.g., if run on a
6 // heavily-loaded system). Sorry. |test::EpsilonTimeout()| may be increased to
7 // increase tolerance and reduce observed flakiness (though doing so reduces the
8 // meaningfulness of the test).
10 #include "mojo/system/simple_dispatcher.h"
12 #include "base/basictypes.h"
13 #include "base/logging.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_vector.h"
16 #include "base/synchronization/lock.h"
17 #include "base/threading/platform_thread.h" // For |Sleep()|.
18 #include "base/time/time.h"
19 #include "mojo/system/test_utils.h"
20 #include "mojo/system/waiter.h"
21 #include "mojo/system/waiter_test_utils.h"
22 #include "testing/gtest/include/gtest/gtest.h"
28 class MockSimpleDispatcher : public SimpleDispatcher {
30 MockSimpleDispatcher()
31 : state_(MOJO_HANDLE_SIGNAL_NONE,
32 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE) {}
34 void SetSatisfiedSignals(MojoHandleSignals new_satisfied_signals) {
35 base::AutoLock locker(lock());
37 // Any new signals that are set should be satisfiable.
38 CHECK_EQ(new_satisfied_signals & ~state_.satisfied_signals,
39 new_satisfied_signals & ~state_.satisfied_signals &
40 state_.satisfiable_signals);
42 if (new_satisfied_signals == state_.satisfied_signals)
45 state_.satisfied_signals = new_satisfied_signals;
46 HandleSignalsStateChangedNoLock();
49 void SetSatisfiableSignals(MojoHandleSignals new_satisfiable_signals) {
50 base::AutoLock locker(lock());
52 // Satisfied implies satisfiable.
53 CHECK_EQ(new_satisfiable_signals & state_.satisfied_signals,
54 state_.satisfied_signals);
56 if (new_satisfiable_signals == state_.satisfiable_signals)
59 state_.satisfiable_signals = new_satisfiable_signals;
60 HandleSignalsStateChangedNoLock();
63 virtual Type GetType() const OVERRIDE {
68 friend class base::RefCountedThreadSafe<MockSimpleDispatcher>;
69 virtual ~MockSimpleDispatcher() {}
71 virtual scoped_refptr<Dispatcher>
72 CreateEquivalentDispatcherAndCloseImplNoLock() OVERRIDE {
73 scoped_refptr<MockSimpleDispatcher> rv(new MockSimpleDispatcher());
75 return scoped_refptr<Dispatcher>(rv.get());
78 // |SimpleDispatcher| implementation:
79 virtual HandleSignalsState GetHandleSignalsStateNoLock() const OVERRIDE {
80 lock().AssertAcquired();
84 // Protected by |lock()|:
85 HandleSignalsState state_;
87 DISALLOW_COPY_AND_ASSIGN(MockSimpleDispatcher);
90 TEST(SimpleDispatcherTest, Basic) {
91 test::Stopwatch stopwatch;
93 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
97 // Try adding a readable waiter when already readable.
99 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
100 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
101 d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_READABLE, 0));
102 // Shouldn't need to remove the waiter (it was not added).
104 // Wait (forever) for writable when already writable.
106 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
107 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 1));
108 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_WRITABLE);
110 EXPECT_EQ(MOJO_RESULT_OK, w.Wait(MOJO_DEADLINE_INDEFINITE, &context));
111 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
112 EXPECT_EQ(1u, context);
115 // Wait for zero time for writable when already writable.
117 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
118 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 2));
119 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_WRITABLE);
121 EXPECT_EQ(MOJO_RESULT_OK, w.Wait(0, &context));
122 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
123 EXPECT_EQ(2u, context);
126 // Wait for non-zero, finite time for writable when already writable.
128 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
129 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 3));
130 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_WRITABLE);
132 EXPECT_EQ(MOJO_RESULT_OK,
133 w.Wait(2 * test::EpsilonTimeout().InMicroseconds(), &context));
134 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
135 EXPECT_EQ(3u, context);
138 // Wait for zero time for writable when not writable (will time out).
140 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
141 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 4));
143 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(0, NULL));
144 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
147 // Wait for non-zero, finite time for writable when not writable (will time
150 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
151 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 5));
153 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
154 w.Wait(2 * test::EpsilonTimeout().InMicroseconds(), NULL));
155 base::TimeDelta elapsed = stopwatch.Elapsed();
156 EXPECT_GT(elapsed, (2-1) * test::EpsilonTimeout());
157 EXPECT_LT(elapsed, (2+1) * test::EpsilonTimeout());
160 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
163 TEST(SimpleDispatcherTest, BasicUnsatisfiable) {
164 test::Stopwatch stopwatch;
166 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
168 uint32_t context = 0;
170 // Try adding a writable waiter when it can never be writable.
172 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE);
173 d->SetSatisfiedSignals(0);
174 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
175 d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 1));
176 // Shouldn't need to remove the waiter (it was not added).
178 // Wait (forever) for writable and then it becomes never writable.
180 d->SetSatisfiableSignals(
181 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE);
182 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 2));
183 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE);
185 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
186 w.Wait(MOJO_DEADLINE_INDEFINITE, &context));
187 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
188 EXPECT_EQ(2u, context);
191 // Wait for zero time for writable and then it becomes never writable.
193 d->SetSatisfiableSignals(
194 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE);
195 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 3));
196 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE);
198 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, w.Wait(0, &context));
199 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
200 EXPECT_EQ(3u, context);
203 // Wait for non-zero, finite time for writable and then it becomes never
206 d->SetSatisfiableSignals(
207 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE);
208 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 4));
209 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE);
211 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
212 w.Wait(2 * test::EpsilonTimeout().InMicroseconds(), &context));
213 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
214 EXPECT_EQ(4u, context);
217 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
220 TEST(SimpleDispatcherTest, BasicClosed) {
221 test::Stopwatch stopwatch;
223 scoped_refptr<MockSimpleDispatcher> d;
225 uint32_t context = 0;
227 // Try adding a writable waiter when the dispatcher has been closed.
228 d = new MockSimpleDispatcher();
230 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
231 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
232 d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 1));
233 // Shouldn't need to remove the waiter (it was not added).
235 // Wait (forever) for writable and then the dispatcher is closed.
236 d = new MockSimpleDispatcher();
238 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 2));
239 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
241 EXPECT_EQ(MOJO_RESULT_CANCELLED, w.Wait(MOJO_DEADLINE_INDEFINITE, &context));
242 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
243 EXPECT_EQ(2u, context);
244 // Don't need to remove waiters from closed dispatchers.
246 // Wait for zero time for writable and then the dispatcher is closed.
247 d = new MockSimpleDispatcher();
249 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 3));
250 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
252 EXPECT_EQ(MOJO_RESULT_CANCELLED, w.Wait(0, &context));
253 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
254 EXPECT_EQ(3u, context);
255 // Don't need to remove waiters from closed dispatchers.
257 // Wait for non-zero, finite time for writable and then the dispatcher is
259 d = new MockSimpleDispatcher();
261 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 4));
262 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
264 EXPECT_EQ(MOJO_RESULT_CANCELLED,
265 w.Wait(2 * test::EpsilonTimeout().InMicroseconds(), &context));
266 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
267 EXPECT_EQ(4u, context);
268 // Don't need to remove waiters from closed dispatchers.
271 TEST(SimpleDispatcherTest, BasicThreaded) {
272 test::Stopwatch stopwatch;
277 // Wait for readable (already readable).
279 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
281 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
282 test::WaiterThread thread(d,
283 MOJO_HANDLE_SIGNAL_READABLE,
284 MOJO_DEADLINE_INDEFINITE,
286 &did_wait, &result, &context);
289 } // Joins the thread.
290 // If we closed earlier, then probably we'd get a |MOJO_RESULT_CANCELLED|.
291 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
293 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
294 EXPECT_FALSE(did_wait);
295 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, result);
297 // Wait for readable and becomes readable after some time.
299 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
300 test::WaiterThread thread(d,
301 MOJO_HANDLE_SIGNAL_READABLE,
302 MOJO_DEADLINE_INDEFINITE,
304 &did_wait, &result, &context);
307 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
308 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
309 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
310 } // Joins the thread.
311 base::TimeDelta elapsed = stopwatch.Elapsed();
312 EXPECT_GT(elapsed, (2-1) * test::EpsilonTimeout());
313 EXPECT_LT(elapsed, (2+1) * test::EpsilonTimeout());
314 EXPECT_TRUE(did_wait);
315 EXPECT_EQ(MOJO_RESULT_OK, result);
316 EXPECT_EQ(2u, context);
318 // Wait for readable and becomes never-readable after some time.
320 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
321 test::WaiterThread thread(d,
322 MOJO_HANDLE_SIGNAL_READABLE,
323 MOJO_DEADLINE_INDEFINITE,
325 &did_wait, &result, &context);
328 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
329 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_NONE);
330 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
331 } // Joins the thread.
332 elapsed = stopwatch.Elapsed();
333 EXPECT_GT(elapsed, (2-1) * test::EpsilonTimeout());
334 EXPECT_LT(elapsed, (2+1) * test::EpsilonTimeout());
335 EXPECT_TRUE(did_wait);
336 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
337 EXPECT_EQ(3u, context);
339 // Wait for readable and dispatcher gets closed.
341 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
342 test::WaiterThread thread(d,
343 MOJO_HANDLE_SIGNAL_READABLE,
344 MOJO_DEADLINE_INDEFINITE,
346 &did_wait, &result, &context);
349 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
350 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
351 } // Joins the thread.
352 elapsed = stopwatch.Elapsed();
353 EXPECT_GT(elapsed, (2-1) * test::EpsilonTimeout());
354 EXPECT_LT(elapsed, (2+1) * test::EpsilonTimeout());
355 EXPECT_TRUE(did_wait);
356 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
357 EXPECT_EQ(4u, context);
359 // Wait for readable and times out.
361 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
363 test::WaiterThread thread(d,
364 MOJO_HANDLE_SIGNAL_READABLE,
365 2 * test::EpsilonTimeout().InMicroseconds(),
367 &did_wait, &result, &context);
370 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
371 // Not what we're waiting for.
372 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_WRITABLE);
373 } // Joins the thread (after its wait times out).
374 // If we closed earlier, then probably we'd get a |MOJO_RESULT_CANCELLED|.
375 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
377 elapsed = stopwatch.Elapsed();
378 EXPECT_GT(elapsed, (2-1) * test::EpsilonTimeout());
379 EXPECT_LT(elapsed, (2+1) * test::EpsilonTimeout());
380 EXPECT_TRUE(did_wait);
381 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, result);
384 TEST(SimpleDispatcherTest, MultipleWaiters) {
385 static const uint32_t kNumWaiters = 20;
387 bool did_wait[kNumWaiters];
388 MojoResult result[kNumWaiters];
389 uint32_t context[kNumWaiters];
391 // All wait for readable and becomes readable after some time.
393 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
394 ScopedVector<test::WaiterThread> threads;
395 for (uint32_t i = 0; i < kNumWaiters; i++) {
396 threads.push_back(new test::WaiterThread(d,
397 MOJO_HANDLE_SIGNAL_READABLE,
398 MOJO_DEADLINE_INDEFINITE,
403 threads.back()->Start();
405 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
406 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
407 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
408 } // Joins the threads.
409 for (uint32_t i = 0; i < kNumWaiters; i++) {
410 EXPECT_TRUE(did_wait[i]);
411 EXPECT_EQ(MOJO_RESULT_OK, result[i]);
412 EXPECT_EQ(i, context[i]);
415 // Some wait for readable, some for writable, and becomes readable after some
418 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
419 ScopedVector<test::WaiterThread> threads;
420 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
421 threads.push_back(new test::WaiterThread(d,
422 MOJO_HANDLE_SIGNAL_READABLE,
423 MOJO_DEADLINE_INDEFINITE,
428 threads.back()->Start();
430 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
431 threads.push_back(new test::WaiterThread(d,
432 MOJO_HANDLE_SIGNAL_WRITABLE,
433 MOJO_DEADLINE_INDEFINITE,
438 threads.back()->Start();
440 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
441 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
442 // This will wake up the ones waiting to write.
443 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
444 } // Joins the threads.
445 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
446 EXPECT_TRUE(did_wait[i]);
447 EXPECT_EQ(MOJO_RESULT_OK, result[i]);
448 EXPECT_EQ(i, context[i]);
450 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
451 EXPECT_TRUE(did_wait[i]);
452 EXPECT_EQ(MOJO_RESULT_CANCELLED, result[i]);
453 EXPECT_EQ(i, context[i]);
456 // Some wait for readable, some for writable, and becomes readable and
457 // never-writable after some time.
459 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
460 ScopedVector<test::WaiterThread> threads;
461 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
462 threads.push_back(new test::WaiterThread(d,
463 MOJO_HANDLE_SIGNAL_READABLE,
464 MOJO_DEADLINE_INDEFINITE,
469 threads.back()->Start();
471 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
472 threads.push_back(new test::WaiterThread(d,
473 MOJO_HANDLE_SIGNAL_WRITABLE,
474 MOJO_DEADLINE_INDEFINITE,
479 threads.back()->Start();
481 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
482 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE);
483 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
484 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
485 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
486 } // Joins the threads.
487 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
488 EXPECT_TRUE(did_wait[i]);
489 EXPECT_EQ(MOJO_RESULT_OK, result[i]);
490 EXPECT_EQ(i, context[i]);
492 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
493 EXPECT_TRUE(did_wait[i]);
494 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result[i]);
495 EXPECT_EQ(i, context[i]);
498 // Some wait for readable, some for writable, and becomes readable after some
501 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
502 ScopedVector<test::WaiterThread> threads;
503 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
505 new test::WaiterThread(d,
506 MOJO_HANDLE_SIGNAL_READABLE,
507 3 * test::EpsilonTimeout().InMicroseconds(),
509 &did_wait[i], &result[i], &context[i]));
510 threads.back()->Start();
512 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
514 new test::WaiterThread(d,
515 MOJO_HANDLE_SIGNAL_WRITABLE,
516 1 * test::EpsilonTimeout().InMicroseconds(),
518 &did_wait[i], &result[i], &context[i]));
519 threads.back()->Start();
521 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
522 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
523 // All those waiting for writable should have timed out.
524 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
525 } // Joins the threads.
526 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
527 EXPECT_TRUE(did_wait[i]);
528 EXPECT_EQ(MOJO_RESULT_OK, result[i]);
529 EXPECT_EQ(i, context[i]);
531 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
532 EXPECT_TRUE(did_wait[i]);
533 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, result[i]);
537 // TODO(vtl): Stress test?
540 } // namespace system