OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "mojo/public/cpp/utility/run_loop.h" | 5 #include "mojo/public/cpp/utility/run_loop.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "mojo/public/cpp/system/macros.h" | 9 #include "mojo/public/cpp/system/macros.h" |
10 #include "mojo/public/cpp/system/message_pipe.h" | 10 #include "mojo/public/cpp/system/message_pipe.h" |
(...skipping 29 matching lines...) Expand all Loading... |
40 } | 40 } |
41 | 41 |
42 private: | 42 private: |
43 int ready_count_; | 43 int ready_count_; |
44 int error_count_; | 44 int error_count_; |
45 MojoResult last_error_result_; | 45 MojoResult last_error_result_; |
46 | 46 |
47 MOJO_DISALLOW_COPY_AND_ASSIGN(TestRunLoopHandler); | 47 MOJO_DISALLOW_COPY_AND_ASSIGN(TestRunLoopHandler); |
48 }; | 48 }; |
49 | 49 |
50 class RunLoopTest : public testing::Test { | |
51 public: | |
52 RunLoopTest() {} | |
53 | |
54 void SetUp() override { | |
55 Test::SetUp(); | |
56 RunLoop::SetUp(); | |
57 } | |
58 void TearDown() override { | |
59 RunLoop::TearDown(); | |
60 Test::TearDown(); | |
61 } | |
62 | |
63 private: | |
64 MOJO_DISALLOW_COPY_AND_ASSIGN(RunLoopTest); | |
65 }; | |
66 | |
67 // Trivial test to verify Run() with no added handles returns. | 50 // Trivial test to verify Run() with no added handles returns. |
68 TEST_F(RunLoopTest, ExitsWithNoHandles) { | 51 TEST(RunLoopTest, ExitsWithNoHandles) { |
69 RunLoop run_loop; | 52 RunLoop run_loop; |
70 run_loop.Run(); | 53 run_loop.Run(); |
71 } | 54 } |
72 | 55 |
73 class RemoveOnReadyRunLoopHandler : public TestRunLoopHandler { | 56 class RemoveOnReadyRunLoopHandler : public TestRunLoopHandler { |
74 public: | 57 public: |
75 RemoveOnReadyRunLoopHandler() : run_loop_(nullptr) {} | 58 RemoveOnReadyRunLoopHandler() : run_loop_(nullptr) {} |
76 ~RemoveOnReadyRunLoopHandler() override {} | 59 ~RemoveOnReadyRunLoopHandler() override {} |
77 | 60 |
78 void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; } | 61 void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; } |
79 | 62 |
80 // RunLoopHandler: | 63 // RunLoopHandler: |
81 void OnHandleReady(const Handle& handle) override { | 64 void OnHandleReady(const Handle& handle) override { |
82 run_loop_->RemoveHandler(handle); | 65 run_loop_->RemoveHandler(handle); |
83 TestRunLoopHandler::OnHandleReady(handle); | 66 TestRunLoopHandler::OnHandleReady(handle); |
84 } | 67 } |
85 | 68 |
86 private: | 69 private: |
87 RunLoop* run_loop_; | 70 RunLoop* run_loop_; |
88 | 71 |
89 MOJO_DISALLOW_COPY_AND_ASSIGN(RemoveOnReadyRunLoopHandler); | 72 MOJO_DISALLOW_COPY_AND_ASSIGN(RemoveOnReadyRunLoopHandler); |
90 }; | 73 }; |
91 | 74 |
92 // Verifies RunLoop quits when no more handles (handle is removed when ready). | 75 // Verifies RunLoop quits when no more handles (handle is removed when ready). |
93 TEST_F(RunLoopTest, HandleReady) { | 76 TEST(RunLoopTest, HandleReady) { |
94 RemoveOnReadyRunLoopHandler handler; | 77 RemoveOnReadyRunLoopHandler handler; |
95 MessagePipe test_pipe; | 78 MessagePipe test_pipe; |
96 EXPECT_TRUE(test::WriteTextMessage(test_pipe.handle1.get(), std::string())); | 79 EXPECT_TRUE(test::WriteTextMessage(test_pipe.handle1.get(), std::string())); |
97 | 80 |
98 RunLoop run_loop; | 81 RunLoop run_loop; |
99 handler.set_run_loop(&run_loop); | 82 handler.set_run_loop(&run_loop); |
100 run_loop.AddHandler(&handler, test_pipe.handle0.get(), | 83 run_loop.AddHandler(&handler, test_pipe.handle0.get(), |
101 MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE); | 84 MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE); |
102 run_loop.Run(); | 85 run_loop.Run(); |
103 EXPECT_EQ(1, handler.ready_count()); | 86 EXPECT_EQ(1, handler.ready_count()); |
(...skipping 14 matching lines...) Expand all Loading... |
118 TestRunLoopHandler::OnHandleReady(handle); | 101 TestRunLoopHandler::OnHandleReady(handle); |
119 } | 102 } |
120 | 103 |
121 private: | 104 private: |
122 RunLoop* run_loop_; | 105 RunLoop* run_loop_; |
123 | 106 |
124 MOJO_DISALLOW_COPY_AND_ASSIGN(QuitOnReadyRunLoopHandler); | 107 MOJO_DISALLOW_COPY_AND_ASSIGN(QuitOnReadyRunLoopHandler); |
125 }; | 108 }; |
126 | 109 |
127 // Verifies Quit() from OnHandleReady() quits the loop. | 110 // Verifies Quit() from OnHandleReady() quits the loop. |
128 TEST_F(RunLoopTest, QuitFromReady) { | 111 TEST(RunLoopTest, QuitFromReady) { |
129 QuitOnReadyRunLoopHandler handler; | 112 QuitOnReadyRunLoopHandler handler; |
130 MessagePipe test_pipe; | 113 MessagePipe test_pipe; |
131 EXPECT_TRUE(test::WriteTextMessage(test_pipe.handle1.get(), std::string())); | 114 EXPECT_TRUE(test::WriteTextMessage(test_pipe.handle1.get(), std::string())); |
132 | 115 |
133 RunLoop run_loop; | 116 RunLoop run_loop; |
134 handler.set_run_loop(&run_loop); | 117 handler.set_run_loop(&run_loop); |
135 run_loop.AddHandler(&handler, test_pipe.handle0.get(), | 118 run_loop.AddHandler(&handler, test_pipe.handle0.get(), |
136 MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE); | 119 MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE); |
137 run_loop.Run(); | 120 run_loop.Run(); |
138 EXPECT_EQ(1, handler.ready_count()); | 121 EXPECT_EQ(1, handler.ready_count()); |
(...skipping 14 matching lines...) Expand all Loading... |
153 TestRunLoopHandler::OnHandleError(handle, result); | 136 TestRunLoopHandler::OnHandleError(handle, result); |
154 } | 137 } |
155 | 138 |
156 private: | 139 private: |
157 RunLoop* run_loop_; | 140 RunLoop* run_loop_; |
158 | 141 |
159 MOJO_DISALLOW_COPY_AND_ASSIGN(QuitOnErrorRunLoopHandler); | 142 MOJO_DISALLOW_COPY_AND_ASSIGN(QuitOnErrorRunLoopHandler); |
160 }; | 143 }; |
161 | 144 |
162 // Verifies Quit() when the deadline is reached works. | 145 // Verifies Quit() when the deadline is reached works. |
163 TEST_F(RunLoopTest, QuitWhenDeadlineExpired) { | 146 TEST(RunLoopTest, QuitWhenDeadlineExpired) { |
164 QuitOnErrorRunLoopHandler handler; | 147 QuitOnErrorRunLoopHandler handler; |
165 MessagePipe test_pipe; | 148 MessagePipe test_pipe; |
166 RunLoop run_loop; | 149 RunLoop run_loop; |
167 handler.set_run_loop(&run_loop); | 150 handler.set_run_loop(&run_loop); |
168 run_loop.AddHandler(&handler, test_pipe.handle0.get(), | 151 run_loop.AddHandler(&handler, test_pipe.handle0.get(), |
169 MOJO_HANDLE_SIGNAL_READABLE, | 152 MOJO_HANDLE_SIGNAL_READABLE, |
170 static_cast<MojoDeadline>(10000)); | 153 static_cast<MojoDeadline>(10000)); |
171 run_loop.Run(); | 154 run_loop.Run(); |
172 EXPECT_EQ(0, handler.ready_count()); | 155 EXPECT_EQ(0, handler.ready_count()); |
173 EXPECT_EQ(1, handler.error_count()); | 156 EXPECT_EQ(1, handler.error_count()); |
174 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, handler.last_error_result()); | 157 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, handler.last_error_result()); |
175 EXPECT_FALSE(run_loop.HasHandler(test_pipe.handle0.get())); | 158 EXPECT_FALSE(run_loop.HasHandler(test_pipe.handle0.get())); |
176 } | 159 } |
177 | 160 |
178 // Test that handlers are notified of loop destruction. | 161 // Test that handlers are notified of loop destruction. |
179 TEST_F(RunLoopTest, Destruction) { | 162 TEST(RunLoopTest, Destruction) { |
180 TestRunLoopHandler handler; | 163 TestRunLoopHandler handler; |
181 MessagePipe test_pipe; | 164 MessagePipe test_pipe; |
182 { | 165 { |
183 RunLoop run_loop; | 166 RunLoop run_loop; |
184 run_loop.AddHandler(&handler, | 167 run_loop.AddHandler(&handler, |
185 test_pipe.handle0.get(), | 168 test_pipe.handle0.get(), |
186 MOJO_HANDLE_SIGNAL_READABLE, | 169 MOJO_HANDLE_SIGNAL_READABLE, |
187 MOJO_DEADLINE_INDEFINITE); | 170 MOJO_DEADLINE_INDEFINITE); |
188 } | 171 } |
189 EXPECT_EQ(1, handler.error_count()); | 172 EXPECT_EQ(1, handler.error_count()); |
(...skipping 16 matching lines...) Expand all Loading... |
206 } | 189 } |
207 | 190 |
208 private: | 191 private: |
209 std::vector<Handle> handles_; | 192 std::vector<Handle> handles_; |
210 RunLoop* run_loop_; | 193 RunLoop* run_loop_; |
211 | 194 |
212 MOJO_DISALLOW_COPY_AND_ASSIGN(RemoveManyRunLoopHandler); | 195 MOJO_DISALLOW_COPY_AND_ASSIGN(RemoveManyRunLoopHandler); |
213 }; | 196 }; |
214 | 197 |
215 // Test that handlers are notified of loop destruction. | 198 // Test that handlers are notified of loop destruction. |
216 TEST_F(RunLoopTest, MultipleHandleDestruction) { | 199 TEST(RunLoopTest, MultipleHandleDestruction) { |
217 RemoveManyRunLoopHandler odd_handler; | 200 RemoveManyRunLoopHandler odd_handler; |
218 TestRunLoopHandler even_handler; | 201 TestRunLoopHandler even_handler; |
219 MessagePipe test_pipe1, test_pipe2, test_pipe3; | 202 MessagePipe test_pipe1, test_pipe2, test_pipe3; |
220 { | 203 { |
221 RunLoop run_loop; | 204 RunLoop run_loop; |
222 odd_handler.set_run_loop(&run_loop); | 205 odd_handler.set_run_loop(&run_loop); |
223 odd_handler.add_handle(test_pipe1.handle0.get()); | 206 odd_handler.add_handle(test_pipe1.handle0.get()); |
224 odd_handler.add_handle(test_pipe3.handle0.get()); | 207 odd_handler.add_handle(test_pipe3.handle0.get()); |
225 run_loop.AddHandler(&odd_handler, | 208 run_loop.AddHandler(&odd_handler, |
226 test_pipe1.handle0.get(), | 209 test_pipe1.handle0.get(), |
(...skipping 28 matching lines...) Expand all Loading... |
255 MOJO_DEADLINE_INDEFINITE); | 238 MOJO_DEADLINE_INDEFINITE); |
256 TestRunLoopHandler::OnHandleError(handle, result); | 239 TestRunLoopHandler::OnHandleError(handle, result); |
257 } | 240 } |
258 | 241 |
259 private: | 242 private: |
260 RunLoop* run_loop_; | 243 RunLoop* run_loop_; |
261 | 244 |
262 MOJO_DISALLOW_COPY_AND_ASSIGN(AddHandlerOnErrorHandler); | 245 MOJO_DISALLOW_COPY_AND_ASSIGN(AddHandlerOnErrorHandler); |
263 }; | 246 }; |
264 | 247 |
265 TEST_F(RunLoopTest, AddHandlerOnError) { | 248 TEST(RunLoopTest, AddHandlerOnError) { |
266 AddHandlerOnErrorHandler handler; | 249 AddHandlerOnErrorHandler handler; |
267 MessagePipe test_pipe; | 250 MessagePipe test_pipe; |
268 { | 251 { |
269 RunLoop run_loop; | 252 RunLoop run_loop; |
270 handler.set_run_loop(&run_loop); | 253 handler.set_run_loop(&run_loop); |
271 run_loop.AddHandler(&handler, | 254 run_loop.AddHandler(&handler, |
272 test_pipe.handle0.get(), | 255 test_pipe.handle0.get(), |
273 MOJO_HANDLE_SIGNAL_READABLE, | 256 MOJO_HANDLE_SIGNAL_READABLE, |
274 MOJO_DEADLINE_INDEFINITE); | 257 MOJO_DEADLINE_INDEFINITE); |
275 } | 258 } |
276 EXPECT_EQ(1, handler.error_count()); | 259 EXPECT_EQ(1, handler.error_count()); |
277 EXPECT_EQ(MOJO_RESULT_ABORTED, handler.last_error_result()); | 260 EXPECT_EQ(MOJO_RESULT_ABORTED, handler.last_error_result()); |
278 } | 261 } |
279 | 262 |
280 TEST_F(RunLoopTest, Current) { | 263 TEST(RunLoopTest, Current) { |
281 EXPECT_TRUE(RunLoop::current() == nullptr); | 264 EXPECT_TRUE(RunLoop::current() == nullptr); |
282 { | 265 { |
283 RunLoop run_loop; | 266 RunLoop run_loop; |
284 EXPECT_EQ(&run_loop, RunLoop::current()); | 267 EXPECT_EQ(&run_loop, RunLoop::current()); |
285 } | 268 } |
286 EXPECT_TRUE(RunLoop::current() == nullptr); | 269 EXPECT_TRUE(RunLoop::current() == nullptr); |
287 } | 270 } |
288 | 271 |
289 class NestingRunLoopHandler : public TestRunLoopHandler { | 272 class NestingRunLoopHandler : public TestRunLoopHandler { |
290 public: | 273 public: |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 MessagePipe* pipe_; | 336 MessagePipe* pipe_; |
354 size_t depth_; | 337 size_t depth_; |
355 bool reached_depth_limit_; | 338 bool reached_depth_limit_; |
356 | 339 |
357 MOJO_DISALLOW_COPY_AND_ASSIGN(NestingRunLoopHandler); | 340 MOJO_DISALLOW_COPY_AND_ASSIGN(NestingRunLoopHandler); |
358 }; | 341 }; |
359 | 342 |
360 const size_t NestingRunLoopHandler::kDepthLimit = 10; | 343 const size_t NestingRunLoopHandler::kDepthLimit = 10; |
361 const char NestingRunLoopHandler::kSignalMagic = 'X'; | 344 const char NestingRunLoopHandler::kSignalMagic = 'X'; |
362 | 345 |
363 TEST_F(RunLoopTest, NestedRun) { | 346 TEST(RunLoopTest, NestedRun) { |
364 NestingRunLoopHandler handler; | 347 NestingRunLoopHandler handler; |
365 MessagePipe test_pipe; | 348 MessagePipe test_pipe; |
366 RunLoop run_loop; | 349 RunLoop run_loop; |
367 handler.set_run_loop(&run_loop); | 350 handler.set_run_loop(&run_loop); |
368 handler.set_pipe(&test_pipe); | 351 handler.set_pipe(&test_pipe); |
369 run_loop.AddHandler(&handler, test_pipe.handle0.get(), | 352 run_loop.AddHandler(&handler, test_pipe.handle0.get(), |
370 MOJO_HANDLE_SIGNAL_READABLE, | 353 MOJO_HANDLE_SIGNAL_READABLE, |
371 static_cast<MojoDeadline>(10000)); | 354 static_cast<MojoDeadline>(10000)); |
372 handler.WriteSignal(); | 355 handler.WriteSignal(); |
373 run_loop.Run(); | 356 run_loop.Run(); |
374 | 357 |
375 EXPECT_TRUE(handler.reached_depth_limit()); | 358 EXPECT_TRUE(handler.reached_depth_limit()); |
376 // Got MOJO_RESULT_DEADLINE_EXCEEDED once then removed from the | 359 // Got MOJO_RESULT_DEADLINE_EXCEEDED once then removed from the |
377 // RunLoop's handler list. | 360 // RunLoop's handler list. |
378 EXPECT_EQ(handler.error_count(), 1); | 361 EXPECT_EQ(handler.error_count(), 1); |
379 EXPECT_EQ(handler.last_error_result(), MOJO_RESULT_DEADLINE_EXCEEDED); | 362 EXPECT_EQ(handler.last_error_result(), MOJO_RESULT_DEADLINE_EXCEEDED); |
380 } | 363 } |
381 | 364 |
382 struct Task { | 365 struct Task { |
383 Task(int num, std::vector<int>* sequence) : num(num), sequence(sequence) {} | 366 Task(int num, std::vector<int>* sequence) : num(num), sequence(sequence) {} |
384 | 367 |
385 void Run() const { sequence->push_back(num); } | 368 void Run() const { sequence->push_back(num); } |
386 | 369 |
387 int num; | 370 int num; |
388 std::vector<int>* sequence; | 371 std::vector<int>* sequence; |
389 }; | 372 }; |
390 | 373 |
391 TEST_F(RunLoopTest, DelayedTaskOrder) { | 374 TEST(RunLoopTest, DelayedTaskOrder) { |
392 std::vector<int> sequence; | 375 std::vector<int> sequence; |
393 RunLoop run_loop; | 376 RunLoop run_loop; |
394 run_loop.PostDelayedTask(Closure(Task(1, &sequence)), 0); | 377 run_loop.PostDelayedTask(Closure(Task(1, &sequence)), 0); |
395 run_loop.PostDelayedTask(Closure(Task(2, &sequence)), 0); | 378 run_loop.PostDelayedTask(Closure(Task(2, &sequence)), 0); |
396 run_loop.PostDelayedTask(Closure(Task(3, &sequence)), 0); | 379 run_loop.PostDelayedTask(Closure(Task(3, &sequence)), 0); |
397 run_loop.RunUntilIdle(); | 380 run_loop.RunUntilIdle(); |
398 | 381 |
399 ASSERT_EQ(3u, sequence.size()); | 382 ASSERT_EQ(3u, sequence.size()); |
400 EXPECT_EQ(1, sequence[0]); | 383 EXPECT_EQ(1, sequence[0]); |
401 EXPECT_EQ(2, sequence[1]); | 384 EXPECT_EQ(2, sequence[1]); |
402 EXPECT_EQ(3, sequence[2]); | 385 EXPECT_EQ(3, sequence[2]); |
403 } | 386 } |
404 | 387 |
405 struct QuittingTask { | 388 struct QuittingTask { |
406 explicit QuittingTask(RunLoop* run_loop) : run_loop(run_loop) {} | 389 explicit QuittingTask(RunLoop* run_loop) : run_loop(run_loop) {} |
407 | 390 |
408 void Run() const { run_loop->Quit(); } | 391 void Run() const { run_loop->Quit(); } |
409 | 392 |
410 RunLoop* run_loop; | 393 RunLoop* run_loop; |
411 }; | 394 }; |
412 | 395 |
413 TEST_F(RunLoopTest, QuitFromDelayedTask) { | 396 TEST(RunLoopTest, QuitFromDelayedTask) { |
414 TestRunLoopHandler handler; | 397 TestRunLoopHandler handler; |
415 MessagePipe test_pipe; | 398 MessagePipe test_pipe; |
416 RunLoop run_loop; | 399 RunLoop run_loop; |
417 run_loop.AddHandler(&handler, | 400 run_loop.AddHandler(&handler, |
418 test_pipe.handle0.get(), | 401 test_pipe.handle0.get(), |
419 MOJO_HANDLE_SIGNAL_READABLE, | 402 MOJO_HANDLE_SIGNAL_READABLE, |
420 MOJO_DEADLINE_INDEFINITE); | 403 MOJO_DEADLINE_INDEFINITE); |
421 run_loop.PostDelayedTask(Closure(QuittingTask(&run_loop)), 0); | 404 run_loop.PostDelayedTask(Closure(QuittingTask(&run_loop)), 0); |
422 run_loop.Run(); | 405 run_loop.Run(); |
423 } | 406 } |
424 | 407 |
425 } // namespace | 408 } // namespace |
426 } // namespace mojo | 409 } // namespace mojo |
OLD | NEW |