xref: /aosp_15_r20/external/cronet/base/task/sequence_manager/wake_up_queue_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/task/sequence_manager/wake_up_queue.h"
6 
7 #include <memory>
8 #include <optional>
9 
10 #include "base/memory/ptr_util.h"
11 #include "base/message_loop/message_pump.h"
12 #include "base/message_loop/message_pump_type.h"
13 #include "base/task/sequence_manager/enqueue_order.h"
14 #include "base/task/sequence_manager/sequence_manager_impl.h"
15 #include "base/task/sequence_manager/task_queue_impl.h"
16 #include "base/test/mock_callback.h"
17 #include "base/test/simple_test_tick_clock.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 
20 using testing::_;
21 using testing::AnyNumber;
22 using testing::Mock;
23 
24 namespace base {
25 namespace sequence_manager {
26 namespace internal {
27 
28 class TaskQueueImplForTest : public internal::TaskQueueImpl {
29  public:
TaskQueueImplForTest(internal::SequenceManagerImpl * sequence_manager,WakeUpQueue * wake_up_queue,const TaskQueue::Spec & spec)30   TaskQueueImplForTest(internal::SequenceManagerImpl* sequence_manager,
31                        WakeUpQueue* wake_up_queue,
32                        const TaskQueue::Spec& spec)
33       : TaskQueueImpl(sequence_manager, wake_up_queue, spec) {}
34   ~TaskQueueImplForTest() override = default;
35 
36   using TaskQueueImpl::SetNextWakeUp;
37 };
38 
39 class MockWakeUpQueue : public WakeUpQueue {
40  public:
MockWakeUpQueue()41   MockWakeUpQueue()
42       : WakeUpQueue(internal::AssociatedThreadId::CreateBound()) {}
43 
44   MockWakeUpQueue(const MockWakeUpQueue&) = delete;
45   MockWakeUpQueue& operator=(const MockWakeUpQueue&) = delete;
46   ~MockWakeUpQueue() override = default;
47 
48   using WakeUpQueue::MoveReadyDelayedTasksToWorkQueues;
49   using WakeUpQueue::SetNextWakeUpForQueue;
50   using WakeUpQueue::UnregisterQueue;
51 
OnNextWakeUpChanged(LazyNow * lazy_now,std::optional<WakeUp> wake_up)52   void OnNextWakeUpChanged(LazyNow* lazy_now,
53                            std::optional<WakeUp> wake_up) override {
54     TimeTicks time = wake_up ? wake_up->time : TimeTicks::Max();
55     OnNextWakeUpChanged_TimeTicks(time);
56   }
GetName() const57   const char* GetName() const override { return "Test"; }
UnregisterQueue(internal::TaskQueueImpl * queue)58   void UnregisterQueue(internal::TaskQueueImpl* queue) override {
59     SetNextWakeUpForQueue(queue, nullptr, std::nullopt);
60   }
61 
NextScheduledTaskQueue() const62   internal::TaskQueueImpl* NextScheduledTaskQueue() const {
63     if (wake_up_queue_.empty())
64       return nullptr;
65     return wake_up_queue_.top().queue;
66   }
67 
NextScheduledRunTime() const68   TimeTicks NextScheduledRunTime() const {
69     if (wake_up_queue_.empty())
70       return TimeTicks::Max();
71     return wake_up_queue_.top().wake_up.time;
72   }
73 
74   MOCK_METHOD1(OnNextWakeUpChanged_TimeTicks, void(TimeTicks time));
75 };
76 
77 class WakeUpQueueTest : public testing::Test {
78  public:
SetUp()79   void SetUp() final {
80     // A null clock triggers some assertions.
81     tick_clock_.Advance(Milliseconds(1));
82     wake_up_queue_ = std::make_unique<MockWakeUpQueue>();
83     task_queue_ = std::make_unique<TaskQueueImplForTest>(
84         nullptr, wake_up_queue_.get(), TaskQueue::Spec(QueueName::TEST_TQ));
85   }
86 
TearDown()87   void TearDown() final {
88     if (task_queue_)
89       task_queue_->UnregisterTaskQueue();
90   }
91 
92   std::unique_ptr<MockWakeUpQueue> wake_up_queue_;
93   std::unique_ptr<TaskQueueImplForTest> task_queue_;
94   SimpleTestTickClock tick_clock_;
95 };
96 
TEST_F(WakeUpQueueTest,ScheduleWakeUpForQueue)97 TEST_F(WakeUpQueueTest, ScheduleWakeUpForQueue) {
98   TimeTicks now = tick_clock_.NowTicks();
99   TimeDelta delay = Milliseconds(10);
100   TimeTicks delayed_runtime = now + delay;
101   EXPECT_TRUE(wake_up_queue_->empty());
102   EXPECT_CALL(*wake_up_queue_.get(),
103               OnNextWakeUpChanged_TimeTicks(delayed_runtime));
104   LazyNow lazy_now(now);
105   task_queue_->SetNextWakeUp(&lazy_now, WakeUp{delayed_runtime});
106 
107   EXPECT_FALSE(wake_up_queue_->empty());
108   EXPECT_EQ(delayed_runtime, wake_up_queue_->NextScheduledRunTime());
109 
110   EXPECT_EQ(task_queue_.get(), wake_up_queue_->NextScheduledTaskQueue());
111   Mock::VerifyAndClearExpectations(wake_up_queue_.get());
112 
113   EXPECT_CALL(*wake_up_queue_.get(),
114               OnNextWakeUpChanged_TimeTicks(TimeTicks::Max()))
115       .Times(AnyNumber());
116 }
117 
TEST_F(WakeUpQueueTest,ScheduleWakeUpForQueueSupersedesPreviousWakeUp)118 TEST_F(WakeUpQueueTest, ScheduleWakeUpForQueueSupersedesPreviousWakeUp) {
119   TimeTicks now = tick_clock_.NowTicks();
120   TimeDelta delay1 = Milliseconds(10);
121   TimeDelta delay2 = Milliseconds(100);
122   TimeTicks delayed_runtime1 = now + delay1;
123   TimeTicks delayed_runtime2 = now + delay2;
124   EXPECT_CALL(*wake_up_queue_.get(),
125               OnNextWakeUpChanged_TimeTicks(delayed_runtime1));
126   LazyNow lazy_now(now);
127   task_queue_->SetNextWakeUp(&lazy_now, WakeUp{delayed_runtime1});
128 
129   EXPECT_EQ(delayed_runtime1, wake_up_queue_->NextScheduledRunTime());
130 
131   Mock::VerifyAndClearExpectations(wake_up_queue_.get());
132 
133   // Now schedule a later wake_up, which should replace the previously
134   // requested one.
135   EXPECT_CALL(*wake_up_queue_.get(),
136               OnNextWakeUpChanged_TimeTicks(delayed_runtime2));
137   task_queue_->SetNextWakeUp(&lazy_now, WakeUp{delayed_runtime2});
138 
139   EXPECT_EQ(delayed_runtime2, wake_up_queue_->NextScheduledRunTime());
140   Mock::VerifyAndClearExpectations(wake_up_queue_.get());
141 
142   EXPECT_CALL(*wake_up_queue_.get(),
143               OnNextWakeUpChanged_TimeTicks(TimeTicks::Max()))
144       .Times(AnyNumber());
145 }
146 
TEST_F(WakeUpQueueTest,ScheduleFlexibleNoSoonerWakeUpForQueueSupersedesPreviousWakeUpWithLeeway)147 TEST_F(
148     WakeUpQueueTest,
149     ScheduleFlexibleNoSoonerWakeUpForQueueSupersedesPreviousWakeUpWithLeeway) {
150   TimeTicks now = tick_clock_.NowTicks();
151   TimeDelta delay1 = Milliseconds(10);
152   TimeDelta delay2 = Milliseconds(15);
153   TimeTicks delayed_runtime1 = now + delay1;
154   TimeTicks delayed_runtime2 = now + delay2;
155   EXPECT_CALL(*wake_up_queue_.get(),
156               OnNextWakeUpChanged_TimeTicks(delayed_runtime1));
157   LazyNow lazy_now(now);
158   task_queue_->SetNextWakeUp(
159       &lazy_now,
160       WakeUp{delayed_runtime1, Milliseconds(10), WakeUpResolution::kLow,
161              subtle::DelayPolicy::kFlexibleNoSooner});
162 
163   EXPECT_EQ((WakeUp{delayed_runtime1, Milliseconds(10), WakeUpResolution::kLow,
164                     subtle::DelayPolicy::kFlexibleNoSooner}),
165             wake_up_queue_->GetNextDelayedWakeUp());
166 
167   Mock::VerifyAndClearExpectations(wake_up_queue_.get());
168 
169   // Now schedule a later wake_up, which should replace the previously
170   // requested one.
171   EXPECT_CALL(*wake_up_queue_.get(),
172               OnNextWakeUpChanged_TimeTicks(delayed_runtime2));
173   task_queue_->SetNextWakeUp(
174       &lazy_now, WakeUp{delayed_runtime2, TimeDelta(), WakeUpResolution::kLow,
175                         subtle::DelayPolicy::kPrecise});
176 
177   EXPECT_EQ((WakeUp{delayed_runtime2, TimeDelta(), WakeUpResolution::kLow,
178                     subtle::DelayPolicy::kPrecise}),
179             wake_up_queue_->GetNextDelayedWakeUp());
180   Mock::VerifyAndClearExpectations(wake_up_queue_.get());
181 
182   EXPECT_CALL(*wake_up_queue_.get(),
183               OnNextWakeUpChanged_TimeTicks(TimeTicks::Max()))
184       .Times(AnyNumber());
185 }
186 
TEST_F(WakeUpQueueTest,ScheduleFlexiblePreferEarlyWakeUpForQueueSupersedesPreviousWakeUp)187 TEST_F(WakeUpQueueTest,
188        ScheduleFlexiblePreferEarlyWakeUpForQueueSupersedesPreviousWakeUp) {
189   TimeTicks now = tick_clock_.NowTicks();
190   TimeDelta delay1 = Milliseconds(10);
191   TimeDelta delay2 = Milliseconds(15);
192   TimeTicks delayed_runtime1 = now + delay1;
193   TimeTicks delayed_runtime2 = now + delay2;
194   EXPECT_CALL(*wake_up_queue_.get(),
195               OnNextWakeUpChanged_TimeTicks(delayed_runtime1));
196   LazyNow lazy_now(now);
197   task_queue_->SetNextWakeUp(
198       &lazy_now, WakeUp{delayed_runtime1, TimeDelta(), WakeUpResolution::kLow,
199                         subtle::DelayPolicy::kPrecise});
200 
201   EXPECT_EQ((WakeUp{delayed_runtime1, TimeDelta(), WakeUpResolution::kLow,
202                     subtle::DelayPolicy::kPrecise}),
203             wake_up_queue_->GetNextDelayedWakeUp());
204 
205   Mock::VerifyAndClearExpectations(wake_up_queue_.get());
206 
207   // Now schedule a later wake_up, which should replace the previously
208   // requested one.
209   EXPECT_CALL(*wake_up_queue_.get(),
210               OnNextWakeUpChanged_TimeTicks(delayed_runtime2));
211   task_queue_->SetNextWakeUp(
212       &lazy_now,
213       WakeUp{delayed_runtime2, Milliseconds(10), WakeUpResolution::kLow,
214              subtle::DelayPolicy::kFlexiblePreferEarly});
215 
216   EXPECT_EQ((WakeUp{delayed_runtime2, Milliseconds(10), WakeUpResolution::kLow,
217                     subtle::DelayPolicy::kFlexiblePreferEarly}),
218             wake_up_queue_->GetNextDelayedWakeUp());
219   Mock::VerifyAndClearExpectations(wake_up_queue_.get());
220 
221   EXPECT_CALL(*wake_up_queue_.get(),
222               OnNextWakeUpChanged_TimeTicks(TimeTicks::Max()))
223       .Times(AnyNumber());
224 }
225 
TEST_F(WakeUpQueueTest,SetNextDelayedDoWork_OnlyCalledForEarlierTasks)226 TEST_F(WakeUpQueueTest, SetNextDelayedDoWork_OnlyCalledForEarlierTasks) {
227   std::unique_ptr<TaskQueueImplForTest> task_queue2 =
228       std::make_unique<TaskQueueImplForTest>(
229           nullptr, wake_up_queue_.get(), TaskQueue::Spec(QueueName::TEST_TQ));
230 
231   std::unique_ptr<TaskQueueImplForTest> task_queue3 =
232       std::make_unique<TaskQueueImplForTest>(
233           nullptr, wake_up_queue_.get(), TaskQueue::Spec(QueueName::TEST_TQ));
234 
235   std::unique_ptr<TaskQueueImplForTest> task_queue4 =
236       std::make_unique<TaskQueueImplForTest>(
237           nullptr, wake_up_queue_.get(), TaskQueue::Spec(QueueName::TEST_TQ));
238 
239   TimeDelta delay1 = Milliseconds(10);
240   TimeDelta delay2 = Milliseconds(20);
241   TimeDelta delay3 = Milliseconds(30);
242   TimeDelta delay4 = Milliseconds(1);
243 
244   // SetNextDelayedDoWork should always be called if there are no other
245   // wake-ups.
246   TimeTicks now = tick_clock_.NowTicks();
247   LazyNow lazy_now(now);
248   EXPECT_CALL(*wake_up_queue_.get(),
249               OnNextWakeUpChanged_TimeTicks(now + delay1));
250   task_queue_->SetNextWakeUp(&lazy_now, WakeUp{now + delay1});
251 
252   Mock::VerifyAndClearExpectations(wake_up_queue_.get());
253 
254   // SetNextDelayedDoWork should not be called when scheduling later tasks.
255   EXPECT_CALL(*wake_up_queue_.get(), OnNextWakeUpChanged_TimeTicks(_)).Times(0);
256   task_queue2->SetNextWakeUp(&lazy_now, WakeUp{now + delay2});
257   task_queue3->SetNextWakeUp(&lazy_now, WakeUp{now + delay3});
258 
259   // SetNextDelayedDoWork should be called when scheduling earlier tasks.
260   Mock::VerifyAndClearExpectations(wake_up_queue_.get());
261   EXPECT_CALL(*wake_up_queue_.get(),
262               OnNextWakeUpChanged_TimeTicks(now + delay4));
263   task_queue4->SetNextWakeUp(&lazy_now, WakeUp{now + delay4});
264 
265   Mock::VerifyAndClearExpectations(wake_up_queue_.get());
266 
267   EXPECT_CALL(*wake_up_queue_.get(), OnNextWakeUpChanged_TimeTicks(_)).Times(2);
268   task_queue2->UnregisterTaskQueue();
269   task_queue3->UnregisterTaskQueue();
270   task_queue4->UnregisterTaskQueue();
271 }
272 
TEST_F(WakeUpQueueTest,UnregisterQueue)273 TEST_F(WakeUpQueueTest, UnregisterQueue) {
274   std::unique_ptr<TaskQueueImplForTest> task_queue2 =
275       std::make_unique<TaskQueueImplForTest>(
276           nullptr, wake_up_queue_.get(), TaskQueue::Spec(QueueName::TEST_TQ));
277   EXPECT_TRUE(wake_up_queue_->empty());
278 
279   TimeTicks now = tick_clock_.NowTicks();
280   LazyNow lazy_now(now);
281   TimeTicks wake_up1 = now + Milliseconds(10);
282   EXPECT_CALL(*wake_up_queue_.get(), OnNextWakeUpChanged_TimeTicks(wake_up1))
283       .Times(1);
284   task_queue_->SetNextWakeUp(&lazy_now, WakeUp{wake_up1});
285   TimeTicks wake_up2 = now + Milliseconds(100);
286   task_queue2->SetNextWakeUp(&lazy_now, WakeUp{wake_up2});
287   EXPECT_FALSE(wake_up_queue_->empty());
288 
289   EXPECT_EQ(task_queue_.get(), wake_up_queue_->NextScheduledTaskQueue());
290 
291   testing::Mock::VerifyAndClearExpectations(wake_up_queue_.get());
292 
293   EXPECT_CALL(*wake_up_queue_.get(), OnNextWakeUpChanged_TimeTicks(wake_up2))
294       .Times(1);
295 
296   wake_up_queue_->UnregisterQueue(task_queue_.get());
297   EXPECT_EQ(task_queue2.get(), wake_up_queue_->NextScheduledTaskQueue());
298 
299   task_queue_->UnregisterTaskQueue();
300   task_queue_ = nullptr;
301 
302   EXPECT_FALSE(wake_up_queue_->empty());
303   testing::Mock::VerifyAndClearExpectations(wake_up_queue_.get());
304 
305   EXPECT_CALL(*wake_up_queue_.get(),
306               OnNextWakeUpChanged_TimeTicks(TimeTicks::Max()))
307       .Times(1);
308 
309   wake_up_queue_->UnregisterQueue(task_queue2.get());
310   EXPECT_FALSE(wake_up_queue_->NextScheduledTaskQueue());
311 
312   task_queue2->UnregisterTaskQueue();
313   task_queue2 = nullptr;
314   EXPECT_TRUE(wake_up_queue_->empty());
315 }
316 
TEST_F(WakeUpQueueTest,MoveReadyDelayedTasksToWorkQueues)317 TEST_F(WakeUpQueueTest, MoveReadyDelayedTasksToWorkQueues) {
318   TimeDelta delay = Milliseconds(50);
319   TimeTicks now = tick_clock_.NowTicks();
320   LazyNow lazy_now_1(now);
321   TimeTicks delayed_runtime = now + delay;
322   EXPECT_CALL(*wake_up_queue_.get(),
323               OnNextWakeUpChanged_TimeTicks(delayed_runtime));
324   task_queue_->SetNextWakeUp(&lazy_now_1, WakeUp{delayed_runtime});
325 
326   EXPECT_EQ(delayed_runtime, wake_up_queue_->NextScheduledRunTime());
327 
328   wake_up_queue_->MoveReadyDelayedTasksToWorkQueues(&lazy_now_1,
329                                                     EnqueueOrder());
330   EXPECT_EQ(delayed_runtime, wake_up_queue_->NextScheduledRunTime());
331 
332   EXPECT_CALL(*wake_up_queue_.get(),
333               OnNextWakeUpChanged_TimeTicks(TimeTicks::Max()));
334   tick_clock_.SetNowTicks(delayed_runtime);
335   LazyNow lazy_now_2(&tick_clock_);
336   wake_up_queue_->MoveReadyDelayedTasksToWorkQueues(&lazy_now_2,
337                                                     EnqueueOrder());
338   ASSERT_TRUE(wake_up_queue_->NextScheduledRunTime().is_max());
339 }
340 
TEST_F(WakeUpQueueTest,MoveReadyDelayedTasksToWorkQueuesWithLeeway)341 TEST_F(WakeUpQueueTest, MoveReadyDelayedTasksToWorkQueuesWithLeeway) {
342   std::unique_ptr<TaskQueueImplForTest> task_queue2 =
343       std::make_unique<TaskQueueImplForTest>(
344           nullptr, wake_up_queue_.get(), TaskQueue::Spec(QueueName::TEST_TQ));
345 
346   TimeTicks now = tick_clock_.NowTicks();
347   LazyNow lazy_now_1(now);
348 
349   EXPECT_CALL(*wake_up_queue_.get(),
350               OnNextWakeUpChanged_TimeTicks(now + Milliseconds(10)));
351   task_queue2->SetNextWakeUp(&lazy_now_1,
352                              WakeUp{now + Milliseconds(10), Milliseconds(4)});
353   EXPECT_CALL(*wake_up_queue_.get(),
354               OnNextWakeUpChanged_TimeTicks(now + Milliseconds(11)));
355   task_queue_->SetNextWakeUp(&lazy_now_1,
356                              WakeUp{now + Milliseconds(11), TimeDelta()});
357 
358   EXPECT_EQ(now + Milliseconds(11), wake_up_queue_->NextScheduledRunTime());
359 
360   wake_up_queue_->MoveReadyDelayedTasksToWorkQueues(&lazy_now_1,
361                                                     EnqueueOrder());
362   EXPECT_EQ(now + Milliseconds(11), wake_up_queue_->NextScheduledRunTime());
363 
364   tick_clock_.SetNowTicks(now + Milliseconds(10));
365   LazyNow lazy_now_2(&tick_clock_);
366   wake_up_queue_->MoveReadyDelayedTasksToWorkQueues(&lazy_now_2,
367                                                     EnqueueOrder());
368   EXPECT_EQ(now + Milliseconds(11), wake_up_queue_->NextScheduledRunTime());
369 
370   Mock::VerifyAndClearExpectations(wake_up_queue_.get());
371   EXPECT_CALL(*wake_up_queue_.get(), OnNextWakeUpChanged_TimeTicks(_))
372       .Times(AnyNumber());
373   // Tidy up.
374   task_queue2->UnregisterTaskQueue();
375 }
376 
TEST_F(WakeUpQueueTest,CancelDelayedWork)377 TEST_F(WakeUpQueueTest, CancelDelayedWork) {
378   TimeTicks now = tick_clock_.NowTicks();
379   LazyNow lazy_now(now);
380   TimeTicks run_time = now + Milliseconds(20);
381 
382   EXPECT_CALL(*wake_up_queue_.get(), OnNextWakeUpChanged_TimeTicks(run_time));
383   task_queue_->SetNextWakeUp(&lazy_now, WakeUp{run_time});
384 
385   EXPECT_EQ(task_queue_.get(), wake_up_queue_->NextScheduledTaskQueue());
386 
387   EXPECT_CALL(*wake_up_queue_.get(),
388               OnNextWakeUpChanged_TimeTicks(TimeTicks::Max()));
389   task_queue_->SetNextWakeUp(&lazy_now, std::nullopt);
390   EXPECT_FALSE(wake_up_queue_->NextScheduledTaskQueue());
391 }
392 
TEST_F(WakeUpQueueTest,CancelDelayedWork_TwoQueues)393 TEST_F(WakeUpQueueTest, CancelDelayedWork_TwoQueues) {
394   std::unique_ptr<TaskQueueImplForTest> task_queue2 =
395       std::make_unique<TaskQueueImplForTest>(
396           nullptr, wake_up_queue_.get(), TaskQueue::Spec(QueueName::TEST_TQ));
397 
398   TimeTicks now = tick_clock_.NowTicks();
399   LazyNow lazy_now(now);
400   TimeTicks run_time1 = now + Milliseconds(20);
401   TimeTicks run_time2 = now + Milliseconds(40);
402   EXPECT_CALL(*wake_up_queue_.get(), OnNextWakeUpChanged_TimeTicks(run_time1));
403   task_queue_->SetNextWakeUp(&lazy_now, WakeUp{run_time1});
404   Mock::VerifyAndClearExpectations(wake_up_queue_.get());
405 
406   EXPECT_CALL(*wake_up_queue_.get(), OnNextWakeUpChanged_TimeTicks(_)).Times(0);
407   task_queue2->SetNextWakeUp(&lazy_now, WakeUp{run_time2});
408   Mock::VerifyAndClearExpectations(wake_up_queue_.get());
409 
410   EXPECT_EQ(task_queue_.get(), wake_up_queue_->NextScheduledTaskQueue());
411 
412   EXPECT_EQ(run_time1, wake_up_queue_->NextScheduledRunTime());
413 
414   EXPECT_CALL(*wake_up_queue_.get(), OnNextWakeUpChanged_TimeTicks(run_time2));
415   task_queue_->SetNextWakeUp(&lazy_now, std::nullopt);
416   EXPECT_EQ(task_queue2.get(), wake_up_queue_->NextScheduledTaskQueue());
417 
418   EXPECT_EQ(run_time2, wake_up_queue_->NextScheduledRunTime());
419 
420   Mock::VerifyAndClearExpectations(wake_up_queue_.get());
421   EXPECT_CALL(*wake_up_queue_.get(), OnNextWakeUpChanged_TimeTicks(_))
422       .Times(AnyNumber());
423 
424   // Tidy up.
425   task_queue2->UnregisterTaskQueue();
426 }
427 
TEST_F(WakeUpQueueTest,HighResolutionWakeUps)428 TEST_F(WakeUpQueueTest, HighResolutionWakeUps) {
429   TimeTicks now = tick_clock_.NowTicks();
430   LazyNow lazy_now(now);
431   TimeTicks run_time1 = now + Milliseconds(20);
432   TimeTicks run_time2 = now + Milliseconds(40);
433   TaskQueueImplForTest q1(nullptr, wake_up_queue_.get(),
434                           TaskQueue::Spec(QueueName::TEST_TQ));
435   TaskQueueImplForTest q2(nullptr, wake_up_queue_.get(),
436                           TaskQueue::Spec(QueueName::TEST_TQ));
437 
438   // Add two high resolution wake-ups.
439   EXPECT_FALSE(wake_up_queue_->has_pending_high_resolution_tasks());
440   wake_up_queue_->SetNextWakeUpForQueue(
441       &q1, &lazy_now, WakeUp{run_time1, TimeDelta(), WakeUpResolution::kHigh});
442   EXPECT_TRUE(wake_up_queue_->has_pending_high_resolution_tasks());
443   wake_up_queue_->SetNextWakeUpForQueue(
444       &q2, &lazy_now, WakeUp{run_time2, TimeDelta(), WakeUpResolution::kHigh});
445   EXPECT_TRUE(wake_up_queue_->has_pending_high_resolution_tasks());
446 
447   // Remove one of the wake-ups.
448   wake_up_queue_->SetNextWakeUpForQueue(&q1, &lazy_now, std::nullopt);
449   EXPECT_TRUE(wake_up_queue_->has_pending_high_resolution_tasks());
450 
451   // Remove the second one too.
452   wake_up_queue_->SetNextWakeUpForQueue(&q2, &lazy_now, std::nullopt);
453   EXPECT_FALSE(wake_up_queue_->has_pending_high_resolution_tasks());
454 
455   // Change a low resolution wake-up to a high resolution one.
456   wake_up_queue_->SetNextWakeUpForQueue(
457       &q1, &lazy_now, WakeUp{run_time1, TimeDelta(), WakeUpResolution::kLow});
458   EXPECT_FALSE(wake_up_queue_->has_pending_high_resolution_tasks());
459   wake_up_queue_->SetNextWakeUpForQueue(
460       &q1, &lazy_now, WakeUp{run_time1, TimeDelta(), WakeUpResolution::kHigh});
461   EXPECT_TRUE(wake_up_queue_->has_pending_high_resolution_tasks());
462 
463   // Move a high resolution wake-up in time.
464   wake_up_queue_->SetNextWakeUpForQueue(
465       &q1, &lazy_now, WakeUp{run_time2, TimeDelta(), WakeUpResolution::kHigh});
466   EXPECT_TRUE(wake_up_queue_->has_pending_high_resolution_tasks());
467 
468   // Cancel the wake-up twice.
469   wake_up_queue_->SetNextWakeUpForQueue(&q1, &lazy_now, std::nullopt);
470   wake_up_queue_->SetNextWakeUpForQueue(&q1, &lazy_now, std::nullopt);
471   EXPECT_FALSE(wake_up_queue_->has_pending_high_resolution_tasks());
472 
473   // Tidy up.
474   q1.UnregisterTaskQueue();
475   q2.UnregisterTaskQueue();
476 }
477 
TEST_F(WakeUpQueueTest,SetNextWakeUpForQueueInThePast)478 TEST_F(WakeUpQueueTest, SetNextWakeUpForQueueInThePast) {
479   constexpr auto kType = MessagePumpType::DEFAULT;
480   constexpr auto kDelay = Milliseconds(20);
481   constexpr TaskQueue::QueuePriority kHighestPriority = 0;
482   constexpr TaskQueue::QueuePriority kDefaultPriority = 1;
483   constexpr TaskQueue::QueuePriority kLowestPriority = 2;
484   constexpr TaskQueue::QueuePriority kPriorityCount = 3;
485   auto sequence_manager = sequence_manager::CreateUnboundSequenceManager(
486       SequenceManager::Settings::Builder()
487           .SetMessagePumpType(kType)
488           .SetTickClock(&tick_clock_)
489           .SetPrioritySettings(SequenceManager::PrioritySettings(
490               kPriorityCount, kDefaultPriority))
491           .Build());
492   sequence_manager->BindToMessagePump(MessagePump::Create(kType));
493   auto high_prio_queue =
494       sequence_manager->CreateTaskQueue(TaskQueue::Spec(QueueName::TEST_TQ));
495   high_prio_queue->SetQueuePriority(kHighestPriority);
496   auto high_prio_runner = high_prio_queue->CreateTaskRunner(kTaskTypeNone);
497   auto low_prio_queue =
498       sequence_manager->CreateTaskQueue(TaskQueue::Spec(QueueName::TEST2_TQ));
499   low_prio_queue->SetQueuePriority(kLowestPriority);
500   auto low_prio_runner = low_prio_queue->CreateTaskRunner(kTaskTypeNone);
501   sequence_manager->SetDefaultTaskRunner(high_prio_runner);
502   base::MockCallback<base::OnceCallback<void()>> task_1, task_2;
503 
504   testing::Sequence s;
505   // Expect task_2 to run after task_1
506   EXPECT_CALL(task_1, Run);
507   EXPECT_CALL(task_2, Run);
508   // Schedule high and low priority tasks in such a way that clock.Now() will be
509   // way into the future by the time the low prio task run time is used to setup
510   // a wake up.
511   low_prio_runner->PostDelayedTask(FROM_HERE, task_2.Get(), kDelay);
512   high_prio_runner->PostDelayedTask(FROM_HERE, task_1.Get(), kDelay * 2);
513   high_prio_runner->PostTask(
514       FROM_HERE, BindOnce([](SimpleTestTickClock* clock,
515                              TimeDelta delay) { clock->Advance(delay); },
516                           base::Unretained(&tick_clock_), kDelay * 2));
517   RunLoop().RunUntilIdle();
518 }
519 
520 }  // namespace internal
521 }  // namespace sequence_manager
522 }  // namespace base
523