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 : satisfied_flags_(MOJO_WAIT_FLAG_NONE
),
32 satisfiable_flags_(MOJO_WAIT_FLAG_READABLE
| MOJO_WAIT_FLAG_WRITABLE
) {}
34 void SetSatisfiedFlags(MojoWaitFlags new_satisfied_flags
) {
35 base::AutoLock
locker(lock());
37 // Any new flags that are set should be satisfiable.
38 CHECK_EQ(new_satisfied_flags
& ~satisfied_flags_
,
39 new_satisfied_flags
& ~satisfied_flags_
& satisfiable_flags_
);
41 if (new_satisfied_flags
== satisfied_flags_
)
44 satisfied_flags_
= new_satisfied_flags
;
48 void SetSatisfiableFlags(MojoWaitFlags new_satisfiable_flags
) {
49 base::AutoLock
locker(lock());
51 if (new_satisfiable_flags
== satisfiable_flags_
)
54 satisfiable_flags_
= new_satisfiable_flags
;
58 virtual Type
GetType() const OVERRIDE
{
63 friend class base::RefCountedThreadSafe
<MockSimpleDispatcher
>;
64 virtual ~MockSimpleDispatcher() {}
66 virtual scoped_refptr
<Dispatcher
>
67 CreateEquivalentDispatcherAndCloseImplNoLock() OVERRIDE
{
68 scoped_refptr
<MockSimpleDispatcher
> rv(new MockSimpleDispatcher());
69 rv
->satisfied_flags_
= satisfied_flags_
;
70 rv
->satisfiable_flags_
= satisfiable_flags_
;
71 return scoped_refptr
<Dispatcher
>(rv
.get());
74 // |SimpleDispatcher| implementation:
75 virtual MojoWaitFlags
SatisfiedFlagsNoLock() const OVERRIDE
{
76 lock().AssertAcquired();
77 return satisfied_flags_
;
80 virtual MojoWaitFlags
SatisfiableFlagsNoLock() const OVERRIDE
{
81 lock().AssertAcquired();
82 return satisfiable_flags_
;
85 // Protected by |lock()|:
86 MojoWaitFlags satisfied_flags_
;
87 MojoWaitFlags satisfiable_flags_
;
89 DISALLOW_COPY_AND_ASSIGN(MockSimpleDispatcher
);
92 TEST(SimpleDispatcherTest
, Basic
) {
93 test::Stopwatch stopwatch
;
95 scoped_refptr
<MockSimpleDispatcher
> d(new MockSimpleDispatcher());
98 // Try adding a readable waiter when already readable.
100 d
->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE
);
101 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS
,
102 d
->AddWaiter(&w
, MOJO_WAIT_FLAG_READABLE
, 0));
103 // Shouldn't need to remove the waiter (it was not added).
105 // Wait (forever) for writable when already writable.
107 d
->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE
);
108 EXPECT_EQ(MOJO_RESULT_OK
, d
->AddWaiter(&w
, MOJO_WAIT_FLAG_WRITABLE
, 1));
109 d
->SetSatisfiedFlags(MOJO_WAIT_FLAG_WRITABLE
);
111 EXPECT_EQ(1, w
.Wait(MOJO_DEADLINE_INDEFINITE
));
112 EXPECT_LT(stopwatch
.Elapsed(), test::EpsilonTimeout());
115 // Wait for zero time for writable when already writable.
117 d
->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE
);
118 EXPECT_EQ(MOJO_RESULT_OK
, d
->AddWaiter(&w
, MOJO_WAIT_FLAG_WRITABLE
, 2));
119 d
->SetSatisfiedFlags(MOJO_WAIT_FLAG_WRITABLE
);
121 EXPECT_EQ(2, w
.Wait(0));
122 EXPECT_LT(stopwatch
.Elapsed(), test::EpsilonTimeout());
125 // Wait for non-zero, finite time for writable when already writable.
127 d
->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE
);
128 EXPECT_EQ(MOJO_RESULT_OK
, d
->AddWaiter(&w
, MOJO_WAIT_FLAG_WRITABLE
, 3));
129 d
->SetSatisfiedFlags(MOJO_WAIT_FLAG_WRITABLE
);
131 EXPECT_EQ(3, w
.Wait(2 * test::EpsilonTimeout().InMicroseconds()));
132 EXPECT_LT(stopwatch
.Elapsed(), test::EpsilonTimeout());
135 // Wait for zero time for writable when not writable (will time out).
137 d
->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE
);
138 EXPECT_EQ(MOJO_RESULT_OK
, d
->AddWaiter(&w
, MOJO_WAIT_FLAG_WRITABLE
, 4));
140 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED
, w
.Wait(0));
141 EXPECT_LT(stopwatch
.Elapsed(), test::EpsilonTimeout());
144 // Wait for non-zero, finite time for writable when not writable (will time
147 d
->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE
);
148 EXPECT_EQ(MOJO_RESULT_OK
, d
->AddWaiter(&w
, MOJO_WAIT_FLAG_WRITABLE
, 4));
150 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED
,
151 w
.Wait(2 * test::EpsilonTimeout().InMicroseconds()));
152 base::TimeDelta elapsed
= stopwatch
.Elapsed();
153 EXPECT_GT(elapsed
, (2-1) * test::EpsilonTimeout());
154 EXPECT_LT(elapsed
, (2+1) * test::EpsilonTimeout());
157 EXPECT_EQ(MOJO_RESULT_OK
, d
->Close());
160 TEST(SimpleDispatcherTest
, BasicUnsatisfiable
) {
161 test::Stopwatch stopwatch
;
163 scoped_refptr
<MockSimpleDispatcher
> d(new MockSimpleDispatcher());
166 // Try adding a writable waiter when it can never be writable.
168 d
->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE
);
169 d
->SetSatisfiedFlags(0);
170 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION
,
171 d
->AddWaiter(&w
, MOJO_WAIT_FLAG_WRITABLE
, 5));
172 // Shouldn't need to remove the waiter (it was not added).
174 // Wait (forever) for writable and then it becomes never writable.
176 d
->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE
| MOJO_WAIT_FLAG_WRITABLE
);
177 EXPECT_EQ(MOJO_RESULT_OK
, d
->AddWaiter(&w
, MOJO_WAIT_FLAG_WRITABLE
, 6));
178 d
->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE
);
180 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION
, w
.Wait(MOJO_DEADLINE_INDEFINITE
));
181 EXPECT_LT(stopwatch
.Elapsed(), test::EpsilonTimeout());
184 // Wait for zero time for writable and then it becomes never writable.
186 d
->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE
| MOJO_WAIT_FLAG_WRITABLE
);
187 EXPECT_EQ(MOJO_RESULT_OK
, d
->AddWaiter(&w
, MOJO_WAIT_FLAG_WRITABLE
, 6));
188 d
->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE
);
190 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION
, w
.Wait(0));
191 EXPECT_LT(stopwatch
.Elapsed(), test::EpsilonTimeout());
194 // Wait for non-zero, finite time for writable and then it becomes never
197 d
->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE
| MOJO_WAIT_FLAG_WRITABLE
);
198 EXPECT_EQ(MOJO_RESULT_OK
, d
->AddWaiter(&w
, MOJO_WAIT_FLAG_WRITABLE
, 7));
199 d
->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE
);
201 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION
,
202 w
.Wait(2 * test::EpsilonTimeout().InMicroseconds()));
203 EXPECT_LT(stopwatch
.Elapsed(), test::EpsilonTimeout());
206 EXPECT_EQ(MOJO_RESULT_OK
, d
->Close());
209 TEST(SimpleDispatcherTest
, BasicClosed
) {
210 test::Stopwatch stopwatch
;
212 scoped_refptr
<MockSimpleDispatcher
> d
;
215 // Try adding a writable waiter when the dispatcher has been closed.
216 d
= new MockSimpleDispatcher();
218 EXPECT_EQ(MOJO_RESULT_OK
, d
->Close());
219 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT
,
220 d
->AddWaiter(&w
, MOJO_WAIT_FLAG_WRITABLE
, 8));
221 // Shouldn't need to remove the waiter (it was not added).
223 // Wait (forever) for writable and then the dispatcher is closed.
224 d
= new MockSimpleDispatcher();
226 EXPECT_EQ(MOJO_RESULT_OK
, d
->AddWaiter(&w
, MOJO_WAIT_FLAG_WRITABLE
, 9));
227 EXPECT_EQ(MOJO_RESULT_OK
, d
->Close());
229 EXPECT_EQ(MOJO_RESULT_CANCELLED
, w
.Wait(MOJO_DEADLINE_INDEFINITE
));
230 EXPECT_LT(stopwatch
.Elapsed(), test::EpsilonTimeout());
231 // Don't need to remove waiters from closed dispatchers.
233 // Wait for zero time for writable and then the dispatcher is closed.
234 d
= new MockSimpleDispatcher();
236 EXPECT_EQ(MOJO_RESULT_OK
, d
->AddWaiter(&w
, MOJO_WAIT_FLAG_WRITABLE
, 10));
237 EXPECT_EQ(MOJO_RESULT_OK
, d
->Close());
239 EXPECT_EQ(MOJO_RESULT_CANCELLED
, w
.Wait(0));
240 EXPECT_LT(stopwatch
.Elapsed(), test::EpsilonTimeout());
241 // Don't need to remove waiters from closed dispatchers.
243 // Wait for non-zero, finite time for writable and then the dispatcher is
245 d
= new MockSimpleDispatcher();
247 EXPECT_EQ(MOJO_RESULT_OK
, d
->AddWaiter(&w
, MOJO_WAIT_FLAG_WRITABLE
, 11));
248 EXPECT_EQ(MOJO_RESULT_OK
, d
->Close());
250 EXPECT_EQ(MOJO_RESULT_CANCELLED
,
251 w
.Wait(2 * test::EpsilonTimeout().InMicroseconds()));
252 EXPECT_LT(stopwatch
.Elapsed(), test::EpsilonTimeout());
253 // Don't need to remove waiters from closed dispatchers.
256 TEST(SimpleDispatcherTest
, BasicThreaded
) {
257 test::Stopwatch stopwatch
;
261 // Wait for readable (already readable).
263 scoped_refptr
<MockSimpleDispatcher
> d(new MockSimpleDispatcher());
265 d
->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE
);
266 test::WaiterThread
thread(d
,
267 MOJO_WAIT_FLAG_READABLE
,
268 MOJO_DEADLINE_INDEFINITE
,
273 } // Joins the thread.
274 // If we closed earlier, then probably we'd get a |MOJO_RESULT_CANCELLED|.
275 EXPECT_EQ(MOJO_RESULT_OK
, d
->Close());
277 EXPECT_LT(stopwatch
.Elapsed(), test::EpsilonTimeout());
278 EXPECT_FALSE(did_wait
);
279 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS
, result
);
281 // Wait for readable and becomes readable after some time.
283 scoped_refptr
<MockSimpleDispatcher
> d(new MockSimpleDispatcher());
284 test::WaiterThread
thread(d
,
285 MOJO_WAIT_FLAG_READABLE
,
286 MOJO_DEADLINE_INDEFINITE
,
291 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
292 d
->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE
);
293 EXPECT_EQ(MOJO_RESULT_OK
, d
->Close());
294 } // Joins the thread.
295 base::TimeDelta elapsed
= stopwatch
.Elapsed();
296 EXPECT_GT(elapsed
, (2-1) * test::EpsilonTimeout());
297 EXPECT_LT(elapsed
, (2+1) * test::EpsilonTimeout());
298 EXPECT_TRUE(did_wait
);
299 EXPECT_EQ(1, result
);
301 // Wait for readable and becomes never-readable after some time.
303 scoped_refptr
<MockSimpleDispatcher
> d(new MockSimpleDispatcher());
304 test::WaiterThread
thread(d
,
305 MOJO_WAIT_FLAG_READABLE
,
306 MOJO_DEADLINE_INDEFINITE
,
311 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
312 d
->SetSatisfiableFlags(MOJO_WAIT_FLAG_NONE
);
313 EXPECT_EQ(MOJO_RESULT_OK
, d
->Close());
314 } // Joins the thread.
315 elapsed
= stopwatch
.Elapsed();
316 EXPECT_GT(elapsed
, (2-1) * test::EpsilonTimeout());
317 EXPECT_LT(elapsed
, (2+1) * test::EpsilonTimeout());
318 EXPECT_TRUE(did_wait
);
319 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION
, result
);
321 // Wait for readable and dispatcher gets closed.
323 scoped_refptr
<MockSimpleDispatcher
> d(new MockSimpleDispatcher());
324 test::WaiterThread
thread(d
,
325 MOJO_WAIT_FLAG_READABLE
,
326 MOJO_DEADLINE_INDEFINITE
,
331 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
332 EXPECT_EQ(MOJO_RESULT_OK
, d
->Close());
333 } // Joins the thread.
334 elapsed
= stopwatch
.Elapsed();
335 EXPECT_GT(elapsed
, (2-1) * test::EpsilonTimeout());
336 EXPECT_LT(elapsed
, (2+1) * test::EpsilonTimeout());
337 EXPECT_TRUE(did_wait
);
338 EXPECT_EQ(MOJO_RESULT_CANCELLED
, result
);
340 // Wait for readable and times out.
342 scoped_refptr
<MockSimpleDispatcher
> d(new MockSimpleDispatcher());
344 test::WaiterThread
thread(d
,
345 MOJO_WAIT_FLAG_READABLE
,
346 2 * test::EpsilonTimeout().InMicroseconds(),
351 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
352 // Not what we're waiting for.
353 d
->SetSatisfiedFlags(MOJO_WAIT_FLAG_WRITABLE
);
354 } // Joins the thread (after its wait times out).
355 // If we closed earlier, then probably we'd get a |MOJO_RESULT_CANCELLED|.
356 EXPECT_EQ(MOJO_RESULT_OK
, d
->Close());
358 elapsed
= stopwatch
.Elapsed();
359 EXPECT_GT(elapsed
, (2-1) * test::EpsilonTimeout());
360 EXPECT_LT(elapsed
, (2+1) * test::EpsilonTimeout());
361 EXPECT_TRUE(did_wait
);
362 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED
, result
);
365 TEST(SimpleDispatcherTest
, MultipleWaiters
) {
366 static const size_t kNumWaiters
= 20;
368 bool did_wait
[kNumWaiters
];
369 MojoResult result
[kNumWaiters
];
371 // All wait for readable and becomes readable after some time.
373 scoped_refptr
<MockSimpleDispatcher
> d(new MockSimpleDispatcher());
374 ScopedVector
<test::WaiterThread
> threads
;
375 for (size_t i
= 0; i
< kNumWaiters
; i
++) {
376 threads
.push_back(new test::WaiterThread(d
,
377 MOJO_WAIT_FLAG_READABLE
,
378 MOJO_DEADLINE_INDEFINITE
,
379 static_cast<MojoResult
>(i
),
380 &did_wait
[i
], &result
[i
]));
381 threads
.back()->Start();
383 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
384 d
->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE
);
385 EXPECT_EQ(MOJO_RESULT_OK
, d
->Close());
386 } // Joins the threads.
387 for (size_t i
= 0; i
< kNumWaiters
; i
++) {
388 EXPECT_TRUE(did_wait
[i
]);
389 EXPECT_EQ(static_cast<MojoResult
>(i
), result
[i
]);
392 // Some wait for readable, some for writable, and becomes readable after some
395 scoped_refptr
<MockSimpleDispatcher
> d(new MockSimpleDispatcher());
396 ScopedVector
<test::WaiterThread
> threads
;
397 for (size_t i
= 0; i
< kNumWaiters
/ 2; i
++) {
398 threads
.push_back(new test::WaiterThread(d
,
399 MOJO_WAIT_FLAG_READABLE
,
400 MOJO_DEADLINE_INDEFINITE
,
401 static_cast<MojoResult
>(i
),
402 &did_wait
[i
], &result
[i
]));
403 threads
.back()->Start();
405 for (size_t i
= kNumWaiters
/ 2; i
< kNumWaiters
; i
++) {
406 threads
.push_back(new test::WaiterThread(d
,
407 MOJO_WAIT_FLAG_WRITABLE
,
408 MOJO_DEADLINE_INDEFINITE
,
409 static_cast<MojoResult
>(i
),
410 &did_wait
[i
], &result
[i
]));
411 threads
.back()->Start();
413 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
414 d
->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE
);
415 // This will wake up the ones waiting to write.
416 EXPECT_EQ(MOJO_RESULT_OK
, d
->Close());
417 } // Joins the threads.
418 for (size_t i
= 0; i
< kNumWaiters
/ 2; i
++) {
419 EXPECT_TRUE(did_wait
[i
]);
420 EXPECT_EQ(static_cast<MojoResult
>(i
), result
[i
]);
422 for (size_t i
= kNumWaiters
/ 2; i
< kNumWaiters
; i
++) {
423 EXPECT_TRUE(did_wait
[i
]);
424 EXPECT_EQ(MOJO_RESULT_CANCELLED
, result
[i
]);
427 // Some wait for readable, some for writable, and becomes readable and
428 // never-writable after some time.
430 scoped_refptr
<MockSimpleDispatcher
> d(new MockSimpleDispatcher());
431 ScopedVector
<test::WaiterThread
> threads
;
432 for (size_t i
= 0; i
< kNumWaiters
/ 2; i
++) {
433 threads
.push_back(new test::WaiterThread(d
,
434 MOJO_WAIT_FLAG_READABLE
,
435 MOJO_DEADLINE_INDEFINITE
,
436 static_cast<MojoResult
>(i
),
437 &did_wait
[i
], &result
[i
]));
438 threads
.back()->Start();
440 for (size_t i
= kNumWaiters
/ 2; i
< kNumWaiters
; i
++) {
441 threads
.push_back(new test::WaiterThread(d
,
442 MOJO_WAIT_FLAG_WRITABLE
,
443 MOJO_DEADLINE_INDEFINITE
,
444 static_cast<MojoResult
>(i
),
445 &did_wait
[i
], &result
[i
]));
446 threads
.back()->Start();
448 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
449 d
->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE
);
450 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
451 d
->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE
);
452 EXPECT_EQ(MOJO_RESULT_OK
, d
->Close());
453 } // Joins the threads.
454 for (size_t i
= 0; i
< kNumWaiters
/ 2; i
++) {
455 EXPECT_TRUE(did_wait
[i
]);
456 EXPECT_EQ(static_cast<MojoResult
>(i
), result
[i
]);
458 for (size_t i
= kNumWaiters
/ 2; i
< kNumWaiters
; i
++) {
459 EXPECT_TRUE(did_wait
[i
]);
460 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION
, result
[i
]);
463 // Some wait for readable, some for writable, and becomes readable after some
466 scoped_refptr
<MockSimpleDispatcher
> d(new MockSimpleDispatcher());
467 ScopedVector
<test::WaiterThread
> threads
;
468 for (size_t i
= 0; i
< kNumWaiters
/ 2; i
++) {
470 new test::WaiterThread(d
,
471 MOJO_WAIT_FLAG_READABLE
,
472 3 * test::EpsilonTimeout().InMicroseconds(),
473 static_cast<MojoResult
>(i
),
474 &did_wait
[i
], &result
[i
]));
475 threads
.back()->Start();
477 for (size_t i
= kNumWaiters
/ 2; i
< kNumWaiters
; i
++) {
479 new test::WaiterThread(d
,
480 MOJO_WAIT_FLAG_WRITABLE
,
481 1 * test::EpsilonTimeout().InMicroseconds(),
482 static_cast<MojoResult
>(i
),
483 &did_wait
[i
], &result
[i
]));
484 threads
.back()->Start();
486 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
487 d
->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE
);
488 // All those waiting for writable should have timed out.
489 EXPECT_EQ(MOJO_RESULT_OK
, d
->Close());
490 } // Joins the threads.
491 for (size_t i
= 0; i
< kNumWaiters
/ 2; i
++) {
492 EXPECT_TRUE(did_wait
[i
]);
493 EXPECT_EQ(static_cast<MojoResult
>(i
), result
[i
]);
495 for (size_t i
= kNumWaiters
/ 2; i
< kNumWaiters
; i
++) {
496 EXPECT_TRUE(did_wait
[i
]);
497 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED
, result
[i
]);
501 // TODO(vtl): Stress test?
504 } // namespace system