java_handler_thread_unittest.cc 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // Copyright 2019 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.
  4. #include "base/android/java_handler_thread.h"
  5. #include "base/synchronization/waitable_event.h"
  6. #include "base/task/sequence_manager/sequence_manager_impl.h"
  7. #include "base/task/task_observer.h"
  8. #include "base/test/android/java_handler_thread_helpers.h"
  9. #include "base/test/bind.h"
  10. #include "testing/gtest/include/gtest/gtest.h"
  11. namespace base {
  12. namespace {
  13. class JavaHandlerThreadForTest : public android::JavaHandlerThread {
  14. public:
  15. explicit JavaHandlerThreadForTest(
  16. const char* name,
  17. base::ThreadType thread_type = base::ThreadType::kDefault)
  18. : android::JavaHandlerThread(name, thread_type) {}
  19. using android::JavaHandlerThread::state;
  20. using android::JavaHandlerThread::State;
  21. };
  22. class DummyTaskObserver : public TaskObserver {
  23. public:
  24. explicit DummyTaskObserver(int num_tasks)
  25. : num_tasks_started_(0), num_tasks_processed_(0), num_tasks_(num_tasks) {}
  26. DummyTaskObserver(int num_tasks, int num_tasks_started)
  27. : num_tasks_started_(num_tasks_started),
  28. num_tasks_processed_(0),
  29. num_tasks_(num_tasks) {}
  30. DummyTaskObserver(const DummyTaskObserver&) = delete;
  31. DummyTaskObserver& operator=(const DummyTaskObserver&) = delete;
  32. ~DummyTaskObserver() override = default;
  33. void WillProcessTask(const PendingTask& /* pending_task */,
  34. bool /* was_blocked_or_low_priority */) override {
  35. num_tasks_started_++;
  36. EXPECT_LE(num_tasks_started_, num_tasks_);
  37. EXPECT_EQ(num_tasks_started_, num_tasks_processed_ + 1);
  38. }
  39. void DidProcessTask(const PendingTask& pending_task) override {
  40. num_tasks_processed_++;
  41. EXPECT_LE(num_tasks_started_, num_tasks_);
  42. EXPECT_EQ(num_tasks_started_, num_tasks_processed_);
  43. }
  44. int num_tasks_started() const { return num_tasks_started_; }
  45. int num_tasks_processed() const { return num_tasks_processed_; }
  46. private:
  47. int num_tasks_started_;
  48. int num_tasks_processed_;
  49. const int num_tasks_;
  50. };
  51. void PostNTasks(int posts_remaining) {
  52. if (posts_remaining > 1) {
  53. ThreadTaskRunnerHandle::Get()->PostTask(
  54. FROM_HERE, BindOnce(&PostNTasks, posts_remaining - 1));
  55. }
  56. }
  57. } // namespace
  58. class JavaHandlerThreadTest : public ::testing::Test {};
  59. void RunTest_AbortDontRunMoreTasks(bool delayed, bool init_java_first) {
  60. WaitableEvent test_done_event;
  61. std::unique_ptr<android::JavaHandlerThread> java_thread;
  62. if (init_java_first) {
  63. java_thread = android::JavaHandlerThreadHelpers::CreateJavaFirst();
  64. } else {
  65. java_thread = std::make_unique<android::JavaHandlerThread>(
  66. "JavaHandlerThreadForTesting from AbortDontRunMoreTasks");
  67. }
  68. java_thread->Start();
  69. java_thread->ListenForUncaughtExceptionsForTesting();
  70. auto target =
  71. BindOnce(&android::JavaHandlerThreadHelpers::ThrowExceptionAndAbort,
  72. &test_done_event);
  73. if (delayed) {
  74. java_thread->task_runner()->PostDelayedTask(FROM_HERE, std::move(target),
  75. Milliseconds(10));
  76. } else {
  77. java_thread->task_runner()->PostTask(FROM_HERE, std::move(target));
  78. java_thread->task_runner()->PostTask(FROM_HERE,
  79. MakeExpectedNotRunClosure(FROM_HERE));
  80. }
  81. test_done_event.Wait();
  82. java_thread->Stop();
  83. android::ScopedJavaLocalRef<jthrowable> exception =
  84. java_thread->GetUncaughtExceptionIfAny();
  85. ASSERT_TRUE(
  86. android::JavaHandlerThreadHelpers::IsExceptionTestException(exception));
  87. }
  88. TEST_F(JavaHandlerThreadTest, JavaExceptionAbort) {
  89. constexpr bool delayed = false;
  90. constexpr bool init_java_first = false;
  91. RunTest_AbortDontRunMoreTasks(delayed, init_java_first);
  92. }
  93. TEST_F(JavaHandlerThreadTest, DelayedJavaExceptionAbort) {
  94. constexpr bool delayed = true;
  95. constexpr bool init_java_first = false;
  96. RunTest_AbortDontRunMoreTasks(delayed, init_java_first);
  97. }
  98. TEST_F(JavaHandlerThreadTest, JavaExceptionAbortInitJavaFirst) {
  99. constexpr bool delayed = false;
  100. constexpr bool init_java_first = true;
  101. RunTest_AbortDontRunMoreTasks(delayed, init_java_first);
  102. }
  103. TEST_F(JavaHandlerThreadTest, RunTasksWhileShuttingDownJavaThread) {
  104. const int kNumPosts = 6;
  105. DummyTaskObserver observer(kNumPosts, 1);
  106. auto java_thread = std::make_unique<JavaHandlerThreadForTest>("test");
  107. java_thread->Start();
  108. sequence_manager::internal::SequenceManagerImpl* sequence_manager =
  109. static_cast<sequence_manager::internal::SequenceManagerImpl*>(
  110. java_thread->state()->sequence_manager.get());
  111. java_thread->task_runner()->PostTask(
  112. FROM_HERE, BindLambdaForTesting([&]() {
  113. sequence_manager->AddTaskObserver(&observer);
  114. ThreadTaskRunnerHandle::Get()->PostDelayedTask(
  115. FROM_HERE, MakeExpectedNotRunClosure(FROM_HERE), Days(1));
  116. java_thread->StopSequenceManagerForTesting();
  117. PostNTasks(kNumPosts);
  118. }));
  119. java_thread->JoinForTesting();
  120. java_thread.reset();
  121. EXPECT_EQ(kNumPosts, observer.num_tasks_started());
  122. EXPECT_EQ(kNumPosts, observer.num_tasks_processed());
  123. }
  124. } // namespace base