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"
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/common/time_helper.h"
14 #include "mojo/public/system/core_cpp.h"
15 #include "mojo/public/tests/test_utils.h"
16 #include "testing/gtest/include/gtest/gtest.h"
23 base::RunLoop run_loop
;
24 run_loop
.RunUntilIdle();
27 void DeleteWatcherAndForwardResult(
28 HandleWatcher
* watcher
,
29 base::Callback
<void(MojoResult
)> next_callback
,
32 next_callback
.Run(result
);
35 // Helper class to manage the callback and running the message loop waiting for
36 // message to be received. Typical usage is something like:
37 // Schedule callback returned from GetCallback().
38 // RunUntilGotCallback();
39 // EXPECT_TRUE(got_callback());
41 class CallbackHelper
{
44 : got_callback_(false),
46 weak_factory_(this) {}
49 // See description above |got_callback_|.
50 bool got_callback() const { return got_callback_
; }
51 void clear_callback() { got_callback_
= false; }
53 // Runs the current MessageLoop until the callback returned from GetCallback()
55 void RunUntilGotCallback() {
56 ASSERT_TRUE(run_loop_
== NULL
);
57 base::RunLoop run_loop
;
58 base::AutoReset
<base::RunLoop
*> reseter(&run_loop_
, &run_loop
);
62 base::Callback
<void(MojoResult
)> GetCallback() {
63 return base::Bind(&CallbackHelper::OnCallback
, weak_factory_
.GetWeakPtr());
66 void Start(HandleWatcher
* watcher
, const MessagePipeHandle
& handle
) {
67 StartWithCallback(watcher
, handle
, GetCallback());
70 void StartWithCallback(HandleWatcher
* watcher
,
71 const MessagePipeHandle
& handle
,
72 const base::Callback
<void(MojoResult
)>& callback
) {
73 watcher
->Start(handle
, MOJO_WAIT_FLAG_READABLE
, MOJO_DEADLINE_INDEFINITE
,
78 void OnCallback(MojoResult result
) {
84 // Set to true when the callback is called.
87 // If non-NULL we're in RunUntilGotCallback().
88 base::RunLoop
* run_loop_
;
90 base::WeakPtrFactory
<CallbackHelper
> weak_factory_
;
93 DISALLOW_COPY_AND_ASSIGN(CallbackHelper
);
96 class HandleWatcherTest
: public testing::Test
{
98 HandleWatcherTest() {}
99 virtual ~HandleWatcherTest() {
100 test::SetTickClockForTest(NULL
);
104 void InstallTickClock() {
105 test::SetTickClockForTest(&tick_clock_
);
108 base::SimpleTestTickClock tick_clock_
;
111 base::MessageLoop message_loop_
;
113 DISALLOW_COPY_AND_ASSIGN(HandleWatcherTest
);
116 // Trivial test case with a single handle to watch.
117 TEST_F(HandleWatcherTest
, SingleHandler
) {
118 MessagePipe test_pipe
;
119 ASSERT_TRUE(test_pipe
.handle0
.is_valid());
120 CallbackHelper callback_helper
;
121 HandleWatcher watcher
;
122 callback_helper
.Start(&watcher
, test_pipe
.handle0
.get());
124 EXPECT_FALSE(callback_helper
.got_callback());
125 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe
.handle1
.get(),
127 callback_helper
.RunUntilGotCallback();
128 EXPECT_TRUE(callback_helper
.got_callback());
131 // Creates three handles and notfies them in reverse order ensuring each one is
132 // notified appropriately.
133 TEST_F(HandleWatcherTest
, ThreeHandles
) {
134 MessagePipe test_pipe1
;
135 MessagePipe test_pipe2
;
136 MessagePipe test_pipe3
;
137 CallbackHelper callback_helper1
;
138 CallbackHelper callback_helper2
;
139 CallbackHelper callback_helper3
;
140 ASSERT_TRUE(test_pipe1
.handle0
.is_valid());
141 ASSERT_TRUE(test_pipe2
.handle0
.is_valid());
142 ASSERT_TRUE(test_pipe3
.handle0
.is_valid());
144 HandleWatcher watcher1
;
145 callback_helper1
.Start(&watcher1
, test_pipe1
.handle0
.get());
147 EXPECT_FALSE(callback_helper1
.got_callback());
148 EXPECT_FALSE(callback_helper2
.got_callback());
149 EXPECT_FALSE(callback_helper3
.got_callback());
151 HandleWatcher watcher2
;
152 callback_helper2
.Start(&watcher2
, test_pipe2
.handle0
.get());
154 EXPECT_FALSE(callback_helper1
.got_callback());
155 EXPECT_FALSE(callback_helper2
.got_callback());
156 EXPECT_FALSE(callback_helper3
.got_callback());
158 HandleWatcher watcher3
;
159 callback_helper3
.Start(&watcher3
, test_pipe3
.handle0
.get());
161 EXPECT_FALSE(callback_helper1
.got_callback());
162 EXPECT_FALSE(callback_helper2
.got_callback());
163 EXPECT_FALSE(callback_helper3
.got_callback());
165 // Write to 3 and make sure it's notified.
166 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe3
.handle1
.get(),
168 callback_helper3
.RunUntilGotCallback();
169 EXPECT_FALSE(callback_helper1
.got_callback());
170 EXPECT_FALSE(callback_helper2
.got_callback());
171 EXPECT_TRUE(callback_helper3
.got_callback());
172 callback_helper3
.clear_callback();
174 // Write to 1 and 3. Only 1 should be notified since 3 was is no longer
176 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1
.handle1
.get(),
178 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe3
.handle1
.get(),
180 callback_helper1
.RunUntilGotCallback();
181 EXPECT_TRUE(callback_helper1
.got_callback());
182 EXPECT_FALSE(callback_helper2
.got_callback());
183 EXPECT_FALSE(callback_helper3
.got_callback());
184 callback_helper1
.clear_callback();
186 // Write to 1 and 2. Only 2 should be notified (since 1 was already notified).
187 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1
.handle1
.get(),
189 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2
.handle1
.get(),
191 callback_helper2
.RunUntilGotCallback();
192 EXPECT_FALSE(callback_helper1
.got_callback());
193 EXPECT_TRUE(callback_helper2
.got_callback());
194 EXPECT_FALSE(callback_helper3
.got_callback());
197 // Verifies Start() invoked a second time works.
198 TEST_F(HandleWatcherTest
, Restart
) {
199 MessagePipe test_pipe1
;
200 MessagePipe test_pipe2
;
201 CallbackHelper callback_helper1
;
202 CallbackHelper callback_helper2
;
203 ASSERT_TRUE(test_pipe1
.handle0
.is_valid());
204 ASSERT_TRUE(test_pipe2
.handle0
.is_valid());
206 HandleWatcher watcher1
;
207 callback_helper1
.Start(&watcher1
, test_pipe1
.handle0
.get());
209 EXPECT_FALSE(callback_helper1
.got_callback());
210 EXPECT_FALSE(callback_helper2
.got_callback());
212 HandleWatcher watcher2
;
213 callback_helper2
.Start(&watcher2
, test_pipe2
.handle0
.get());
215 EXPECT_FALSE(callback_helper1
.got_callback());
216 EXPECT_FALSE(callback_helper2
.got_callback());
218 // Write to 1 and make sure it's notified.
219 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1
.handle1
.get(),
221 callback_helper1
.RunUntilGotCallback();
222 EXPECT_TRUE(callback_helper1
.got_callback());
223 EXPECT_FALSE(callback_helper2
.got_callback());
224 callback_helper1
.clear_callback();
225 EXPECT_TRUE(mojo::test::DiscardMessage(test_pipe1
.handle0
.get()));
227 // Write to 2 and make sure it's notified.
228 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2
.handle1
.get(),
230 callback_helper2
.RunUntilGotCallback();
231 EXPECT_FALSE(callback_helper1
.got_callback());
232 EXPECT_TRUE(callback_helper2
.got_callback());
233 callback_helper2
.clear_callback();
235 // Listen on 1 again.
236 callback_helper1
.Start(&watcher1
, test_pipe1
.handle0
.get());
238 EXPECT_FALSE(callback_helper1
.got_callback());
239 EXPECT_FALSE(callback_helper2
.got_callback());
241 // Write to 1 and make sure it's notified.
242 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1
.handle1
.get(),
244 callback_helper1
.RunUntilGotCallback();
245 EXPECT_TRUE(callback_helper1
.got_callback());
246 EXPECT_FALSE(callback_helper2
.got_callback());
249 // Verifies deadline is honored.
250 TEST_F(HandleWatcherTest
, Deadline
) {
253 MessagePipe test_pipe1
;
254 MessagePipe test_pipe2
;
255 MessagePipe test_pipe3
;
256 CallbackHelper callback_helper1
;
257 CallbackHelper callback_helper2
;
258 CallbackHelper callback_helper3
;
259 ASSERT_TRUE(test_pipe1
.handle0
.is_valid());
260 ASSERT_TRUE(test_pipe2
.handle0
.is_valid());
261 ASSERT_TRUE(test_pipe3
.handle0
.is_valid());
263 // Add a watcher with an infinite timeout.
264 HandleWatcher watcher1
;
265 callback_helper1
.Start(&watcher1
, test_pipe1
.handle0
.get());
267 EXPECT_FALSE(callback_helper1
.got_callback());
268 EXPECT_FALSE(callback_helper2
.got_callback());
269 EXPECT_FALSE(callback_helper3
.got_callback());
271 // Add another watcher wth a timeout of 500 microseconds.
272 HandleWatcher watcher2
;
273 watcher2
.Start(test_pipe2
.handle0
.get(), MOJO_WAIT_FLAG_READABLE
, 500,
274 callback_helper2
.GetCallback());
276 EXPECT_FALSE(callback_helper1
.got_callback());
277 EXPECT_FALSE(callback_helper2
.got_callback());
278 EXPECT_FALSE(callback_helper3
.got_callback());
280 // Advance the clock passed the deadline. We also have to start another
281 // watcher to wake up the background thread.
282 tick_clock_
.Advance(base::TimeDelta::FromMicroseconds(501));
284 HandleWatcher watcher3
;
285 callback_helper3
.Start(&watcher3
, test_pipe3
.handle0
.get());
287 callback_helper2
.RunUntilGotCallback();
288 EXPECT_FALSE(callback_helper1
.got_callback());
289 EXPECT_TRUE(callback_helper2
.got_callback());
290 EXPECT_FALSE(callback_helper3
.got_callback());
293 TEST_F(HandleWatcherTest
, DeleteInCallback
) {
294 MessagePipe test_pipe
;
295 CallbackHelper callback_helper
;
297 HandleWatcher
* watcher
= new HandleWatcher();
298 callback_helper
.StartWithCallback(watcher
, test_pipe
.handle1
.get(),
299 base::Bind(&DeleteWatcherAndForwardResult
,
301 callback_helper
.GetCallback()));
302 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe
.handle0
.get(),
304 callback_helper
.RunUntilGotCallback();
305 EXPECT_TRUE(callback_helper
.got_callback());
309 } // namespace common