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/run_loop.h" | 13 #include "base/run_loop.h" |
13 #include "base/test/simple_test_tick_clock.h" | 14 #include "base/test/simple_test_tick_clock.h" |
| 15 #include "base/threading/thread.h" |
14 #include "mojo/common/time_helper.h" | 16 #include "mojo/common/time_helper.h" |
15 #include "mojo/public/cpp/system/core.h" | 17 #include "mojo/public/cpp/system/core.h" |
16 #include "mojo/public/cpp/test_support/test_utils.h" | 18 #include "mojo/public/cpp/test_support/test_utils.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
18 | 20 |
19 namespace mojo { | 21 namespace mojo { |
20 namespace common { | 22 namespace common { |
21 namespace test { | 23 namespace test { |
22 | 24 |
23 void ObserveCallback(bool* was_signaled, | 25 void ObserveCallback(bool* was_signaled, |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 MOJO_DEADLINE_INDEFINITE, | 331 MOJO_DEADLINE_INDEFINITE, |
330 base::Bind(&ObserveCallback, &was_signaled, &result)); | 332 base::Bind(&ObserveCallback, &was_signaled, &result)); |
331 | 333 |
332 // Now, let the MessageLoop get torn down. We expect our callback to run. | 334 // Now, let the MessageLoop get torn down. We expect our callback to run. |
333 } | 335 } |
334 | 336 |
335 EXPECT_TRUE(was_signaled); | 337 EXPECT_TRUE(was_signaled); |
336 EXPECT_EQ(MOJO_RESULT_ABORTED, result); | 338 EXPECT_EQ(MOJO_RESULT_ABORTED, result); |
337 } | 339 } |
338 | 340 |
| 341 void NeverReached(MojoResult result) { |
| 342 FAIL() << "Callback should never be invoked " << result; |
| 343 } |
| 344 |
| 345 // Called on the main thread when a thread is done. Decrements |active_count| |
| 346 // and if |active_count| is zero quits |run_loop|. |
| 347 void StressThreadDone(base::RunLoop* run_loop, int* active_count) { |
| 348 (*active_count)--; |
| 349 EXPECT_GE(*active_count, 0); |
| 350 if (*active_count == 0) |
| 351 run_loop->Quit(); |
| 352 } |
| 353 |
| 354 // See description of StressTest. This is called on the background thread. |
| 355 // |count| is the number of HandleWatchers to create. |active_count| is the |
| 356 // number of outstanding threads, |task_runner| the task runner for the main |
| 357 // thread and |run_loop| the run loop that should be quit when there are no more |
| 358 // threads running. When done StressThreadDone() is invoked on the main thread. |
| 359 // |active_count| and |run_loop| should only be used on the main thread. |
| 360 void RunStressTest(int count, |
| 361 scoped_refptr<base::TaskRunner> task_runner, |
| 362 base::RunLoop* run_loop, |
| 363 int* active_count) { |
| 364 struct TestData { |
| 365 MessagePipe pipe; |
| 366 HandleWatcher watcher; |
| 367 }; |
| 368 ScopedVector<TestData> data_vector; |
| 369 for (int i = 0; i < count; ++i) { |
| 370 if (i % 20 == 0) { |
| 371 // Every so often we wait. This results in some level of thread balancing |
| 372 // as well as making sure HandleWatcher has time to actually start some |
| 373 // watches. |
| 374 MessagePipe test_pipe; |
| 375 ASSERT_TRUE(test_pipe.handle0.is_valid()); |
| 376 CallbackHelper callback_helper; |
| 377 HandleWatcher watcher; |
| 378 callback_helper.Start(&watcher, test_pipe.handle0.get()); |
| 379 RunUntilIdle(); |
| 380 EXPECT_FALSE(callback_helper.got_callback()); |
| 381 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle1.get(), |
| 382 std::string())); |
| 383 base::MessageLoop::ScopedNestableTaskAllower scoper( |
| 384 base::MessageLoop::current()); |
| 385 callback_helper.RunUntilGotCallback(); |
| 386 EXPECT_TRUE(callback_helper.got_callback()); |
| 387 } else { |
| 388 scoped_ptr<TestData> test_data(new TestData); |
| 389 ASSERT_TRUE(test_data->pipe.handle0.is_valid()); |
| 390 test_data->watcher.Start(test_data->pipe.handle0.get(), |
| 391 MOJO_HANDLE_SIGNAL_READABLE, |
| 392 MOJO_DEADLINE_INDEFINITE, |
| 393 base::Bind(&NeverReached)); |
| 394 data_vector.push_back(test_data.release()); |
| 395 } |
| 396 if (i % 15 == 0) |
| 397 data_vector.clear(); |
| 398 } |
| 399 task_runner->PostTask(FROM_HERE, |
| 400 base::Bind(&StressThreadDone, run_loop, |
| 401 active_count)); |
| 402 } |
| 403 |
| 404 // This test is meant to stress HandleWatcher. It uses from various threads |
| 405 // repeatedly starting and stopping watches. It spins up kThreadCount |
| 406 // threads. Each thread creates kWatchCount watches. Every so often each thread |
| 407 // writes to a pipe and waits for the response. |
| 408 TEST(HandleWatcherCleanEnvironmentTest, StressTest) { |
| 409 #if defined(NDEBUG) |
| 410 const int kThreadCount = 15; |
| 411 const int kWatchCount = 400; |
| 412 #else |
| 413 const int kThreadCount = 10; |
| 414 const int kWatchCount = 250; |
| 415 #endif |
| 416 |
| 417 base::ShadowingAtExitManager at_exit; |
| 418 base::MessageLoop message_loop; |
| 419 base::RunLoop run_loop; |
| 420 ScopedVector<base::Thread> threads; |
| 421 int threads_active_counter = kThreadCount; |
| 422 // Starts the threads first and then post the task in hopes of having more |
| 423 // threads running at once. |
| 424 for (int i = 0; i < kThreadCount; ++i) { |
| 425 scoped_ptr<base::Thread> thread(new base::Thread("test thread")); |
| 426 thread->Start(); |
| 427 threads.push_back(thread.release()); |
| 428 } |
| 429 for (int i = 0; i < kThreadCount; ++i) { |
| 430 threads[i]->task_runner()->PostTask( |
| 431 FROM_HERE, base::Bind(&RunStressTest, kWatchCount, |
| 432 message_loop.task_runner(), |
| 433 &run_loop, &threads_active_counter)); |
| 434 } |
| 435 run_loop.Run(); |
| 436 ASSERT_EQ(0, threads_active_counter); |
| 437 } |
| 438 |
339 } // namespace test | 439 } // namespace test |
340 } // namespace common | 440 } // namespace common |
341 } // namespace mojo | 441 } // namespace mojo |
OLD | NEW |