| 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 |