Index: base/task_scheduler/test_task_factory.cc |
diff --git a/base/task_scheduler/test_task_factory.cc b/base/task_scheduler/test_task_factory.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..5edf3dda17a16ed39b26e0ac71b1be1781c6592c |
--- /dev/null |
+++ b/base/task_scheduler/test_task_factory.cc |
@@ -0,0 +1,82 @@ |
+// 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/test_task_factory.h" |
+ |
+#include "base/bind.h" |
+#include "base/bind_helpers.h" |
+#include "base/location.h" |
+#include "base/logging.h" |
+#include "base/synchronization/waitable_event.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace base { |
+namespace internal { |
+namespace test { |
+ |
+TestTaskFactory::TestTaskFactory(scoped_refptr<TaskRunner> task_runner, |
+ ExecutionMode execution_mode) |
+ : cv_(&lock_), |
+ task_runner_(std::move(task_runner)), |
+ execution_mode_(execution_mode) { |
+ // Detach |thread_checker_| from the current thread. It will be attached to |
+ // the first thread that calls ThreadCheckerImpl::CalledOnValidThread(). |
+ thread_checker_.DetachFromThread(); |
+} |
+ |
+TestTaskFactory::~TestTaskFactory() { |
+ WaitForAllTasksToRun(); |
+} |
+ |
+bool TestTaskFactory::PostTask(PostNestedTask post_nested_task, |
+ WaitableEvent* event) { |
+ AutoLock auto_lock(lock_); |
+ return task_runner_->PostTask( |
+ FROM_HERE, |
+ Bind(&TestTaskFactory::RunTaskCallback, Unretained(this), |
+ num_posted_tasks_++, post_nested_task, Unretained(event))); |
+} |
+ |
+void TestTaskFactory::WaitForAllTasksToRun() const { |
+ AutoLock auto_lock(lock_); |
+ while (ran_tasks_.size() < num_posted_tasks_) |
+ cv_.Wait(); |
+} |
+ |
+void TestTaskFactory::RunTaskCallback(size_t task_index, |
+ PostNestedTask post_nested_task, |
+ WaitableEvent* event) { |
+ if (post_nested_task == PostNestedTask::YES) |
+ PostTask(PostNestedTask::NO, nullptr); |
+ |
+ EXPECT_TRUE(task_runner_->RunsTasksOnCurrentThread()); |
+ |
+ { |
+ AutoLock auto_lock(lock_); |
+ |
+ DCHECK_LE(task_index, num_posted_tasks_); |
+ |
+ if ((execution_mode_ == ExecutionMode::SINGLE_THREADED || |
+ execution_mode_ == ExecutionMode::SEQUENCED) && |
+ task_index != ran_tasks_.size()) { |
+ ADD_FAILURE() << "A task didn't run in the expected order."; |
+ } |
+ |
+ if (execution_mode_ == ExecutionMode::SINGLE_THREADED) |
+ EXPECT_TRUE(thread_checker_.CalledOnValidThread()); |
+ |
+ if (ran_tasks_.find(task_index) != ran_tasks_.end()) |
+ ADD_FAILURE() << "A task ran more than once."; |
+ ran_tasks_.insert(task_index); |
+ |
+ cv_.Signal(); |
+ } |
+ |
+ if (event) |
+ event->Wait(); |
+} |
+ |
+} // namespace test |
+} // namespace internal |
+} // namespace base |