metronome_like_task_queue_test.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // Copyright 2022 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 "third_party/webrtc_overrides/test/metronome_like_task_queue_test.h"
  5. #include <functional>
  6. #include <memory>
  7. #include "base/time/time.h"
  8. #include "testing/gmock/include/gmock/gmock.h"
  9. #include "testing/gtest/include/gtest/gtest.h"
  10. #include "third_party/abseil-cpp/absl/functional/any_invocable.h"
  11. #include "third_party/webrtc/api/task_queue/task_queue_factory.h"
  12. namespace blink {
  13. using ::testing::ElementsAre;
  14. using ::testing::MockFunction;
  15. namespace {
  16. class MockCallback {
  17. public:
  18. MockCallback() {
  19. EXPECT_CALL(callback_, Call()).WillRepeatedly([&]() { ++callback_count_; });
  20. }
  21. size_t callback_count() const { return callback_count_; }
  22. bool was_called() const { return callback_count_ > 0; }
  23. absl::AnyInvocable<void() &&> ToTask() { return callback_.AsStdFunction(); }
  24. private:
  25. MockFunction<void()> callback_;
  26. size_t callback_count_ = 0;
  27. };
  28. webrtc::TimeDelta ToWebrtc(base::TimeDelta delta) {
  29. return webrtc::TimeDelta::Micros(delta.InMicroseconds());
  30. }
  31. } // namespace
  32. TEST_P(MetronomeLikeTaskQueueTest, PostTaskRunsPriorToTick) {
  33. auto* task_queue = provider_->TaskQueue();
  34. MockCallback callback;
  35. EXPECT_FALSE(callback.was_called());
  36. task_queue->PostTask(callback.ToTask());
  37. // The task environment uses multiple threads so it's possible for the
  38. // callback to be invoked as soon as we call PostTask(), but by advancing time
  39. // we ensure the task has had time to run.
  40. task_environment_.FastForwardBy(base::Nanoseconds(1));
  41. EXPECT_TRUE(callback.was_called());
  42. }
  43. TEST_P(MetronomeLikeTaskQueueTest, NormalPriorityDelayedTasksRunOnTicks) {
  44. auto* task_queue = provider_->TaskQueue();
  45. // Delay task until next tick.
  46. MockCallback callback;
  47. task_queue->PostDelayedTask(callback.ToTask(),
  48. ToWebrtc(provider_->MetronomeTick()));
  49. EXPECT_EQ(callback.callback_count(), 0u);
  50. task_environment_.FastForwardBy(provider_->MetronomeTick());
  51. EXPECT_EQ(callback.callback_count(), 1u);
  52. // Delay half a tick. A full tick must pass before it runs.
  53. task_queue->PostDelayedTask(callback.ToTask(),
  54. ToWebrtc(provider_->MetronomeTick() / 2));
  55. task_environment_.FastForwardBy(provider_->MetronomeTick() -
  56. base::Milliseconds(1));
  57. EXPECT_EQ(callback.callback_count(), 1u);
  58. task_environment_.FastForwardBy(base::Milliseconds(1));
  59. EXPECT_EQ(callback.callback_count(), 2u);
  60. // Delay several ticks.
  61. task_queue->PostDelayedTask(callback.ToTask(),
  62. ToWebrtc(provider_->MetronomeTick() * 3));
  63. task_environment_.FastForwardBy(provider_->MetronomeTick() * 2);
  64. EXPECT_EQ(callback.callback_count(), 2u);
  65. task_environment_.FastForwardBy(provider_->MetronomeTick());
  66. EXPECT_EQ(callback.callback_count(), 3u);
  67. }
  68. TEST_P(MetronomeLikeTaskQueueTest,
  69. NormalPriorityHighPrecisionDelayedTasksRunOutsideTicks) {
  70. auto* task_queue = provider_->TaskQueue();
  71. MockCallback callback;
  72. task_queue->PostDelayedHighPrecisionTask(callback.ToTask(),
  73. webrtc::TimeDelta::Millis(1));
  74. EXPECT_FALSE(callback.was_called());
  75. task_environment_.FastForwardBy(base::Milliseconds(1));
  76. EXPECT_TRUE(callback.was_called());
  77. }
  78. TEST_P(MetronomeLikeTaskQueueTest, DelayedTasksRunInOrder) {
  79. auto* task_queue = provider_->TaskQueue();
  80. constexpr webrtc::TimeDelta kTime0 = webrtc::TimeDelta::Millis(1);
  81. constexpr webrtc::TimeDelta kTime1 = webrtc::TimeDelta::Millis(2);
  82. std::vector<std::string> run_tasks;
  83. task_queue->PostDelayedTask(
  84. [&run_tasks]() { run_tasks.emplace_back("Time0_First"); }, kTime0);
  85. task_queue->PostDelayedTask(
  86. [&run_tasks]() { run_tasks.emplace_back("Time1_First"); }, kTime1);
  87. task_queue->PostDelayedTask(
  88. [&run_tasks]() { run_tasks.emplace_back("Time1_Second"); }, kTime1);
  89. task_queue->PostDelayedTask(
  90. [&run_tasks]() { run_tasks.emplace_back("Time0_Second"); }, kTime0);
  91. task_queue->PostDelayedTask(
  92. [&run_tasks]() { run_tasks.emplace_back("Time0_Third"); }, kTime0);
  93. task_queue->PostDelayedTask(
  94. [&run_tasks]() { run_tasks.emplace_back("Time1_Third"); }, kTime1);
  95. task_environment_.FastForwardBy(provider_->MetronomeTick());
  96. EXPECT_THAT(run_tasks,
  97. ElementsAre("Time0_First", "Time0_Second", "Time0_Third",
  98. "Time1_First", "Time1_Second", "Time1_Third"));
  99. }
  100. TEST_P(MetronomeLikeTaskQueueTest, DelayedTaskCanPostDelayedTask) {
  101. auto* task_queue = provider_->TaskQueue();
  102. bool task0_ran = false;
  103. bool task1_ran = false;
  104. task_queue->PostDelayedTask(
  105. [tick = provider_->MetronomeTick(), &task_queue, &task0_ran,
  106. &task1_ran]() {
  107. task0_ran = true;
  108. // Inception!
  109. task_queue->PostDelayedTask([&task1_ran]() { task1_ran = true; },
  110. ToWebrtc(tick));
  111. },
  112. ToWebrtc(provider_->MetronomeTick()));
  113. task_environment_.FastForwardBy(provider_->MetronomeTick());
  114. EXPECT_TRUE(task0_ran);
  115. EXPECT_FALSE(task1_ran);
  116. task_environment_.FastForwardBy(provider_->MetronomeTick());
  117. EXPECT_TRUE(task0_ran);
  118. EXPECT_TRUE(task1_ran);
  119. }
  120. } // namespace blink