Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / mojo / common / handle_watcher_unittest.cc
blobb734e99b7fc9564a5390c6dc418adada04da5616
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 #include "mojo/common/handle_watcher.h"
7 #include <string>
9 #include "base/at_exit.h"
10 #include "base/auto_reset.h"
11 #include "base/bind.h"
12 #include "base/memory/scoped_vector.h"
13 #include "base/run_loop.h"
14 #include "base/test/simple_test_tick_clock.h"
15 #include "base/threading/thread.h"
16 #include "mojo/common/time_helper.h"
17 #include "mojo/public/cpp/system/core.h"
18 #include "mojo/public/cpp/test_support/test_utils.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 namespace mojo {
22 namespace common {
23 namespace test {
25 void ObserveCallback(bool* was_signaled,
26 MojoResult* result_observed,
27 MojoResult result) {
28 *was_signaled = true;
29 *result_observed = result;
32 void RunUntilIdle() {
33 base::RunLoop run_loop;
34 run_loop.RunUntilIdle();
37 void DeleteWatcherAndForwardResult(
38 HandleWatcher* watcher,
39 base::Callback<void(MojoResult)> next_callback,
40 MojoResult result) {
41 delete watcher;
42 next_callback.Run(result);
45 // Helper class to manage the callback and running the message loop waiting for
46 // message to be received. Typical usage is something like:
47 // Schedule callback returned from GetCallback().
48 // RunUntilGotCallback();
49 // EXPECT_TRUE(got_callback());
50 // clear_callback();
51 class CallbackHelper {
52 public:
53 CallbackHelper()
54 : got_callback_(false),
55 run_loop_(NULL),
56 weak_factory_(this) {}
57 ~CallbackHelper() {}
59 // See description above |got_callback_|.
60 bool got_callback() const { return got_callback_; }
61 void clear_callback() { got_callback_ = false; }
63 // Runs the current MessageLoop until the callback returned from GetCallback()
64 // is notified.
65 void RunUntilGotCallback() {
66 ASSERT_TRUE(run_loop_ == NULL);
67 base::RunLoop run_loop;
68 base::AutoReset<base::RunLoop*> reseter(&run_loop_, &run_loop);
69 run_loop.Run();
72 base::Callback<void(MojoResult)> GetCallback() {
73 return base::Bind(&CallbackHelper::OnCallback, weak_factory_.GetWeakPtr());
76 void Start(HandleWatcher* watcher, const MessagePipeHandle& handle) {
77 StartWithCallback(watcher, handle, GetCallback());
80 void StartWithCallback(HandleWatcher* watcher,
81 const MessagePipeHandle& handle,
82 const base::Callback<void(MojoResult)>& callback) {
83 watcher->Start(handle, MOJO_HANDLE_SIGNAL_READABLE,
84 MOJO_DEADLINE_INDEFINITE, callback);
87 private:
88 void OnCallback(MojoResult result) {
89 got_callback_ = true;
90 if (run_loop_)
91 run_loop_->Quit();
94 // Set to true when the callback is called.
95 bool got_callback_;
97 // If non-NULL we're in RunUntilGotCallback().
98 base::RunLoop* run_loop_;
100 base::WeakPtrFactory<CallbackHelper> weak_factory_;
102 private:
103 DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
106 class HandleWatcherTest : public testing::Test {
107 public:
108 HandleWatcherTest() {}
109 virtual ~HandleWatcherTest() {
110 test::SetTickClockForTest(NULL);
113 protected:
114 void InstallTickClock() {
115 test::SetTickClockForTest(&tick_clock_);
118 base::SimpleTestTickClock tick_clock_;
120 private:
121 base::ShadowingAtExitManager at_exit_;
122 base::MessageLoop message_loop_;
124 DISALLOW_COPY_AND_ASSIGN(HandleWatcherTest);
127 // Trivial test case with a single handle to watch.
128 TEST_F(HandleWatcherTest, SingleHandler) {
129 MessagePipe test_pipe;
130 ASSERT_TRUE(test_pipe.handle0.is_valid());
131 CallbackHelper callback_helper;
132 HandleWatcher watcher;
133 callback_helper.Start(&watcher, test_pipe.handle0.get());
134 RunUntilIdle();
135 EXPECT_FALSE(callback_helper.got_callback());
136 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle1.get(),
137 std::string()));
138 callback_helper.RunUntilGotCallback();
139 EXPECT_TRUE(callback_helper.got_callback());
142 // Creates three handles and notfies them in reverse order ensuring each one is
143 // notified appropriately.
144 TEST_F(HandleWatcherTest, ThreeHandles) {
145 MessagePipe test_pipe1;
146 MessagePipe test_pipe2;
147 MessagePipe test_pipe3;
148 CallbackHelper callback_helper1;
149 CallbackHelper callback_helper2;
150 CallbackHelper callback_helper3;
151 ASSERT_TRUE(test_pipe1.handle0.is_valid());
152 ASSERT_TRUE(test_pipe2.handle0.is_valid());
153 ASSERT_TRUE(test_pipe3.handle0.is_valid());
155 HandleWatcher watcher1;
156 callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
157 RunUntilIdle();
158 EXPECT_FALSE(callback_helper1.got_callback());
159 EXPECT_FALSE(callback_helper2.got_callback());
160 EXPECT_FALSE(callback_helper3.got_callback());
162 HandleWatcher watcher2;
163 callback_helper2.Start(&watcher2, test_pipe2.handle0.get());
164 RunUntilIdle();
165 EXPECT_FALSE(callback_helper1.got_callback());
166 EXPECT_FALSE(callback_helper2.got_callback());
167 EXPECT_FALSE(callback_helper3.got_callback());
169 HandleWatcher watcher3;
170 callback_helper3.Start(&watcher3, test_pipe3.handle0.get());
171 RunUntilIdle();
172 EXPECT_FALSE(callback_helper1.got_callback());
173 EXPECT_FALSE(callback_helper2.got_callback());
174 EXPECT_FALSE(callback_helper3.got_callback());
176 // Write to 3 and make sure it's notified.
177 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe3.handle1.get(),
178 std::string()));
179 callback_helper3.RunUntilGotCallback();
180 EXPECT_FALSE(callback_helper1.got_callback());
181 EXPECT_FALSE(callback_helper2.got_callback());
182 EXPECT_TRUE(callback_helper3.got_callback());
183 callback_helper3.clear_callback();
185 // Write to 1 and 3. Only 1 should be notified since 3 was is no longer
186 // running.
187 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
188 std::string()));
189 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe3.handle1.get(),
190 std::string()));
191 callback_helper1.RunUntilGotCallback();
192 EXPECT_TRUE(callback_helper1.got_callback());
193 EXPECT_FALSE(callback_helper2.got_callback());
194 EXPECT_FALSE(callback_helper3.got_callback());
195 callback_helper1.clear_callback();
197 // Write to 1 and 2. Only 2 should be notified (since 1 was already notified).
198 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
199 std::string()));
200 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2.handle1.get(),
201 std::string()));
202 callback_helper2.RunUntilGotCallback();
203 EXPECT_FALSE(callback_helper1.got_callback());
204 EXPECT_TRUE(callback_helper2.got_callback());
205 EXPECT_FALSE(callback_helper3.got_callback());
208 // Verifies Start() invoked a second time works.
209 TEST_F(HandleWatcherTest, Restart) {
210 MessagePipe test_pipe1;
211 MessagePipe test_pipe2;
212 CallbackHelper callback_helper1;
213 CallbackHelper callback_helper2;
214 ASSERT_TRUE(test_pipe1.handle0.is_valid());
215 ASSERT_TRUE(test_pipe2.handle0.is_valid());
217 HandleWatcher watcher1;
218 callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
219 RunUntilIdle();
220 EXPECT_FALSE(callback_helper1.got_callback());
221 EXPECT_FALSE(callback_helper2.got_callback());
223 HandleWatcher watcher2;
224 callback_helper2.Start(&watcher2, test_pipe2.handle0.get());
225 RunUntilIdle();
226 EXPECT_FALSE(callback_helper1.got_callback());
227 EXPECT_FALSE(callback_helper2.got_callback());
229 // Write to 1 and make sure it's notified.
230 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
231 std::string()));
232 callback_helper1.RunUntilGotCallback();
233 EXPECT_TRUE(callback_helper1.got_callback());
234 EXPECT_FALSE(callback_helper2.got_callback());
235 callback_helper1.clear_callback();
236 EXPECT_TRUE(mojo::test::DiscardMessage(test_pipe1.handle0.get()));
238 // Write to 2 and make sure it's notified.
239 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2.handle1.get(),
240 std::string()));
241 callback_helper2.RunUntilGotCallback();
242 EXPECT_FALSE(callback_helper1.got_callback());
243 EXPECT_TRUE(callback_helper2.got_callback());
244 callback_helper2.clear_callback();
246 // Listen on 1 again.
247 callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
248 RunUntilIdle();
249 EXPECT_FALSE(callback_helper1.got_callback());
250 EXPECT_FALSE(callback_helper2.got_callback());
252 // Write to 1 and make sure it's notified.
253 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
254 std::string()));
255 callback_helper1.RunUntilGotCallback();
256 EXPECT_TRUE(callback_helper1.got_callback());
257 EXPECT_FALSE(callback_helper2.got_callback());
260 // Verifies deadline is honored.
261 TEST_F(HandleWatcherTest, Deadline) {
262 InstallTickClock();
264 MessagePipe test_pipe1;
265 MessagePipe test_pipe2;
266 MessagePipe test_pipe3;
267 CallbackHelper callback_helper1;
268 CallbackHelper callback_helper2;
269 CallbackHelper callback_helper3;
270 ASSERT_TRUE(test_pipe1.handle0.is_valid());
271 ASSERT_TRUE(test_pipe2.handle0.is_valid());
272 ASSERT_TRUE(test_pipe3.handle0.is_valid());
274 // Add a watcher with an infinite timeout.
275 HandleWatcher watcher1;
276 callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
277 RunUntilIdle();
278 EXPECT_FALSE(callback_helper1.got_callback());
279 EXPECT_FALSE(callback_helper2.got_callback());
280 EXPECT_FALSE(callback_helper3.got_callback());
282 // Add another watcher wth a timeout of 500 microseconds.
283 HandleWatcher watcher2;
284 watcher2.Start(test_pipe2.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE, 500,
285 callback_helper2.GetCallback());
286 RunUntilIdle();
287 EXPECT_FALSE(callback_helper1.got_callback());
288 EXPECT_FALSE(callback_helper2.got_callback());
289 EXPECT_FALSE(callback_helper3.got_callback());
291 // Advance the clock passed the deadline. We also have to start another
292 // watcher to wake up the background thread.
293 tick_clock_.Advance(base::TimeDelta::FromMicroseconds(501));
295 HandleWatcher watcher3;
296 callback_helper3.Start(&watcher3, test_pipe3.handle0.get());
298 callback_helper2.RunUntilGotCallback();
299 EXPECT_FALSE(callback_helper1.got_callback());
300 EXPECT_TRUE(callback_helper2.got_callback());
301 EXPECT_FALSE(callback_helper3.got_callback());
304 TEST_F(HandleWatcherTest, DeleteInCallback) {
305 MessagePipe test_pipe;
306 CallbackHelper callback_helper;
308 HandleWatcher* watcher = new HandleWatcher();
309 callback_helper.StartWithCallback(watcher, test_pipe.handle1.get(),
310 base::Bind(&DeleteWatcherAndForwardResult,
311 watcher,
312 callback_helper.GetCallback()));
313 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle0.get(),
314 std::string()));
315 callback_helper.RunUntilGotCallback();
316 EXPECT_TRUE(callback_helper.got_callback());
319 TEST(HandleWatcherCleanEnvironmentTest, AbortedOnMessageLoopDestruction) {
320 bool was_signaled = false;
321 MojoResult result = MOJO_RESULT_OK;
323 base::ShadowingAtExitManager at_exit;
324 MessagePipe pipe;
325 HandleWatcher watcher;
327 base::MessageLoop loop;
329 watcher.Start(pipe.handle0.get(),
330 MOJO_HANDLE_SIGNAL_READABLE,
331 MOJO_DEADLINE_INDEFINITE,
332 base::Bind(&ObserveCallback, &was_signaled, &result));
334 // Now, let the MessageLoop get torn down. We expect our callback to run.
337 EXPECT_TRUE(was_signaled);
338 EXPECT_EQ(MOJO_RESULT_ABORTED, result);
341 void NeverReached(MojoResult result) {
342 FAIL() << "Callback should never be invoked " << result;
345 // Called on the main thread when a thread is done. Decrements |active_count|
346 // and if |active_count| is zero quits |run_loop|.
347 void StressThreadDone(base::RunLoop* run_loop, int* active_count) {
348 (*active_count)--;
349 EXPECT_GE(*active_count, 0);
350 if (*active_count == 0)
351 run_loop->Quit();
354 // See description of StressTest. This is called on the background thread.
355 // |count| is the number of HandleWatchers to create. |active_count| is the
356 // number of outstanding threads, |task_runner| the task runner for the main
357 // thread and |run_loop| the run loop that should be quit when there are no more
358 // threads running. When done StressThreadDone() is invoked on the main thread.
359 // |active_count| and |run_loop| should only be used on the main thread.
360 void RunStressTest(int count,
361 scoped_refptr<base::TaskRunner> task_runner,
362 base::RunLoop* run_loop,
363 int* active_count) {
364 struct TestData {
365 MessagePipe pipe;
366 HandleWatcher watcher;
368 ScopedVector<TestData> data_vector;
369 for (int i = 0; i < count; ++i) {
370 if (i % 20 == 0) {
371 // Every so often we wait. This results in some level of thread balancing
372 // as well as making sure HandleWatcher has time to actually start some
373 // watches.
374 MessagePipe test_pipe;
375 ASSERT_TRUE(test_pipe.handle0.is_valid());
376 CallbackHelper callback_helper;
377 HandleWatcher watcher;
378 callback_helper.Start(&watcher, test_pipe.handle0.get());
379 RunUntilIdle();
380 EXPECT_FALSE(callback_helper.got_callback());
381 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle1.get(),
382 std::string()));
383 base::MessageLoop::ScopedNestableTaskAllower scoper(
384 base::MessageLoop::current());
385 callback_helper.RunUntilGotCallback();
386 EXPECT_TRUE(callback_helper.got_callback());
387 } else {
388 scoped_ptr<TestData> test_data(new TestData);
389 ASSERT_TRUE(test_data->pipe.handle0.is_valid());
390 test_data->watcher.Start(test_data->pipe.handle0.get(),
391 MOJO_HANDLE_SIGNAL_READABLE,
392 MOJO_DEADLINE_INDEFINITE,
393 base::Bind(&NeverReached));
394 data_vector.push_back(test_data.release());
396 if (i % 15 == 0)
397 data_vector.clear();
399 task_runner->PostTask(FROM_HERE,
400 base::Bind(&StressThreadDone, run_loop,
401 active_count));
404 // This test is meant to stress HandleWatcher. It uses from various threads
405 // repeatedly starting and stopping watches. It spins up kThreadCount
406 // threads. Each thread creates kWatchCount watches. Every so often each thread
407 // writes to a pipe and waits for the response.
408 TEST(HandleWatcherCleanEnvironmentTest, StressTest) {
409 #if defined(NDEBUG)
410 const int kThreadCount = 15;
411 const int kWatchCount = 400;
412 #else
413 const int kThreadCount = 10;
414 const int kWatchCount = 250;
415 #endif
417 base::ShadowingAtExitManager at_exit;
418 base::MessageLoop message_loop;
419 base::RunLoop run_loop;
420 ScopedVector<base::Thread> threads;
421 int threads_active_counter = kThreadCount;
422 // Starts the threads first and then post the task in hopes of having more
423 // threads running at once.
424 for (int i = 0; i < kThreadCount; ++i) {
425 scoped_ptr<base::Thread> thread(new base::Thread("test thread"));
426 thread->Start();
427 threads.push_back(thread.release());
429 for (int i = 0; i < kThreadCount; ++i) {
430 threads[i]->task_runner()->PostTask(
431 FROM_HERE, base::Bind(&RunStressTest, kWatchCount,
432 message_loop.task_runner(),
433 &run_loop, &threads_active_counter));
435 run_loop.Run();
436 ASSERT_EQ(0, threads_active_counter);
439 } // namespace test
440 } // namespace common
441 } // namespace mojo