Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(244)

Side by Side Diff: base/task_scheduler/scheduler_worker_pool_impl_unittest.cc

Issue 2405243003: TaskScheduler: Replace the SchedulerServiceThread with a base::Thread. (Closed)
Patch Set: CR robliao #9 Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/task_scheduler/scheduler_worker_pool_impl.h" 5 #include "base/task_scheduler/scheduler_worker_pool_impl.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 #include <unordered_set> 10 #include <unordered_set>
(...skipping 13 matching lines...) Expand all
24 #include "base/synchronization/lock.h" 24 #include "base/synchronization/lock.h"
25 #include "base/synchronization/waitable_event.h" 25 #include "base/synchronization/waitable_event.h"
26 #include "base/task_runner.h" 26 #include "base/task_runner.h"
27 #include "base/task_scheduler/delayed_task_manager.h" 27 #include "base/task_scheduler/delayed_task_manager.h"
28 #include "base/task_scheduler/scheduler_worker_pool_params.h" 28 #include "base/task_scheduler/scheduler_worker_pool_params.h"
29 #include "base/task_scheduler/sequence.h" 29 #include "base/task_scheduler/sequence.h"
30 #include "base/task_scheduler/sequence_sort_key.h" 30 #include "base/task_scheduler/sequence_sort_key.h"
31 #include "base/task_scheduler/task_tracker.h" 31 #include "base/task_scheduler/task_tracker.h"
32 #include "base/task_scheduler/test_task_factory.h" 32 #include "base/task_scheduler/test_task_factory.h"
33 #include "base/test/gtest_util.h" 33 #include "base/test/gtest_util.h"
34 #include "base/test/test_simple_task_runner.h"
35 #include "base/test/test_timeouts.h"
34 #include "base/threading/platform_thread.h" 36 #include "base/threading/platform_thread.h"
35 #include "base/threading/simple_thread.h" 37 #include "base/threading/simple_thread.h"
38 #include "base/threading/thread.h"
36 #include "base/threading/thread_checker_impl.h" 39 #include "base/threading/thread_checker_impl.h"
37 #include "base/threading/thread_local_storage.h" 40 #include "base/threading/thread_local_storage.h"
38 #include "base/threading/thread_restrictions.h" 41 #include "base/threading/thread_restrictions.h"
39 #include "base/time/time.h" 42 #include "base/time/time.h"
40 #include "testing/gtest/include/gtest/gtest.h" 43 #include "testing/gtest/include/gtest/gtest.h"
41 44
42 namespace base { 45 namespace base {
43 namespace internal { 46 namespace internal {
44 namespace { 47 namespace {
45 48
46 constexpr size_t kNumWorkersInWorkerPool = 4; 49 constexpr size_t kNumWorkersInWorkerPool = 4;
47 constexpr size_t kNumThreadsPostingTasks = 4; 50 constexpr size_t kNumThreadsPostingTasks = 4;
48 constexpr size_t kNumTasksPostedPerThread = 150; 51 constexpr size_t kNumTasksPostedPerThread = 150;
49 // This can't be lower because Windows' WaitableEvent wakes up too early when a 52 // This can't be lower because Windows' WaitableEvent wakes up too early when a
50 // small timeout is used. This results in many spurious wake ups before a worker 53 // small timeout is used. This results in many spurious wake ups before a worker
51 // is allowed to detach. 54 // is allowed to detach.
52 constexpr TimeDelta kReclaimTimeForDetachTests = 55 constexpr TimeDelta kReclaimTimeForDetachTests =
53 TimeDelta::FromMilliseconds(500); 56 TimeDelta::FromMilliseconds(500);
54 constexpr TimeDelta kExtraTimeToWaitForDetach = 57 constexpr TimeDelta kExtraTimeToWaitForDetach =
55 TimeDelta::FromSeconds(1); 58 TimeDelta::FromSeconds(1);
56 59
57 using IORestriction = SchedulerWorkerPoolParams::IORestriction; 60 using IORestriction = SchedulerWorkerPoolParams::IORestriction;
58 61
59 class TestDelayedTaskManager : public DelayedTaskManager {
60 public:
61 TestDelayedTaskManager() : DelayedTaskManager(Bind(&DoNothing)) {}
62
63 void SetCurrentTime(TimeTicks now) { now_ = now; }
64
65 // DelayedTaskManager:
66 TimeTicks Now() const override { return now_; }
67
68 private:
69 TimeTicks now_ = TimeTicks::Now();
70
71 DISALLOW_COPY_AND_ASSIGN(TestDelayedTaskManager);
72 };
73
74 class TaskSchedulerWorkerPoolImplTest 62 class TaskSchedulerWorkerPoolImplTest
75 : public testing::TestWithParam<ExecutionMode> { 63 : public testing::TestWithParam<ExecutionMode> {
76 protected: 64 protected:
77 TaskSchedulerWorkerPoolImplTest() = default; 65 TaskSchedulerWorkerPoolImplTest()
66 : service_thread_("TaskSchedulerServiceThread") {}
78 67
79 void SetUp() override { 68 void SetUp() override {
80 InitializeWorkerPool(TimeDelta::Max(), kNumWorkersInWorkerPool); 69 InitializeWorkerPool(TimeDelta::Max(), kNumWorkersInWorkerPool);
81 } 70 }
82 71
83 void TearDown() override { 72 void TearDown() override {
73 service_thread_.Stop();
84 worker_pool_->WaitForAllWorkersIdleForTesting(); 74 worker_pool_->WaitForAllWorkersIdleForTesting();
85 worker_pool_->JoinForTesting(); 75 worker_pool_->JoinForTesting();
86 } 76 }
87 77
88 void InitializeWorkerPool(const TimeDelta& suggested_reclaim_time, 78 void InitializeWorkerPool(const TimeDelta& suggested_reclaim_time,
89 size_t num_workers) { 79 size_t num_workers) {
80 ASSERT_FALSE(worker_pool_);
81 ASSERT_FALSE(delayed_task_manager_);
82 service_thread_.Start();
83 delayed_task_manager_ =
84 base::MakeUnique<DelayedTaskManager>(service_thread_.task_runner());
90 worker_pool_ = SchedulerWorkerPoolImpl::Create( 85 worker_pool_ = SchedulerWorkerPoolImpl::Create(
91 SchedulerWorkerPoolParams("TestWorkerPool", ThreadPriority::NORMAL, 86 SchedulerWorkerPoolParams("TestWorkerPool", ThreadPriority::NORMAL,
92 IORestriction::ALLOWED, num_workers, 87 IORestriction::ALLOWED, num_workers,
93 suggested_reclaim_time), 88 suggested_reclaim_time),
94 Bind(&TaskSchedulerWorkerPoolImplTest::ReEnqueueSequenceCallback, 89 Bind(&TaskSchedulerWorkerPoolImplTest::ReEnqueueSequenceCallback,
95 Unretained(this)), 90 Unretained(this)),
96 &task_tracker_, &delayed_task_manager_); 91 &task_tracker_, delayed_task_manager_.get());
97 ASSERT_TRUE(worker_pool_); 92 ASSERT_TRUE(worker_pool_);
98 } 93 }
99 94
100 std::unique_ptr<SchedulerWorkerPoolImpl> worker_pool_; 95 std::unique_ptr<SchedulerWorkerPoolImpl> worker_pool_;
101 96
102 TaskTracker task_tracker_; 97 TaskTracker task_tracker_;
103 TestDelayedTaskManager delayed_task_manager_; 98 Thread service_thread_;
99 std::unique_ptr<DelayedTaskManager> delayed_task_manager_;
104 100
105 private: 101 private:
106 void ReEnqueueSequenceCallback(scoped_refptr<Sequence> sequence) { 102 void ReEnqueueSequenceCallback(scoped_refptr<Sequence> sequence) {
107 // In production code, this callback would be implemented by the 103 // In production code, this callback would be implemented by the
108 // TaskScheduler which would first determine which PriorityQueue the 104 // TaskScheduler which would first determine which PriorityQueue the
109 // sequence must be re-enqueued. 105 // sequence must be re-enqueued.
110 const SequenceSortKey sort_key(sequence->GetSortKey()); 106 const SequenceSortKey sort_key(sequence->GetSortKey());
111 worker_pool_->ReEnqueueSequence(std::move(sequence), sort_key); 107 worker_pool_->ReEnqueueSequence(std::move(sequence), sort_key);
112 } 108 }
113 109
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 } 295 }
300 296
301 // Verify that a Task can't be posted after shutdown. 297 // Verify that a Task can't be posted after shutdown.
302 TEST_P(TaskSchedulerWorkerPoolImplTest, PostTaskAfterShutdown) { 298 TEST_P(TaskSchedulerWorkerPoolImplTest, PostTaskAfterShutdown) {
303 auto task_runner = 299 auto task_runner =
304 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()); 300 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam());
305 task_tracker_.Shutdown(); 301 task_tracker_.Shutdown();
306 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, Bind(&ShouldNotRunCallback))); 302 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, Bind(&ShouldNotRunCallback)));
307 } 303 }
308 304
309 // Verify that a Task posted with a delay is added to the DelayedTaskManager and 305 // Verify that a Task doesn't run before its delay expires.
310 // doesn't run before its delay expires. 306 TEST_P(TaskSchedulerWorkerPoolImplTest, PostDelayedTaskNeverRuns) {
gab 2016/10/17 19:09:18 I'm not convinced that this test is required. Task
fdoray 2016/10/18 20:10:49 Removed the test.
307 // Post a task with a very long delay.
308 EXPECT_TRUE(worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam())
309 ->PostDelayedTask(FROM_HERE, Bind([]() {
310 ADD_FAILURE()
311 << "The delayed task should not run.";
312 }),
313 TimeDelta::FromDays(30)));
314
315 // Wait a few milliseconds. The test will fail if the delayed task runs.
316 PlatformThread::Sleep(TestTimeouts::tiny_timeout());
317 }
318
319 // Verify that a Task runs shortly after its delay expires.
311 TEST_P(TaskSchedulerWorkerPoolImplTest, PostDelayedTask) { 320 TEST_P(TaskSchedulerWorkerPoolImplTest, PostDelayedTask) {
312 EXPECT_TRUE(delayed_task_manager_.GetDelayedRunTime().is_null()); 321 TimeTicks start_time = TimeTicks::Now();
313 322
314 // Post a delayed task. 323 // Post a task with a short delay.
315 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, 324 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL,
fdoray 2016/10/18 20:10:49 I think this test is useful because it verifies th
316 WaitableEvent::InitialState::NOT_SIGNALED); 325 WaitableEvent::InitialState::NOT_SIGNALED);
317 EXPECT_TRUE(worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()) 326 EXPECT_TRUE(worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam())
318 ->PostDelayedTask(FROM_HERE, Bind(&WaitableEvent::Signal, 327 ->PostDelayedTask(FROM_HERE, Bind(&WaitableEvent::Signal,
319 Unretained(&task_ran)), 328 Unretained(&task_ran)),
320 TimeDelta::FromSeconds(10))); 329 TestTimeouts::tiny_timeout()));
321 330
322 // The task should have been added to the DelayedTaskManager. 331 // Wait until the task runs.
323 EXPECT_FALSE(delayed_task_manager_.GetDelayedRunTime().is_null()); 332 task_ran.Wait();
324 333
325 // The task shouldn't run. 334 // Expect the task to run less than 250 ms after its delay expires.
326 EXPECT_FALSE(task_ran.IsSignaled()); 335 EXPECT_LT(TimeTicks::Now() - start_time,
327 336 TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout());
gab 2016/10/17 19:09:18 Also EXPECT_GT(..., tiny_timeout)
fdoray 2016/10/18 20:10:49 Done.
328 // Fast-forward time and post tasks that are ripe for execution.
329 delayed_task_manager_.SetCurrentTime(
330 delayed_task_manager_.GetDelayedRunTime());
331 delayed_task_manager_.PostReadyTasks();
332
333 // The task should run.
334 task_ran.Wait();
335 } 337 }
336 338
337 // Verify that the RunsTasksOnCurrentThread() method of a SEQUENCED TaskRunner 339 // Verify that the RunsTasksOnCurrentThread() method of a SEQUENCED TaskRunner
338 // returns false when called from a task that isn't part of the sequence. 340 // returns false when called from a task that isn't part of the sequence.
339 TEST_P(TaskSchedulerWorkerPoolImplTest, SequencedRunsTasksOnCurrentThread) { 341 TEST_P(TaskSchedulerWorkerPoolImplTest, SequencedRunsTasksOnCurrentThread) {
340 scoped_refptr<TaskRunner> task_runner( 342 scoped_refptr<TaskRunner> task_runner(
341 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam())); 343 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()));
342 scoped_refptr<TaskRunner> sequenced_task_runner( 344 scoped_refptr<TaskRunner> sequenced_task_runner(
343 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), 345 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(),
344 ExecutionMode::SEQUENCED)); 346 ExecutionMode::SEQUENCED));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 TaskSchedulerWorkerPoolImplIORestrictionTest() = default; 398 TaskSchedulerWorkerPoolImplIORestrictionTest() = default;
397 399
398 private: 400 private:
399 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolImplIORestrictionTest); 401 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolImplIORestrictionTest);
400 }; 402 };
401 403
402 } // namespace 404 } // namespace
403 405
404 TEST_P(TaskSchedulerWorkerPoolImplIORestrictionTest, IORestriction) { 406 TEST_P(TaskSchedulerWorkerPoolImplIORestrictionTest, IORestriction) {
405 TaskTracker task_tracker; 407 TaskTracker task_tracker;
406 DelayedTaskManager delayed_task_manager(Bind(&DoNothing)); 408 DelayedTaskManager delayed_task_manager(
409 make_scoped_refptr(new TestSimpleTaskRunner));
407 410
408 auto worker_pool = SchedulerWorkerPoolImpl::Create( 411 auto worker_pool = SchedulerWorkerPoolImpl::Create(
409 SchedulerWorkerPoolParams("TestWorkerPoolWithParam", 412 SchedulerWorkerPoolParams("TestWorkerPoolWithParam",
410 ThreadPriority::NORMAL, GetParam(), 1U, 413 ThreadPriority::NORMAL, GetParam(), 1U,
411 TimeDelta::Max()), 414 TimeDelta::Max()),
412 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, 415 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker,
413 &delayed_task_manager); 416 &delayed_task_manager);
414 ASSERT_TRUE(worker_pool); 417 ASSERT_TRUE(worker_pool);
415 418
416 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, 419 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL,
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 worker_pool_.reset(); 753 worker_pool_.reset();
751 754
752 // Verify that counts were recorded to the histogram as expected. 755 // Verify that counts were recorded to the histogram as expected.
753 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(0)); 756 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(0));
754 EXPECT_EQ(1, histogram->SnapshotSamples()->GetCount(3)); 757 EXPECT_EQ(1, histogram->SnapshotSamples()->GetCount(3));
755 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(10)); 758 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(10));
756 } 759 }
757 760
758 } // namespace internal 761 } // namespace internal
759 } // namespace base 762 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698