| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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/common/handle_watcher.h" | 5 #include "mojo/common/handle_watcher.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/memory/scoped_vector.h" | 12 #include "base/memory/scoped_vector.h" |
| 13 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
| 14 #include "base/test/simple_test_tick_clock.h" | 14 #include "base/test/simple_test_tick_clock.h" |
| 15 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" |
| 16 #include "mojo/common/message_pump_mojo.h" |
| 16 #include "mojo/common/time_helper.h" | 17 #include "mojo/common/time_helper.h" |
| 17 #include "mojo/public/cpp/system/core.h" | 18 #include "mojo/public/cpp/system/core.h" |
| 18 #include "mojo/public/cpp/test_support/test_utils.h" | 19 #include "mojo/public/cpp/test_support/test_utils.h" |
| 19 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 20 | 21 |
| 21 namespace mojo { | 22 namespace mojo { |
| 22 namespace common { | 23 namespace common { |
| 23 namespace test { | 24 namespace test { |
| 24 | 25 |
| 26 enum MessageLoopConfig { |
| 27 MESSAGE_LOOP_CONFIG_DEFAULT = 0, |
| 28 MESSAGE_LOOP_CONFIG_MOJO = 1 |
| 29 }; |
| 30 |
| 25 void ObserveCallback(bool* was_signaled, | 31 void ObserveCallback(bool* was_signaled, |
| 26 MojoResult* result_observed, | 32 MojoResult* result_observed, |
| 27 MojoResult result) { | 33 MojoResult result) { |
| 28 *was_signaled = true; | 34 *was_signaled = true; |
| 29 *result_observed = result; | 35 *result_observed = result; |
| 30 } | 36 } |
| 31 | 37 |
| 32 void RunUntilIdle() { | 38 void RunUntilIdle() { |
| 33 base::RunLoop run_loop; | 39 base::RunLoop run_loop; |
| 34 run_loop.RunUntilIdle(); | 40 run_loop.RunUntilIdle(); |
| 35 } | 41 } |
| 36 | 42 |
| 37 void DeleteWatcherAndForwardResult( | 43 void DeleteWatcherAndForwardResult( |
| 38 HandleWatcher* watcher, | 44 HandleWatcher* watcher, |
| 39 base::Callback<void(MojoResult)> next_callback, | 45 base::Callback<void(MojoResult)> next_callback, |
| 40 MojoResult result) { | 46 MojoResult result) { |
| 41 delete watcher; | 47 delete watcher; |
| 42 next_callback.Run(result); | 48 next_callback.Run(result); |
| 43 } | 49 } |
| 44 | 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 |
| 45 // Helper class to manage the callback and running the message loop waiting for | 60 // Helper class to manage the callback and running the message loop waiting for |
| 46 // message to be received. Typical usage is something like: | 61 // message to be received. Typical usage is something like: |
| 47 // Schedule callback returned from GetCallback(). | 62 // Schedule callback returned from GetCallback(). |
| 48 // RunUntilGotCallback(); | 63 // RunUntilGotCallback(); |
| 49 // EXPECT_TRUE(got_callback()); | 64 // EXPECT_TRUE(got_callback()); |
| 50 // clear_callback(); | 65 // clear_callback(); |
| 51 class CallbackHelper { | 66 class CallbackHelper { |
| 52 public: | 67 public: |
| 53 CallbackHelper() | 68 CallbackHelper() |
| 54 : got_callback_(false), | 69 : got_callback_(false), |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 | 111 |
| 97 // If non-NULL we're in RunUntilGotCallback(). | 112 // If non-NULL we're in RunUntilGotCallback(). |
| 98 base::RunLoop* run_loop_; | 113 base::RunLoop* run_loop_; |
| 99 | 114 |
| 100 base::WeakPtrFactory<CallbackHelper> weak_factory_; | 115 base::WeakPtrFactory<CallbackHelper> weak_factory_; |
| 101 | 116 |
| 102 private: | 117 private: |
| 103 DISALLOW_COPY_AND_ASSIGN(CallbackHelper); | 118 DISALLOW_COPY_AND_ASSIGN(CallbackHelper); |
| 104 }; | 119 }; |
| 105 | 120 |
| 106 class HandleWatcherTest : public testing::Test { | 121 class HandleWatcherTest : public testing::TestWithParam<MessageLoopConfig> { |
| 107 public: | 122 public: |
| 108 HandleWatcherTest() {} | 123 HandleWatcherTest() : message_loop_(CreateMessageLoop(GetParam())) {} |
| 109 virtual ~HandleWatcherTest() { | 124 virtual ~HandleWatcherTest() { |
| 110 test::SetTickClockForTest(NULL); | 125 test::SetTickClockForTest(NULL); |
| 111 } | 126 } |
| 112 | 127 |
| 113 protected: | 128 protected: |
| 129 void TearDownMessageLoop() { |
| 130 message_loop_.reset(); |
| 131 } |
| 132 |
| 114 void InstallTickClock() { | 133 void InstallTickClock() { |
| 115 test::SetTickClockForTest(&tick_clock_); | 134 test::SetTickClockForTest(&tick_clock_); |
| 116 } | 135 } |
| 117 | 136 |
| 118 base::SimpleTestTickClock tick_clock_; | 137 base::SimpleTestTickClock tick_clock_; |
| 119 | 138 |
| 120 private: | 139 private: |
| 121 base::ShadowingAtExitManager at_exit_; | 140 base::ShadowingAtExitManager at_exit_; |
| 122 base::MessageLoop message_loop_; | 141 scoped_ptr<base::MessageLoop> message_loop_; |
| 123 | 142 |
| 124 DISALLOW_COPY_AND_ASSIGN(HandleWatcherTest); | 143 DISALLOW_COPY_AND_ASSIGN(HandleWatcherTest); |
| 125 }; | 144 }; |
| 126 | 145 |
| 146 INSTANTIATE_TEST_CASE_P( |
| 147 MultipleMessageLoopConfigs, HandleWatcherTest, |
| 148 testing::Values(MESSAGE_LOOP_CONFIG_DEFAULT, MESSAGE_LOOP_CONFIG_MOJO)); |
| 149 |
| 127 // Trivial test case with a single handle to watch. | 150 // Trivial test case with a single handle to watch. |
| 128 TEST_F(HandleWatcherTest, SingleHandler) { | 151 TEST_P(HandleWatcherTest, SingleHandler) { |
| 129 MessagePipe test_pipe; | 152 MessagePipe test_pipe; |
| 130 ASSERT_TRUE(test_pipe.handle0.is_valid()); | 153 ASSERT_TRUE(test_pipe.handle0.is_valid()); |
| 131 CallbackHelper callback_helper; | 154 CallbackHelper callback_helper; |
| 132 HandleWatcher watcher; | 155 HandleWatcher watcher; |
| 133 callback_helper.Start(&watcher, test_pipe.handle0.get()); | 156 callback_helper.Start(&watcher, test_pipe.handle0.get()); |
| 134 RunUntilIdle(); | 157 RunUntilIdle(); |
| 135 EXPECT_FALSE(callback_helper.got_callback()); | 158 EXPECT_FALSE(callback_helper.got_callback()); |
| 136 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle1.get(), | 159 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle1.get(), |
| 137 std::string())); | 160 std::string())); |
| 138 callback_helper.RunUntilGotCallback(); | 161 callback_helper.RunUntilGotCallback(); |
| 139 EXPECT_TRUE(callback_helper.got_callback()); | 162 EXPECT_TRUE(callback_helper.got_callback()); |
| 140 } | 163 } |
| 141 | 164 |
| 142 // Creates three handles and notfies them in reverse order ensuring each one is | 165 // Creates three handles and notfies them in reverse order ensuring each one is |
| 143 // notified appropriately. | 166 // notified appropriately. |
| 144 TEST_F(HandleWatcherTest, ThreeHandles) { | 167 TEST_P(HandleWatcherTest, ThreeHandles) { |
| 145 MessagePipe test_pipe1; | 168 MessagePipe test_pipe1; |
| 146 MessagePipe test_pipe2; | 169 MessagePipe test_pipe2; |
| 147 MessagePipe test_pipe3; | 170 MessagePipe test_pipe3; |
| 148 CallbackHelper callback_helper1; | 171 CallbackHelper callback_helper1; |
| 149 CallbackHelper callback_helper2; | 172 CallbackHelper callback_helper2; |
| 150 CallbackHelper callback_helper3; | 173 CallbackHelper callback_helper3; |
| 151 ASSERT_TRUE(test_pipe1.handle0.is_valid()); | 174 ASSERT_TRUE(test_pipe1.handle0.is_valid()); |
| 152 ASSERT_TRUE(test_pipe2.handle0.is_valid()); | 175 ASSERT_TRUE(test_pipe2.handle0.is_valid()); |
| 153 ASSERT_TRUE(test_pipe3.handle0.is_valid()); | 176 ASSERT_TRUE(test_pipe3.handle0.is_valid()); |
| 154 | 177 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 std::string())); | 222 std::string())); |
| 200 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2.handle1.get(), | 223 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2.handle1.get(), |
| 201 std::string())); | 224 std::string())); |
| 202 callback_helper2.RunUntilGotCallback(); | 225 callback_helper2.RunUntilGotCallback(); |
| 203 EXPECT_FALSE(callback_helper1.got_callback()); | 226 EXPECT_FALSE(callback_helper1.got_callback()); |
| 204 EXPECT_TRUE(callback_helper2.got_callback()); | 227 EXPECT_TRUE(callback_helper2.got_callback()); |
| 205 EXPECT_FALSE(callback_helper3.got_callback()); | 228 EXPECT_FALSE(callback_helper3.got_callback()); |
| 206 } | 229 } |
| 207 | 230 |
| 208 // Verifies Start() invoked a second time works. | 231 // Verifies Start() invoked a second time works. |
| 209 TEST_F(HandleWatcherTest, Restart) { | 232 TEST_P(HandleWatcherTest, Restart) { |
| 210 MessagePipe test_pipe1; | 233 MessagePipe test_pipe1; |
| 211 MessagePipe test_pipe2; | 234 MessagePipe test_pipe2; |
| 212 CallbackHelper callback_helper1; | 235 CallbackHelper callback_helper1; |
| 213 CallbackHelper callback_helper2; | 236 CallbackHelper callback_helper2; |
| 214 ASSERT_TRUE(test_pipe1.handle0.is_valid()); | 237 ASSERT_TRUE(test_pipe1.handle0.is_valid()); |
| 215 ASSERT_TRUE(test_pipe2.handle0.is_valid()); | 238 ASSERT_TRUE(test_pipe2.handle0.is_valid()); |
| 216 | 239 |
| 217 HandleWatcher watcher1; | 240 HandleWatcher watcher1; |
| 218 callback_helper1.Start(&watcher1, test_pipe1.handle0.get()); | 241 callback_helper1.Start(&watcher1, test_pipe1.handle0.get()); |
| 219 RunUntilIdle(); | 242 RunUntilIdle(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 | 274 |
| 252 // Write to 1 and make sure it's notified. | 275 // Write to 1 and make sure it's notified. |
| 253 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(), | 276 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(), |
| 254 std::string())); | 277 std::string())); |
| 255 callback_helper1.RunUntilGotCallback(); | 278 callback_helper1.RunUntilGotCallback(); |
| 256 EXPECT_TRUE(callback_helper1.got_callback()); | 279 EXPECT_TRUE(callback_helper1.got_callback()); |
| 257 EXPECT_FALSE(callback_helper2.got_callback()); | 280 EXPECT_FALSE(callback_helper2.got_callback()); |
| 258 } | 281 } |
| 259 | 282 |
| 260 // Verifies deadline is honored. | 283 // Verifies deadline is honored. |
| 261 TEST_F(HandleWatcherTest, Deadline) { | 284 TEST_P(HandleWatcherTest, Deadline) { |
| 262 InstallTickClock(); | 285 InstallTickClock(); |
| 263 | 286 |
| 264 MessagePipe test_pipe1; | 287 MessagePipe test_pipe1; |
| 265 MessagePipe test_pipe2; | 288 MessagePipe test_pipe2; |
| 266 MessagePipe test_pipe3; | 289 MessagePipe test_pipe3; |
| 267 CallbackHelper callback_helper1; | 290 CallbackHelper callback_helper1; |
| 268 CallbackHelper callback_helper2; | 291 CallbackHelper callback_helper2; |
| 269 CallbackHelper callback_helper3; | 292 CallbackHelper callback_helper3; |
| 270 ASSERT_TRUE(test_pipe1.handle0.is_valid()); | 293 ASSERT_TRUE(test_pipe1.handle0.is_valid()); |
| 271 ASSERT_TRUE(test_pipe2.handle0.is_valid()); | 294 ASSERT_TRUE(test_pipe2.handle0.is_valid()); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 294 | 317 |
| 295 HandleWatcher watcher3; | 318 HandleWatcher watcher3; |
| 296 callback_helper3.Start(&watcher3, test_pipe3.handle0.get()); | 319 callback_helper3.Start(&watcher3, test_pipe3.handle0.get()); |
| 297 | 320 |
| 298 callback_helper2.RunUntilGotCallback(); | 321 callback_helper2.RunUntilGotCallback(); |
| 299 EXPECT_FALSE(callback_helper1.got_callback()); | 322 EXPECT_FALSE(callback_helper1.got_callback()); |
| 300 EXPECT_TRUE(callback_helper2.got_callback()); | 323 EXPECT_TRUE(callback_helper2.got_callback()); |
| 301 EXPECT_FALSE(callback_helper3.got_callback()); | 324 EXPECT_FALSE(callback_helper3.got_callback()); |
| 302 } | 325 } |
| 303 | 326 |
| 304 TEST_F(HandleWatcherTest, DeleteInCallback) { | 327 TEST_P(HandleWatcherTest, DeleteInCallback) { |
| 305 MessagePipe test_pipe; | 328 MessagePipe test_pipe; |
| 306 CallbackHelper callback_helper; | 329 CallbackHelper callback_helper; |
| 307 | 330 |
| 308 HandleWatcher* watcher = new HandleWatcher(); | 331 HandleWatcher* watcher = new HandleWatcher(); |
| 309 callback_helper.StartWithCallback(watcher, test_pipe.handle1.get(), | 332 callback_helper.StartWithCallback(watcher, test_pipe.handle1.get(), |
| 310 base::Bind(&DeleteWatcherAndForwardResult, | 333 base::Bind(&DeleteWatcherAndForwardResult, |
| 311 watcher, | 334 watcher, |
| 312 callback_helper.GetCallback())); | 335 callback_helper.GetCallback())); |
| 313 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle0.get(), | 336 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle0.get(), |
| 314 std::string())); | 337 std::string())); |
| 315 callback_helper.RunUntilGotCallback(); | 338 callback_helper.RunUntilGotCallback(); |
| 316 EXPECT_TRUE(callback_helper.got_callback()); | 339 EXPECT_TRUE(callback_helper.got_callback()); |
| 317 } | 340 } |
| 318 | 341 |
| 319 TEST(HandleWatcherCleanEnvironmentTest, AbortedOnMessageLoopDestruction) { | 342 TEST_P(HandleWatcherTest, AbortedOnMessageLoopDestruction) { |
| 320 bool was_signaled = false; | 343 bool was_signaled = false; |
| 321 MojoResult result = MOJO_RESULT_OK; | 344 MojoResult result = MOJO_RESULT_OK; |
| 322 | 345 |
| 323 base::ShadowingAtExitManager at_exit; | |
| 324 MessagePipe pipe; | 346 MessagePipe pipe; |
| 325 HandleWatcher watcher; | 347 HandleWatcher watcher; |
| 326 { | 348 watcher.Start(pipe.handle0.get(), |
| 327 base::MessageLoop loop; | 349 MOJO_HANDLE_SIGNAL_READABLE, |
| 350 MOJO_DEADLINE_INDEFINITE, |
| 351 base::Bind(&ObserveCallback, &was_signaled, &result)); |
| 328 | 352 |
| 329 watcher.Start(pipe.handle0.get(), | 353 // Now, let the MessageLoop get torn down. We expect our callback to run. |
| 330 MOJO_HANDLE_SIGNAL_READABLE, | 354 TearDownMessageLoop(); |
| 331 MOJO_DEADLINE_INDEFINITE, | |
| 332 base::Bind(&ObserveCallback, &was_signaled, &result)); | |
| 333 | |
| 334 // Now, let the MessageLoop get torn down. We expect our callback to run. | |
| 335 } | |
| 336 | 355 |
| 337 EXPECT_TRUE(was_signaled); | 356 EXPECT_TRUE(was_signaled); |
| 338 EXPECT_EQ(MOJO_RESULT_ABORTED, result); | 357 EXPECT_EQ(MOJO_RESULT_ABORTED, result); |
| 339 } | 358 } |
| 340 | 359 |
| 341 void NeverReached(MojoResult result) { | 360 void NeverReached(MojoResult result) { |
| 342 FAIL() << "Callback should never be invoked " << result; | 361 FAIL() << "Callback should never be invoked " << result; |
| 343 } | 362 } |
| 344 | 363 |
| 345 // Called on the main thread when a thread is done. Decrements |active_count| | 364 // Called on the main thread when a thread is done. Decrements |active_count| |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 | 435 |
| 417 base::ShadowingAtExitManager at_exit; | 436 base::ShadowingAtExitManager at_exit; |
| 418 base::MessageLoop message_loop; | 437 base::MessageLoop message_loop; |
| 419 base::RunLoop run_loop; | 438 base::RunLoop run_loop; |
| 420 ScopedVector<base::Thread> threads; | 439 ScopedVector<base::Thread> threads; |
| 421 int threads_active_counter = kThreadCount; | 440 int threads_active_counter = kThreadCount; |
| 422 // Starts the threads first and then post the task in hopes of having more | 441 // Starts the threads first and then post the task in hopes of having more |
| 423 // threads running at once. | 442 // threads running at once. |
| 424 for (int i = 0; i < kThreadCount; ++i) { | 443 for (int i = 0; i < kThreadCount; ++i) { |
| 425 scoped_ptr<base::Thread> thread(new base::Thread("test thread")); | 444 scoped_ptr<base::Thread> thread(new base::Thread("test thread")); |
| 426 thread->Start(); | 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 } |
| 427 threads.push_back(thread.release()); | 453 threads.push_back(thread.release()); |
| 428 } | 454 } |
| 429 for (int i = 0; i < kThreadCount; ++i) { | 455 for (int i = 0; i < kThreadCount; ++i) { |
| 430 threads[i]->task_runner()->PostTask( | 456 threads[i]->task_runner()->PostTask( |
| 431 FROM_HERE, base::Bind(&RunStressTest, kWatchCount, | 457 FROM_HERE, base::Bind(&RunStressTest, kWatchCount, |
| 432 message_loop.task_runner(), | 458 message_loop.task_runner(), |
| 433 &run_loop, &threads_active_counter)); | 459 &run_loop, &threads_active_counter)); |
| 434 } | 460 } |
| 435 run_loop.Run(); | 461 run_loop.Run(); |
| 436 ASSERT_EQ(0, threads_active_counter); | 462 ASSERT_EQ(0, threads_active_counter); |
| 437 } | 463 } |
| 438 | 464 |
| 439 } // namespace test | 465 } // namespace test |
| 440 } // namespace common | 466 } // namespace common |
| 441 } // namespace mojo | 467 } // namespace mojo |
| OLD | NEW |