delayed_task_handle_unittest.cc 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. // Copyright 2021 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/task/delayed_task_handle.h"
  5. #include "base/memory/raw_ptr.h"
  6. #include "base/test/gtest_util.h"
  7. #include "testing/gtest/include/gtest/gtest.h"
  8. namespace base {
  9. namespace {
  10. // A non-working delegate that allows the testing of DelayedTaskHandle.
  11. class TestDelegate : public DelayedTaskHandle::Delegate {
  12. public:
  13. explicit TestDelegate(bool* was_cancel_task_called = nullptr)
  14. : was_cancel_task_called_(was_cancel_task_called) {
  15. DCHECK(!was_cancel_task_called_ || !*was_cancel_task_called_);
  16. }
  17. ~TestDelegate() override = default;
  18. bool IsValid() const override { return is_valid_; }
  19. void CancelTask() override {
  20. is_valid_ = false;
  21. if (was_cancel_task_called_)
  22. *was_cancel_task_called_ = true;
  23. }
  24. private:
  25. // Indicates if this delegate is currently valid.
  26. bool is_valid_ = true;
  27. // Indicates if CancelTask() was invoked, if not null. Must outlives |this|.
  28. raw_ptr<bool> was_cancel_task_called_;
  29. };
  30. } // namespace
  31. // Tests that a default-constructed handle is invalid.
  32. TEST(DelayedTaskHandleTest, DefaultConstructor) {
  33. DelayedTaskHandle delayed_task_handle;
  34. EXPECT_FALSE(delayed_task_handle.IsValid());
  35. }
  36. // Tests that creating a handle with an invalid delegate will DCHECK.
  37. TEST(DelayedTaskHandleTest, RequiresValidDelegateOnConstruction) {
  38. auto delegate = std::make_unique<TestDelegate>();
  39. EXPECT_TRUE(delegate->IsValid());
  40. // Invalidate the delegate before creating the handle.
  41. delegate->CancelTask();
  42. EXPECT_FALSE(delegate->IsValid());
  43. EXPECT_DCHECK_DEATH(
  44. { DelayedTaskHandle delayed_task_handle(std::move(delegate)); });
  45. }
  46. // Tests that calling CancelTask() on the handle will call CancelTask() on the
  47. // delegate and invalidate it.
  48. TEST(DelayedTaskHandleTest, CancelTask) {
  49. bool was_cancel_task_called = false;
  50. auto delegate = std::make_unique<TestDelegate>(&was_cancel_task_called);
  51. EXPECT_FALSE(was_cancel_task_called);
  52. EXPECT_TRUE(delegate->IsValid());
  53. auto* delegate_ptr = delegate.get();
  54. DelayedTaskHandle delayed_task_handle(std::move(delegate));
  55. EXPECT_FALSE(was_cancel_task_called);
  56. EXPECT_TRUE(delegate_ptr->IsValid());
  57. EXPECT_TRUE(delayed_task_handle.IsValid());
  58. delayed_task_handle.CancelTask();
  59. EXPECT_TRUE(was_cancel_task_called);
  60. EXPECT_FALSE(delayed_task_handle.IsValid());
  61. }
  62. // Tests that calling CancelTask() on a handle with no delegate will no-op.
  63. TEST(DelayedTaskHandleTest, CancelTaskNoDelegate) {
  64. DelayedTaskHandle delayed_task_handle;
  65. EXPECT_FALSE(delayed_task_handle.IsValid());
  66. delayed_task_handle.CancelTask();
  67. EXPECT_FALSE(delayed_task_handle.IsValid());
  68. }
  69. // Tests that calling CancelTask() on a handle with an invalid delegate doesn't
  70. // crash and keeps the handle invalid.
  71. TEST(DelayedTaskHandleTest, CancelTaskInvalidDelegate) {
  72. bool was_cancel_task_called = false;
  73. auto delegate = std::make_unique<TestDelegate>(&was_cancel_task_called);
  74. EXPECT_FALSE(was_cancel_task_called);
  75. EXPECT_TRUE(delegate->IsValid());
  76. auto* delegate_ptr = delegate.get();
  77. DelayedTaskHandle delayed_task_handle(std::move(delegate));
  78. EXPECT_FALSE(was_cancel_task_called);
  79. EXPECT_TRUE(delegate_ptr->IsValid());
  80. EXPECT_TRUE(delayed_task_handle.IsValid());
  81. delegate_ptr->CancelTask();
  82. EXPECT_TRUE(was_cancel_task_called);
  83. EXPECT_FALSE(delegate_ptr->IsValid());
  84. EXPECT_FALSE(delayed_task_handle.IsValid());
  85. // Reset |was_cancel_task_called| to ensure Delegate::CancelTask() is still
  86. // invoked on an invalid delegate.
  87. was_cancel_task_called = false;
  88. delayed_task_handle.CancelTask();
  89. EXPECT_TRUE(was_cancel_task_called);
  90. EXPECT_FALSE(delayed_task_handle.IsValid());
  91. }
  92. // Tests that invalidating the delegate will also invalidate the handle.
  93. TEST(DelayedTaskHandleTest, InvalidateDelegate) {
  94. auto delegate = std::make_unique<TestDelegate>();
  95. EXPECT_TRUE(delegate->IsValid());
  96. auto* delegate_ptr = delegate.get();
  97. DelayedTaskHandle delayed_task_handle(std::move(delegate));
  98. EXPECT_TRUE(delegate_ptr->IsValid());
  99. EXPECT_TRUE(delayed_task_handle.IsValid());
  100. delegate_ptr->CancelTask();
  101. EXPECT_FALSE(delegate_ptr->IsValid());
  102. EXPECT_FALSE(delayed_task_handle.IsValid());
  103. }
  104. // Tests that destroying a valid handle will DCHECK.
  105. TEST(DelayedTaskHandleTest, InvalidOnDestuction) {
  106. auto delegate = std::make_unique<TestDelegate>();
  107. EXPECT_TRUE(delegate->IsValid());
  108. auto* delegate_ptr = delegate.get();
  109. EXPECT_DCHECK_DEATH({
  110. DelayedTaskHandle delayed_task_handle(std::move(delegate));
  111. EXPECT_TRUE(delegate_ptr->IsValid());
  112. EXPECT_TRUE(delayed_task_handle.IsValid());
  113. });
  114. }
  115. // Tests the move-constructor.
  116. TEST(DelayedTaskHandleTest, MoveConstructor) {
  117. auto delegate = std::make_unique<TestDelegate>();
  118. EXPECT_TRUE(delegate->IsValid());
  119. auto* delegate_ptr = delegate.get();
  120. DelayedTaskHandle delayed_task_handle(std::move(delegate));
  121. EXPECT_TRUE(delegate_ptr->IsValid());
  122. EXPECT_TRUE(delayed_task_handle.IsValid());
  123. DelayedTaskHandle other_delayed_task_handle(std::move(delayed_task_handle));
  124. EXPECT_TRUE(delegate_ptr->IsValid());
  125. EXPECT_TRUE(other_delayed_task_handle.IsValid());
  126. // Clean-up.
  127. other_delayed_task_handle.CancelTask();
  128. }
  129. // Tests the move-assignment.
  130. TEST(DelayedTaskHandleTest, MoveAssignment) {
  131. auto delegate = std::make_unique<TestDelegate>();
  132. EXPECT_TRUE(delegate->IsValid());
  133. auto* delegate_ptr = delegate.get();
  134. DelayedTaskHandle delayed_task_handle(std::move(delegate));
  135. EXPECT_TRUE(delegate_ptr->IsValid());
  136. EXPECT_TRUE(delayed_task_handle.IsValid());
  137. DelayedTaskHandle other_delayed_task_handle;
  138. EXPECT_FALSE(other_delayed_task_handle.IsValid());
  139. other_delayed_task_handle = std::move(delayed_task_handle);
  140. EXPECT_TRUE(delegate_ptr->IsValid());
  141. EXPECT_TRUE(other_delayed_task_handle.IsValid());
  142. // Clean-up.
  143. other_delayed_task_handle.CancelTask();
  144. }
  145. // Tests that assigning to a valid handle will DCHECK.
  146. TEST(DelayedTaskHandleTest, AssignToValidHandle) {
  147. auto delegate = std::make_unique<TestDelegate>();
  148. EXPECT_TRUE(delegate->IsValid());
  149. auto* delegate_ptr = delegate.get();
  150. DelayedTaskHandle delayed_task_handle(std::move(delegate));
  151. EXPECT_TRUE(delegate_ptr->IsValid());
  152. EXPECT_TRUE(delayed_task_handle.IsValid());
  153. EXPECT_DCHECK_DEATH({ delayed_task_handle = DelayedTaskHandle(); });
  154. // Clean-up.
  155. delayed_task_handle.CancelTask();
  156. }
  157. } // namespace base