Index: base/task_scheduler/scheduler_service_thread_unittest.cc |
diff --git a/base/task_scheduler/scheduler_service_thread_unittest.cc b/base/task_scheduler/scheduler_service_thread_unittest.cc |
deleted file mode 100644 |
index 65690b004727dd64a092d4996f3e1a6fbaaa51d6..0000000000000000000000000000000000000000 |
--- a/base/task_scheduler/scheduler_service_thread_unittest.cc |
+++ /dev/null |
@@ -1,188 +0,0 @@ |
-// Copyright 2016 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "base/task_scheduler/scheduler_service_thread.h" |
- |
-#include <memory> |
- |
-#include "base/bind.h" |
-#include "base/bind_helpers.h" |
-#include "base/location.h" |
-#include "base/macros.h" |
-#include "base/memory/ptr_util.h" |
-#include "base/memory/ref_counted.h" |
-#include "base/synchronization/waitable_event.h" |
-#include "base/task_scheduler/delayed_task_manager.h" |
-#include "base/task_scheduler/scheduler_worker_pool_impl.h" |
-#include "base/task_scheduler/scheduler_worker_pool_params.h" |
-#include "base/task_scheduler/sequence.h" |
-#include "base/task_scheduler/task.h" |
-#include "base/task_scheduler/task_tracker.h" |
-#include "base/task_scheduler/task_traits.h" |
-#include "base/time/time.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
- |
-namespace base { |
-namespace internal { |
-namespace { |
- |
-// The goal of the tests here is to verify the behavior of the Service Thread. |
-// Some tests may be better part of DelayedTaskManager unit tests depending on |
-// the nature of the test. |
-// |
-// Timed waits are inherent in the service thread because one of its main |
-// purposes is to tell the delayed task manager when to post ready tasks. |
-// This also makes writing tests tricky since the goal isn't to test if |
-// WaitableEvent works but rather do the correct callbacks occur at the right |
-// time. |
-// |
-// As a result, there are a few assumptions that are made in the test: |
-// 1) Tests execute with balanced context switching. This means that there isn't |
-// an adversary that context switches test main thread for an extended period |
-// of time when the test main thread isn't waiting. |
-// 2) Time proceeds normally. Since timed waits determine how long the service |
-// thread will wait, and timed waits is currently not mockable, time needs to |
-// proceed in a forward fashion. If time is frozen (e.g. TimeTicks::Now() |
-// doesn't advance), some tests below may fail. |
-// 3) Short waits sufficiently cover longer waits. Having tests run quickly is |
-// desirable. Since the tests can't change the behavior of timed waiting, the |
-// delay durations should be reasonably short on the order of hundreds of |
-// milliseconds. |
-class TaskSchedulerServiceThreadTest : public testing::Test { |
- protected: |
- TaskSchedulerServiceThreadTest() : delayed_task_manager_(Bind(&DoNothing)) {} |
- |
- void SetUp() override { |
- scheduler_worker_pool_ = SchedulerWorkerPoolImpl::Create( |
- SchedulerWorkerPoolParams("TestWorkerPoolForSchedulerServiceThread", |
- ThreadPriority::BACKGROUND, |
- SchedulerWorkerPoolParams::IORestriction:: |
- DISALLOWED, |
- 1u, |
- TimeDelta::Max()), |
- Bind(&ReEnqueueSequenceCallback), &task_tracker_, |
- &delayed_task_manager_); |
- ASSERT_TRUE(scheduler_worker_pool_); |
- service_thread_ = SchedulerServiceThread::Create( |
- &task_tracker_, &delayed_task_manager_); |
- ASSERT_TRUE(service_thread_); |
- } |
- |
- void TearDown() override { |
- scheduler_worker_pool_->JoinForTesting(); |
- service_thread_->JoinForTesting(); |
- } |
- |
- SchedulerServiceThread* service_thread() { |
- return service_thread_.get(); |
- } |
- |
- DelayedTaskManager& delayed_task_manager() { |
- return delayed_task_manager_; |
- } |
- |
- SchedulerWorkerPoolImpl* worker_pool() { |
- return scheduler_worker_pool_.get(); |
- } |
- |
- private: |
- static void ReEnqueueSequenceCallback(scoped_refptr<Sequence> sequence) { |
- ADD_FAILURE() << "This test only expects one task per sequence."; |
- } |
- |
- DelayedTaskManager delayed_task_manager_; |
- TaskTracker task_tracker_; |
- std::unique_ptr<SchedulerWorkerPoolImpl> scheduler_worker_pool_; |
- std::unique_ptr<SchedulerServiceThread> service_thread_; |
- |
- DISALLOW_COPY_AND_ASSIGN(TaskSchedulerServiceThreadTest); |
-}; |
- |
-} // namespace |
- |
-// Tests that the service thread can handle a single delayed task. |
-TEST_F(TaskSchedulerServiceThreadTest, RunSingleDelayedTask) { |
- WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, |
- WaitableEvent::InitialState::NOT_SIGNALED); |
- delayed_task_manager().AddDelayedTask( |
- WrapUnique(new Task(FROM_HERE, |
- Bind(&WaitableEvent::Signal, Unretained(&event)), |
- TaskTraits(), TimeDelta::FromMilliseconds(100))), |
- make_scoped_refptr(new Sequence), nullptr, worker_pool()); |
- // Waking the service thread shouldn't cause the task to be executed per its |
- // delay not having expired (racy in theory, see test-fixture meta-comment). |
- service_thread()->WakeUp(); |
- // Yield to increase the likelihood of catching a bug where these tasks would |
- // be released before their delay is passed. |
- PlatformThread::YieldCurrentThread(); |
- EXPECT_FALSE(event.IsSignaled()); |
- // When the delay expires, the delayed task is posted, signaling |event|. |
- event.Wait(); |
-} |
- |
-// Tests that the service thread can handle more than one delayed task with |
-// different delays. |
-TEST_F(TaskSchedulerServiceThreadTest, RunMultipleDelayedTasks) { |
- const TimeTicks test_begin_time = TimeTicks::Now(); |
- const TimeDelta delay1 = TimeDelta::FromMilliseconds(100); |
- const TimeDelta delay2 = TimeDelta::FromMilliseconds(200); |
- |
- WaitableEvent event1(WaitableEvent::ResetPolicy::MANUAL, |
- WaitableEvent::InitialState::NOT_SIGNALED); |
- delayed_task_manager().AddDelayedTask( |
- WrapUnique(new Task(FROM_HERE, |
- Bind(&WaitableEvent::Signal, Unretained(&event1)), |
- TaskTraits(), delay1)), |
- make_scoped_refptr(new Sequence), nullptr, worker_pool()); |
- |
- WaitableEvent event2(WaitableEvent::ResetPolicy::MANUAL, |
- WaitableEvent::InitialState::NOT_SIGNALED); |
- delayed_task_manager().AddDelayedTask( |
- WrapUnique(new Task(FROM_HERE, |
- Bind(&WaitableEvent::Signal, Unretained(&event2)), |
- TaskTraits(), delay2)), |
- make_scoped_refptr(new Sequence), nullptr, worker_pool()); |
- |
- // Adding the task shouldn't have caused them to be executed. |
- EXPECT_FALSE(event1.IsSignaled()); |
- EXPECT_FALSE(event2.IsSignaled()); |
- |
- // Waking the service thread shouldn't cause the tasks to be executed per |
- // their delays not having expired (note: this is racy if the delay somehow |
- // expires before this runs but 100ms is a long time in a unittest...). It |
- // should instead cause the service thread to schedule itself for wakeup when |
- // |delay1| expires. |
- service_thread()->WakeUp(); |
- // Yield to increase the likelihood of catching a bug where these tasks would |
- // be released before their delay is passed. |
- PlatformThread::YieldCurrentThread(); |
- EXPECT_FALSE(event1.IsSignaled()); |
- EXPECT_FALSE(event2.IsSignaled()); |
- |
- // Confirm the above assumption about the evolution of time in the test. |
- EXPECT_LT(TimeTicks::Now() - test_begin_time, delay1); |
- |
- // Wait until |delay1| expires and service thread wakes up to schedule the |
- // first task, signalling |event1|. |
- event1.Wait(); |
- |
- // Only the first task should have been released. |
- EXPECT_TRUE(event1.IsSignaled()); |
- EXPECT_FALSE(event2.IsSignaled()); |
- |
- // At least |delay1| should have passed for |event1| to fire. |
- EXPECT_GE(TimeTicks::Now() - test_begin_time, delay1); |
- |
- // And assuming a sane test timeline |delay2| shouldn't have expired yet. |
- EXPECT_LT(TimeTicks::Now() - test_begin_time, delay2); |
- |
- // Now wait for the second task to be fired. |
- event2.Wait(); |
- |
- // Which should only have fired after |delay2| was expired. |
- EXPECT_GE(TimeTicks::Now() - test_begin_time, delay2); |
-} |
- |
-} // namespace internal |
-} // namespace base |