Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / mojo / common / handle_watcher_unittest.cc
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.
4
5 #include "mojo/common/handle_watcher.h"
6
7 #include <string>
8
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/message_pump_mojo.h"
17 #include "mojo/common/time_helper.h"
18 #include "mojo/public/cpp/system/core.h"
19 #include "mojo/public/cpp/test_support/test_utils.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace mojo {
23 namespace common {
24 namespace test {
25
26 enum MessageLoopConfig {
27   MESSAGE_LOOP_CONFIG_DEFAULT = 0,
28   MESSAGE_LOOP_CONFIG_MOJO = 1
29 };
30
31 void ObserveCallback(bool* was_signaled,
32                      MojoResult* result_observed,
33                      MojoResult result) {
34   *was_signaled = true;
35   *result_observed = result;
36 }
37
38 void RunUntilIdle() {
39   base::RunLoop run_loop;
40   run_loop.RunUntilIdle();
41 }
42
43 void DeleteWatcherAndForwardResult(
44     HandleWatcher* watcher,
45     base::Callback<void(MojoResult)> next_callback,
46     MojoResult result) {
47   delete watcher;
48   next_callback.Run(result);
49 }
50
51 scoped_ptr<base::MessageLoop> CreateMessageLoop(MessageLoopConfig config) {
52   scoped_ptr<base::MessageLoop> loop;
53   if (config == MESSAGE_LOOP_CONFIG_DEFAULT)
54     loop.reset(new base::MessageLoop());
55   else
56     loop.reset(new base::MessageLoop(MessagePumpMojo::Create()));
57   return loop.Pass();
58 }
59
60 // Helper class to manage the callback and running the message loop waiting for
61 // message to be received. Typical usage is something like:
62 //   Schedule callback returned from GetCallback().
63 //   RunUntilGotCallback();
64 //   EXPECT_TRUE(got_callback());
65 //   clear_callback();
66 class CallbackHelper {
67  public:
68   CallbackHelper()
69       : got_callback_(false),
70         run_loop_(NULL),
71         weak_factory_(this) {}
72   ~CallbackHelper() {}
73
74   // See description above |got_callback_|.
75   bool got_callback() const { return got_callback_; }
76   void clear_callback() { got_callback_ = false; }
77
78   // Runs the current MessageLoop until the callback returned from GetCallback()
79   // is notified.
80   void RunUntilGotCallback() {
81     ASSERT_TRUE(run_loop_ == NULL);
82     base::RunLoop run_loop;
83     base::AutoReset<base::RunLoop*> reseter(&run_loop_, &run_loop);
84     run_loop.Run();
85   }
86
87   base::Callback<void(MojoResult)> GetCallback() {
88     return base::Bind(&CallbackHelper::OnCallback, weak_factory_.GetWeakPtr());
89   }
90
91   void Start(HandleWatcher* watcher, const MessagePipeHandle& handle) {
92     StartWithCallback(watcher, handle, GetCallback());
93   }
94
95   void StartWithCallback(HandleWatcher* watcher,
96                          const MessagePipeHandle& handle,
97                          const base::Callback<void(MojoResult)>& callback) {
98     watcher->Start(handle, MOJO_HANDLE_SIGNAL_READABLE,
99                    MOJO_DEADLINE_INDEFINITE, callback);
100   }
101
102  private:
103   void OnCallback(MojoResult result) {
104     got_callback_ = true;
105     if (run_loop_)
106       run_loop_->Quit();
107   }
108
109   // Set to true when the callback is called.
110   bool got_callback_;
111
112   // If non-NULL we're in RunUntilGotCallback().
113   base::RunLoop* run_loop_;
114
115   base::WeakPtrFactory<CallbackHelper> weak_factory_;
116
117  private:
118   DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
119 };
120
121 class HandleWatcherTest : public testing::TestWithParam<MessageLoopConfig> {
122  public:
123   HandleWatcherTest() : message_loop_(CreateMessageLoop(GetParam())) {}
124   virtual ~HandleWatcherTest() {
125     test::SetTickClockForTest(NULL);
126   }
127
128  protected:
129   void TearDownMessageLoop() {
130     message_loop_.reset();
131   }
132
133   void InstallTickClock() {
134     test::SetTickClockForTest(&tick_clock_);
135   }
136
137   base::SimpleTestTickClock tick_clock_;
138
139  private:
140   base::ShadowingAtExitManager at_exit_;
141   scoped_ptr<base::MessageLoop> message_loop_;
142
143   DISALLOW_COPY_AND_ASSIGN(HandleWatcherTest);
144 };
145
146 INSTANTIATE_TEST_CASE_P(
147     MultipleMessageLoopConfigs, HandleWatcherTest,
148     testing::Values(MESSAGE_LOOP_CONFIG_DEFAULT, MESSAGE_LOOP_CONFIG_MOJO));
149
150 // Trivial test case with a single handle to watch.
151 TEST_P(HandleWatcherTest, SingleHandler) {
152   MessagePipe test_pipe;
153   ASSERT_TRUE(test_pipe.handle0.is_valid());
154   CallbackHelper callback_helper;
155   HandleWatcher watcher;
156   callback_helper.Start(&watcher, test_pipe.handle0.get());
157   RunUntilIdle();
158   EXPECT_FALSE(callback_helper.got_callback());
159   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle1.get(),
160                                            std::string()));
161   callback_helper.RunUntilGotCallback();
162   EXPECT_TRUE(callback_helper.got_callback());
163 }
164
165 // Creates three handles and notfies them in reverse order ensuring each one is
166 // notified appropriately.
167 TEST_P(HandleWatcherTest, ThreeHandles) {
168   MessagePipe test_pipe1;
169   MessagePipe test_pipe2;
170   MessagePipe test_pipe3;
171   CallbackHelper callback_helper1;
172   CallbackHelper callback_helper2;
173   CallbackHelper callback_helper3;
174   ASSERT_TRUE(test_pipe1.handle0.is_valid());
175   ASSERT_TRUE(test_pipe2.handle0.is_valid());
176   ASSERT_TRUE(test_pipe3.handle0.is_valid());
177
178   HandleWatcher watcher1;
179   callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
180   RunUntilIdle();
181   EXPECT_FALSE(callback_helper1.got_callback());
182   EXPECT_FALSE(callback_helper2.got_callback());
183   EXPECT_FALSE(callback_helper3.got_callback());
184
185   HandleWatcher watcher2;
186   callback_helper2.Start(&watcher2, test_pipe2.handle0.get());
187   RunUntilIdle();
188   EXPECT_FALSE(callback_helper1.got_callback());
189   EXPECT_FALSE(callback_helper2.got_callback());
190   EXPECT_FALSE(callback_helper3.got_callback());
191
192   HandleWatcher watcher3;
193   callback_helper3.Start(&watcher3, test_pipe3.handle0.get());
194   RunUntilIdle();
195   EXPECT_FALSE(callback_helper1.got_callback());
196   EXPECT_FALSE(callback_helper2.got_callback());
197   EXPECT_FALSE(callback_helper3.got_callback());
198
199   // Write to 3 and make sure it's notified.
200   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe3.handle1.get(),
201                                            std::string()));
202   callback_helper3.RunUntilGotCallback();
203   EXPECT_FALSE(callback_helper1.got_callback());
204   EXPECT_FALSE(callback_helper2.got_callback());
205   EXPECT_TRUE(callback_helper3.got_callback());
206   callback_helper3.clear_callback();
207
208   // Write to 1 and 3. Only 1 should be notified since 3 was is no longer
209   // running.
210   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
211                                            std::string()));
212   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe3.handle1.get(),
213                                            std::string()));
214   callback_helper1.RunUntilGotCallback();
215   EXPECT_TRUE(callback_helper1.got_callback());
216   EXPECT_FALSE(callback_helper2.got_callback());
217   EXPECT_FALSE(callback_helper3.got_callback());
218   callback_helper1.clear_callback();
219
220   // Write to 1 and 2. Only 2 should be notified (since 1 was already notified).
221   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
222                                            std::string()));
223   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2.handle1.get(),
224                                            std::string()));
225   callback_helper2.RunUntilGotCallback();
226   EXPECT_FALSE(callback_helper1.got_callback());
227   EXPECT_TRUE(callback_helper2.got_callback());
228   EXPECT_FALSE(callback_helper3.got_callback());
229 }
230
231 // Verifies Start() invoked a second time works.
232 TEST_P(HandleWatcherTest, Restart) {
233   MessagePipe test_pipe1;
234   MessagePipe test_pipe2;
235   CallbackHelper callback_helper1;
236   CallbackHelper callback_helper2;
237   ASSERT_TRUE(test_pipe1.handle0.is_valid());
238   ASSERT_TRUE(test_pipe2.handle0.is_valid());
239
240   HandleWatcher watcher1;
241   callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
242   RunUntilIdle();
243   EXPECT_FALSE(callback_helper1.got_callback());
244   EXPECT_FALSE(callback_helper2.got_callback());
245
246   HandleWatcher watcher2;
247   callback_helper2.Start(&watcher2, test_pipe2.handle0.get());
248   RunUntilIdle();
249   EXPECT_FALSE(callback_helper1.got_callback());
250   EXPECT_FALSE(callback_helper2.got_callback());
251
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());
258   callback_helper1.clear_callback();
259   EXPECT_TRUE(mojo::test::DiscardMessage(test_pipe1.handle0.get()));
260
261   // Write to 2 and make sure it's notified.
262   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2.handle1.get(),
263                                            std::string()));
264   callback_helper2.RunUntilGotCallback();
265   EXPECT_FALSE(callback_helper1.got_callback());
266   EXPECT_TRUE(callback_helper2.got_callback());
267   callback_helper2.clear_callback();
268
269   // Listen on 1 again.
270   callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
271   RunUntilIdle();
272   EXPECT_FALSE(callback_helper1.got_callback());
273   EXPECT_FALSE(callback_helper2.got_callback());
274
275   // Write to 1 and make sure it's notified.
276   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
277                                            std::string()));
278   callback_helper1.RunUntilGotCallback();
279   EXPECT_TRUE(callback_helper1.got_callback());
280   EXPECT_FALSE(callback_helper2.got_callback());
281 }
282
283 // Verifies deadline is honored.
284 TEST_P(HandleWatcherTest, Deadline) {
285   InstallTickClock();
286
287   MessagePipe test_pipe1;
288   MessagePipe test_pipe2;
289   MessagePipe test_pipe3;
290   CallbackHelper callback_helper1;
291   CallbackHelper callback_helper2;
292   CallbackHelper callback_helper3;
293   ASSERT_TRUE(test_pipe1.handle0.is_valid());
294   ASSERT_TRUE(test_pipe2.handle0.is_valid());
295   ASSERT_TRUE(test_pipe3.handle0.is_valid());
296
297   // Add a watcher with an infinite timeout.
298   HandleWatcher watcher1;
299   callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
300   RunUntilIdle();
301   EXPECT_FALSE(callback_helper1.got_callback());
302   EXPECT_FALSE(callback_helper2.got_callback());
303   EXPECT_FALSE(callback_helper3.got_callback());
304
305   // Add another watcher wth a timeout of 500 microseconds.
306   HandleWatcher watcher2;
307   watcher2.Start(test_pipe2.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE, 500,
308                  callback_helper2.GetCallback());
309   RunUntilIdle();
310   EXPECT_FALSE(callback_helper1.got_callback());
311   EXPECT_FALSE(callback_helper2.got_callback());
312   EXPECT_FALSE(callback_helper3.got_callback());
313
314   // Advance the clock passed the deadline. We also have to start another
315   // watcher to wake up the background thread.
316   tick_clock_.Advance(base::TimeDelta::FromMicroseconds(501));
317
318   HandleWatcher watcher3;
319   callback_helper3.Start(&watcher3, test_pipe3.handle0.get());
320
321   callback_helper2.RunUntilGotCallback();
322   EXPECT_FALSE(callback_helper1.got_callback());
323   EXPECT_TRUE(callback_helper2.got_callback());
324   EXPECT_FALSE(callback_helper3.got_callback());
325 }
326
327 TEST_P(HandleWatcherTest, DeleteInCallback) {
328   MessagePipe test_pipe;
329   CallbackHelper callback_helper;
330
331   HandleWatcher* watcher = new HandleWatcher();
332   callback_helper.StartWithCallback(watcher, test_pipe.handle1.get(),
333                                     base::Bind(&DeleteWatcherAndForwardResult,
334                                                watcher,
335                                                callback_helper.GetCallback()));
336   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle0.get(),
337                                            std::string()));
338   callback_helper.RunUntilGotCallback();
339   EXPECT_TRUE(callback_helper.got_callback());
340 }
341
342 TEST_P(HandleWatcherTest, AbortedOnMessageLoopDestruction) {
343   bool was_signaled = false;
344   MojoResult result = MOJO_RESULT_OK;
345
346   MessagePipe pipe;
347   HandleWatcher watcher;
348   watcher.Start(pipe.handle0.get(),
349                 MOJO_HANDLE_SIGNAL_READABLE,
350                 MOJO_DEADLINE_INDEFINITE,
351                 base::Bind(&ObserveCallback, &was_signaled, &result));
352
353   // Now, let the MessageLoop get torn down. We expect our callback to run.
354   TearDownMessageLoop();
355
356   EXPECT_TRUE(was_signaled);
357   EXPECT_EQ(MOJO_RESULT_ABORTED, result);
358 }
359
360 void NeverReached(MojoResult result) {
361   FAIL() << "Callback should never be invoked " << result;
362 }
363
364 // Called on the main thread when a thread is done. Decrements |active_count|
365 // and if |active_count| is zero quits |run_loop|.
366 void StressThreadDone(base::RunLoop* run_loop, int* active_count) {
367   (*active_count)--;
368   EXPECT_GE(*active_count, 0);
369   if (*active_count == 0)
370     run_loop->Quit();
371 }
372
373 // See description of StressTest. This is called on the background thread.
374 // |count| is the number of HandleWatchers to create. |active_count| is the
375 // number of outstanding threads, |task_runner| the task runner for the main
376 // thread and |run_loop| the run loop that should be quit when there are no more
377 // threads running. When done StressThreadDone() is invoked on the main thread.
378 // |active_count| and |run_loop| should only be used on the main thread.
379 void RunStressTest(int count,
380                    scoped_refptr<base::TaskRunner> task_runner,
381                    base::RunLoop* run_loop,
382                    int* active_count) {
383   struct TestData {
384     MessagePipe pipe;
385     HandleWatcher watcher;
386   };
387   ScopedVector<TestData> data_vector;
388   for (int i = 0; i < count; ++i) {
389     if (i % 20 == 0) {
390       // Every so often we wait. This results in some level of thread balancing
391       // as well as making sure HandleWatcher has time to actually start some
392       // watches.
393       MessagePipe test_pipe;
394       ASSERT_TRUE(test_pipe.handle0.is_valid());
395       CallbackHelper callback_helper;
396       HandleWatcher watcher;
397       callback_helper.Start(&watcher, test_pipe.handle0.get());
398       RunUntilIdle();
399       EXPECT_FALSE(callback_helper.got_callback());
400       EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle1.get(),
401                                                std::string()));
402       base::MessageLoop::ScopedNestableTaskAllower scoper(
403           base::MessageLoop::current());
404       callback_helper.RunUntilGotCallback();
405       EXPECT_TRUE(callback_helper.got_callback());
406     } else {
407       scoped_ptr<TestData> test_data(new TestData);
408       ASSERT_TRUE(test_data->pipe.handle0.is_valid());
409       test_data->watcher.Start(test_data->pipe.handle0.get(),
410                     MOJO_HANDLE_SIGNAL_READABLE,
411                     MOJO_DEADLINE_INDEFINITE,
412                     base::Bind(&NeverReached));
413       data_vector.push_back(test_data.release());
414     }
415     if (i % 15 == 0)
416       data_vector.clear();
417   }
418   task_runner->PostTask(FROM_HERE,
419                         base::Bind(&StressThreadDone, run_loop,
420                                    active_count));
421 }
422
423 // This test is meant to stress HandleWatcher. It uses from various threads
424 // repeatedly starting and stopping watches. It spins up kThreadCount
425 // threads. Each thread creates kWatchCount watches. Every so often each thread
426 // writes to a pipe and waits for the response.
427 TEST(HandleWatcherCleanEnvironmentTest, StressTest) {
428 #if defined(NDEBUG)
429   const int kThreadCount = 15;
430   const int kWatchCount = 400;
431 #else
432   const int kThreadCount = 10;
433   const int kWatchCount = 250;
434 #endif
435
436   base::ShadowingAtExitManager at_exit;
437   base::MessageLoop message_loop;
438   base::RunLoop run_loop;
439   ScopedVector<base::Thread> threads;
440   int threads_active_counter = kThreadCount;
441   // Starts the threads first and then post the task in hopes of having more
442   // threads running at once.
443   for (int i = 0; i < kThreadCount; ++i) {
444     scoped_ptr<base::Thread> thread(new base::Thread("test thread"));
445     if (i % 2) {
446       base::Thread::Options thread_options;
447       thread_options.message_pump_factory =
448           base::Bind(&MessagePumpMojo::Create);
449       thread->StartWithOptions(thread_options);
450     } else {
451       thread->Start();
452     }
453     threads.push_back(thread.release());
454   }
455   for (int i = 0; i < kThreadCount; ++i) {
456     threads[i]->task_runner()->PostTask(
457         FROM_HERE, base::Bind(&RunStressTest, kWatchCount,
458                               message_loop.task_runner(),
459                               &run_loop, &threads_active_counter));
460   }
461   run_loop.Run();
462   ASSERT_EQ(0, threads_active_counter);
463 }
464
465 }  // namespace test
466 }  // namespace common
467 }  // namespace mojo