Upstream version 5.34.104.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/auto_reset.h"
10 #include "base/bind.h"
11 #include "base/run_loop.h"
12 #include "base/test/simple_test_tick_clock.h"
13 #include "mojo/public/system/core_cpp.h"
14 #include "mojo/public/tests/test_utils.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace mojo {
18 namespace common {
19 namespace test {
20
21 void RunUntilIdle() {
22   base::RunLoop run_loop;
23   run_loop.RunUntilIdle();
24 }
25
26 void DeleteWatcherAndForwardResult(
27     HandleWatcher* watcher,
28     base::Callback<void(MojoResult)> next_callback,
29     MojoResult result) {
30   delete watcher;
31   next_callback.Run(result);
32 }
33
34 // Helper class to manage the callback and running the message loop waiting for
35 // message to be received. Typical usage is something like:
36 //   Schedule callback returned from GetCallback().
37 //   RunUntilGotCallback();
38 //   EXPECT_TRUE(got_callback());
39 //   clear_callback();
40 class CallbackHelper {
41  public:
42   CallbackHelper()
43       : got_callback_(false),
44         run_loop_(NULL),
45         weak_factory_(this) {}
46   ~CallbackHelper() {}
47
48   // See description above |got_callback_|.
49   bool got_callback() const { return got_callback_; }
50   void clear_callback() { got_callback_ = false; }
51
52   // Runs the current MessageLoop until the callback returned from GetCallback()
53   // is notified.
54   void RunUntilGotCallback() {
55     ASSERT_TRUE(run_loop_ == NULL);
56     base::RunLoop run_loop;
57     base::AutoReset<base::RunLoop*> reseter(&run_loop_, &run_loop);
58     run_loop.Run();
59   }
60
61   base::Callback<void(MojoResult)> GetCallback() {
62     return base::Bind(&CallbackHelper::OnCallback, weak_factory_.GetWeakPtr());
63   }
64
65   void Start(HandleWatcher* watcher, const MessagePipeHandle& handle) {
66     StartWithCallback(watcher, handle, GetCallback());
67   }
68
69   void StartWithCallback(HandleWatcher* watcher,
70                          const MessagePipeHandle& handle,
71                          const base::Callback<void(MojoResult)>& callback) {
72     watcher->Start(handle, MOJO_WAIT_FLAG_READABLE, MOJO_DEADLINE_INDEFINITE,
73                    callback);
74   }
75
76  private:
77   void OnCallback(MojoResult result) {
78     got_callback_ = true;
79     if (run_loop_)
80       run_loop_->Quit();
81   }
82
83   // Set to true when the callback is called.
84   bool got_callback_;
85
86   // If non-NULL we're in RunUntilGotCallback().
87   base::RunLoop* run_loop_;
88
89   base::WeakPtrFactory<CallbackHelper> weak_factory_;
90
91  private:
92   DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
93 };
94
95 class HandleWatcherTest : public testing::Test {
96  public:
97   HandleWatcherTest() {}
98   virtual ~HandleWatcherTest() {
99     HandleWatcher::tick_clock_ = NULL;
100   }
101
102  protected:
103   void InstallTickClock() {
104     HandleWatcher::tick_clock_ = &tick_clock_;
105   }
106
107   base::SimpleTestTickClock tick_clock_;
108
109  private:
110   base::MessageLoop message_loop_;
111
112   DISALLOW_COPY_AND_ASSIGN(HandleWatcherTest);
113 };
114
115 // Trivial test case with a single handle to watch.
116 TEST_F(HandleWatcherTest, SingleHandler) {
117   MessagePipe test_pipe;
118   ASSERT_TRUE(test_pipe.handle0.is_valid());
119   CallbackHelper callback_helper;
120   HandleWatcher watcher;
121   callback_helper.Start(&watcher, test_pipe.handle0.get());
122   RunUntilIdle();
123   EXPECT_FALSE(callback_helper.got_callback());
124   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle1.get(),
125                                            std::string()));
126   callback_helper.RunUntilGotCallback();
127   EXPECT_TRUE(callback_helper.got_callback());
128 }
129
130 // Creates three handles and notfies them in reverse order ensuring each one is
131 // notified appropriately.
132 TEST_F(HandleWatcherTest, ThreeHandles) {
133   MessagePipe test_pipe1;
134   MessagePipe test_pipe2;
135   MessagePipe test_pipe3;
136   CallbackHelper callback_helper1;
137   CallbackHelper callback_helper2;
138   CallbackHelper callback_helper3;
139   ASSERT_TRUE(test_pipe1.handle0.is_valid());
140   ASSERT_TRUE(test_pipe2.handle0.is_valid());
141   ASSERT_TRUE(test_pipe3.handle0.is_valid());
142
143   HandleWatcher watcher1;
144   callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
145   RunUntilIdle();
146   EXPECT_FALSE(callback_helper1.got_callback());
147   EXPECT_FALSE(callback_helper2.got_callback());
148   EXPECT_FALSE(callback_helper3.got_callback());
149
150   HandleWatcher watcher2;
151   callback_helper2.Start(&watcher2, test_pipe2.handle0.get());
152   RunUntilIdle();
153   EXPECT_FALSE(callback_helper1.got_callback());
154   EXPECT_FALSE(callback_helper2.got_callback());
155   EXPECT_FALSE(callback_helper3.got_callback());
156
157   HandleWatcher watcher3;
158   callback_helper3.Start(&watcher3, test_pipe3.handle0.get());
159   RunUntilIdle();
160   EXPECT_FALSE(callback_helper1.got_callback());
161   EXPECT_FALSE(callback_helper2.got_callback());
162   EXPECT_FALSE(callback_helper3.got_callback());
163
164   // Write to 3 and make sure it's notified.
165   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe3.handle1.get(),
166                                            std::string()));
167   callback_helper3.RunUntilGotCallback();
168   EXPECT_FALSE(callback_helper1.got_callback());
169   EXPECT_FALSE(callback_helper2.got_callback());
170   EXPECT_TRUE(callback_helper3.got_callback());
171   callback_helper3.clear_callback();
172
173   // Write to 1 and 3. Only 1 should be notified since 3 was is no longer
174   // running.
175   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
176                                            std::string()));
177   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe3.handle1.get(),
178                                            std::string()));
179   callback_helper1.RunUntilGotCallback();
180   EXPECT_TRUE(callback_helper1.got_callback());
181   EXPECT_FALSE(callback_helper2.got_callback());
182   EXPECT_FALSE(callback_helper3.got_callback());
183   callback_helper1.clear_callback();
184
185   // Write to 1 and 2. Only 2 should be notified (since 1 was already notified).
186   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
187                                            std::string()));
188   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2.handle1.get(),
189                                            std::string()));
190   callback_helper2.RunUntilGotCallback();
191   EXPECT_FALSE(callback_helper1.got_callback());
192   EXPECT_TRUE(callback_helper2.got_callback());
193   EXPECT_FALSE(callback_helper3.got_callback());
194 }
195
196 // Verifies Start() invoked a second time works.
197 TEST_F(HandleWatcherTest, Restart) {
198   MessagePipe test_pipe1;
199   MessagePipe test_pipe2;
200   CallbackHelper callback_helper1;
201   CallbackHelper callback_helper2;
202   ASSERT_TRUE(test_pipe1.handle0.is_valid());
203   ASSERT_TRUE(test_pipe2.handle0.is_valid());
204
205   HandleWatcher watcher1;
206   callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
207   RunUntilIdle();
208   EXPECT_FALSE(callback_helper1.got_callback());
209   EXPECT_FALSE(callback_helper2.got_callback());
210
211   HandleWatcher watcher2;
212   callback_helper2.Start(&watcher2, test_pipe2.handle0.get());
213   RunUntilIdle();
214   EXPECT_FALSE(callback_helper1.got_callback());
215   EXPECT_FALSE(callback_helper2.got_callback());
216
217   // Write to 1 and make sure it's notified.
218   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
219                                            std::string()));
220   callback_helper1.RunUntilGotCallback();
221   EXPECT_TRUE(callback_helper1.got_callback());
222   EXPECT_FALSE(callback_helper2.got_callback());
223   callback_helper1.clear_callback();
224   EXPECT_TRUE(mojo::test::DiscardMessage(test_pipe1.handle0.get()));
225
226   // Write to 2 and make sure it's notified.
227   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2.handle1.get(),
228                                            std::string()));
229   callback_helper2.RunUntilGotCallback();
230   EXPECT_FALSE(callback_helper1.got_callback());
231   EXPECT_TRUE(callback_helper2.got_callback());
232   callback_helper2.clear_callback();
233
234   // Listen on 1 again.
235   callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
236   RunUntilIdle();
237   EXPECT_FALSE(callback_helper1.got_callback());
238   EXPECT_FALSE(callback_helper2.got_callback());
239
240   // Write to 1 and make sure it's notified.
241   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
242                                            std::string()));
243   callback_helper1.RunUntilGotCallback();
244   EXPECT_TRUE(callback_helper1.got_callback());
245   EXPECT_FALSE(callback_helper2.got_callback());
246 }
247
248 // Verifies deadline is honored.
249 TEST_F(HandleWatcherTest, Deadline) {
250   InstallTickClock();
251
252   MessagePipe test_pipe1;
253   MessagePipe test_pipe2;
254   MessagePipe test_pipe3;
255   CallbackHelper callback_helper1;
256   CallbackHelper callback_helper2;
257   CallbackHelper callback_helper3;
258   ASSERT_TRUE(test_pipe1.handle0.is_valid());
259   ASSERT_TRUE(test_pipe2.handle0.is_valid());
260   ASSERT_TRUE(test_pipe3.handle0.is_valid());
261
262   // Add a watcher with an infinite timeout.
263   HandleWatcher watcher1;
264   callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
265   RunUntilIdle();
266   EXPECT_FALSE(callback_helper1.got_callback());
267   EXPECT_FALSE(callback_helper2.got_callback());
268   EXPECT_FALSE(callback_helper3.got_callback());
269
270   // Add another watcher wth a timeout of 500 microseconds.
271   HandleWatcher watcher2;
272   watcher2.Start(test_pipe2.handle0.get(), MOJO_WAIT_FLAG_READABLE, 500,
273                  callback_helper2.GetCallback());
274   RunUntilIdle();
275   EXPECT_FALSE(callback_helper1.got_callback());
276   EXPECT_FALSE(callback_helper2.got_callback());
277   EXPECT_FALSE(callback_helper3.got_callback());
278
279   // Advance the clock passed the deadline. We also have to start another
280   // watcher to wake up the background thread.
281   tick_clock_.Advance(base::TimeDelta::FromMicroseconds(501));
282
283   HandleWatcher watcher3;
284   callback_helper3.Start(&watcher3, test_pipe3.handle0.get());
285
286   callback_helper2.RunUntilGotCallback();
287   EXPECT_FALSE(callback_helper1.got_callback());
288   EXPECT_TRUE(callback_helper2.got_callback());
289   EXPECT_FALSE(callback_helper3.got_callback());
290 }
291
292 TEST_F(HandleWatcherTest, DeleteInCallback) {
293   MessagePipe test_pipe;
294   CallbackHelper callback_helper;
295
296   HandleWatcher* watcher = new HandleWatcher();
297   callback_helper.StartWithCallback(watcher, test_pipe.handle1.get(),
298                                     base::Bind(&DeleteWatcherAndForwardResult,
299                                                watcher,
300                                                callback_helper.GetCallback()));
301   EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle0.get(),
302                                            std::string()));
303   callback_helper.RunUntilGotCallback();
304   EXPECT_TRUE(callback_helper.got_callback());
305 }
306
307 }  // namespace test
308 }  // namespace common
309 }  // namespace mojo