1 // Copyright 2016 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 5 #include "base/task_scheduler/sequence.h" 6 7 #include "base/macros.h" 8 #include "base/time/time.h" 9 #include "testing/gtest/include/gtest/gtest.h" 10 11 namespace base { 12 namespace internal { 13 14 namespace { 15 16 class TaskSchedulerSequenceTest : public testing::Test { 17 public: 18 TaskSchedulerSequenceTest() 19 : task_a_owned_( 20 new Task(FROM_HERE, 21 Closure(), 22 TaskTraits().WithPriority(TaskPriority::BACKGROUND), 23 TimeDelta())), 24 task_b_owned_( 25 new Task(FROM_HERE, 26 Closure(), 27 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE), 28 TimeDelta())), 29 task_c_owned_( 30 new Task(FROM_HERE, 31 Closure(), 32 TaskTraits().WithPriority(TaskPriority::USER_BLOCKING), 33 TimeDelta())), 34 task_d_owned_( 35 new Task(FROM_HERE, 36 Closure(), 37 TaskTraits().WithPriority(TaskPriority::USER_BLOCKING), 38 TimeDelta())), 39 task_e_owned_( 40 new Task(FROM_HERE, 41 Closure(), 42 TaskTraits().WithPriority(TaskPriority::BACKGROUND), 43 TimeDelta())), 44 task_a_(task_a_owned_.get()), 45 task_b_(task_b_owned_.get()), 46 task_c_(task_c_owned_.get()), 47 task_d_(task_d_owned_.get()), 48 task_e_(task_e_owned_.get()) {} 49 50 protected: 51 // Tasks to be handed off to a Sequence for testing. 52 std::unique_ptr<Task> task_a_owned_; 53 std::unique_ptr<Task> task_b_owned_; 54 std::unique_ptr<Task> task_c_owned_; 55 std::unique_ptr<Task> task_d_owned_; 56 std::unique_ptr<Task> task_e_owned_; 57 58 // Raw pointers to those same tasks for verification. This is needed because 59 // the scoped_ptrs above no longer point to the tasks once they have been 60 // moved into a Sequence. 61 const Task* task_a_; 62 const Task* task_b_; 63 const Task* task_c_; 64 const Task* task_d_; 65 const Task* task_e_; 66 67 private: 68 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSequenceTest); 69 }; 70 71 } // namespace 72 73 TEST_F(TaskSchedulerSequenceTest, PushPopPeek) { 74 scoped_refptr<Sequence> sequence(new Sequence); 75 76 // Push task A in the sequence. Its sequenced time should be updated and it 77 // should be in front of the sequence. 78 EXPECT_TRUE(sequence->PushTask(std::move(task_a_owned_))); 79 EXPECT_FALSE(task_a_->sequenced_time.is_null()); 80 EXPECT_EQ(task_a_, sequence->PeekTask()); 81 82 // Push task B, C and D in the sequence. Their sequenced time should be 83 // updated and task A should always remain in front of the sequence. 84 EXPECT_FALSE(sequence->PushTask(std::move(task_b_owned_))); 85 EXPECT_FALSE(task_b_->sequenced_time.is_null()); 86 EXPECT_EQ(task_a_, sequence->PeekTask()); 87 88 EXPECT_FALSE(sequence->PushTask(std::move(task_c_owned_))); 89 EXPECT_FALSE(task_c_->sequenced_time.is_null()); 90 EXPECT_EQ(task_a_, sequence->PeekTask()); 91 92 EXPECT_FALSE(sequence->PushTask(std::move(task_d_owned_))); 93 EXPECT_FALSE(task_d_->sequenced_time.is_null()); 94 EXPECT_EQ(task_a_, sequence->PeekTask()); 95 96 // Pop task A. Task B should now be in front. 97 EXPECT_FALSE(sequence->PopTask()); 98 EXPECT_EQ(task_b_, sequence->PeekTask()); 99 100 // Pop task B. Task C should now be in front. 101 EXPECT_FALSE(sequence->PopTask()); 102 EXPECT_EQ(task_c_, sequence->PeekTask()); 103 104 // Pop task C. Task D should now be in front. 105 EXPECT_FALSE(sequence->PopTask()); 106 EXPECT_EQ(task_d_, sequence->PeekTask()); 107 108 // Push task E in the sequence. Its sequenced time should be updated and 109 // task D should remain in front. 110 EXPECT_FALSE(sequence->PushTask(std::move(task_e_owned_))); 111 EXPECT_FALSE(task_e_->sequenced_time.is_null()); 112 EXPECT_EQ(task_d_, sequence->PeekTask()); 113 114 // Pop task D. Task E should now be in front. 115 EXPECT_FALSE(sequence->PopTask()); 116 EXPECT_EQ(task_e_, sequence->PeekTask()); 117 118 // Pop task E. The sequence should now be empty. 119 EXPECT_TRUE(sequence->PopTask()); 120 EXPECT_EQ(nullptr, sequence->PeekTask()); 121 } 122 123 TEST_F(TaskSchedulerSequenceTest, GetSortKey) { 124 scoped_refptr<Sequence> sequence(new Sequence); 125 126 // Push task A in the sequence. The highest priority is from task A 127 // (BACKGROUND). Task A is in front of the sequence. 128 sequence->PushTask(std::move(task_a_owned_)); 129 EXPECT_EQ(SequenceSortKey(TaskPriority::BACKGROUND, task_a_->sequenced_time), 130 sequence->GetSortKey()); 131 132 // Push task B in the sequence. The highest priority is from task B 133 // (USER_VISIBLE). Task A is still in front of the sequence. 134 sequence->PushTask(std::move(task_b_owned_)); 135 EXPECT_EQ( 136 SequenceSortKey(TaskPriority::USER_VISIBLE, task_a_->sequenced_time), 137 sequence->GetSortKey()); 138 139 // Push task C in the sequence. The highest priority is from task C 140 // (USER_BLOCKING). Task A is still in front of the sequence. 141 sequence->PushTask(std::move(task_c_owned_)); 142 EXPECT_EQ( 143 SequenceSortKey(TaskPriority::USER_BLOCKING, task_a_->sequenced_time), 144 sequence->GetSortKey()); 145 146 // Push task D in the sequence. The highest priority is from tasks C/D 147 // (USER_BLOCKING). Task A is still in front of the sequence. 148 sequence->PushTask(std::move(task_d_owned_)); 149 EXPECT_EQ( 150 SequenceSortKey(TaskPriority::USER_BLOCKING, task_a_->sequenced_time), 151 sequence->GetSortKey()); 152 153 // Pop task A. The highest priority is still USER_BLOCKING. The task in front 154 // of the sequence is now task B. 155 sequence->PopTask(); 156 EXPECT_EQ( 157 SequenceSortKey(TaskPriority::USER_BLOCKING, task_b_->sequenced_time), 158 sequence->GetSortKey()); 159 160 // Pop task B. The highest priority is still USER_BLOCKING. The task in front 161 // of the sequence is now task C. 162 sequence->PopTask(); 163 EXPECT_EQ( 164 SequenceSortKey(TaskPriority::USER_BLOCKING, task_c_->sequenced_time), 165 sequence->GetSortKey()); 166 167 // Pop task C. The highest priority is still USER_BLOCKING. The task in front 168 // of the sequence is now task D. 169 sequence->PopTask(); 170 EXPECT_EQ( 171 SequenceSortKey(TaskPriority::USER_BLOCKING, task_d_->sequenced_time), 172 sequence->GetSortKey()); 173 174 // Push task E in the sequence. The highest priority is still USER_BLOCKING. 175 // The task in front of the sequence is still task D. 176 sequence->PushTask(std::move(task_e_owned_)); 177 EXPECT_EQ( 178 SequenceSortKey(TaskPriority::USER_BLOCKING, task_d_->sequenced_time), 179 sequence->GetSortKey()); 180 181 // Pop task D. The highest priority is now from task E (BACKGROUND). The 182 // task in front of the sequence is now task E. 183 sequence->PopTask(); 184 EXPECT_EQ(SequenceSortKey(TaskPriority::BACKGROUND, task_e_->sequenced_time), 185 sequence->GetSortKey()); 186 } 187 188 } // namespace internal 189 } // namespace base 190