Index: cc/test/task_graph_runner_test_template.h |
diff --git a/cc/test/task_graph_runner_test_template.h b/cc/test/task_graph_runner_test_template.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d3989b9cae0c7e9a087c26793e2d1a1de8d58350 |
--- /dev/null |
+++ b/cc/test/task_graph_runner_test_template.h |
@@ -0,0 +1,244 @@ |
+// Copyright 2015 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. |
+ |
+#ifndef CC_TEST_TASK_GRAPH_RUNNER_TEST_TEMPLATE_H_ |
+#define CC_TEST_TASK_GRAPH_RUNNER_TEST_TEMPLATE_H_ |
+ |
+#include "cc/raster/task_graph_runner.h" |
+ |
+#include <vector> |
+ |
+#include "base/bind.h" |
+#include "base/macros.h" |
+#include "base/synchronization/lock.h" |
+#include "base/threading/simple_thread.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace cc { |
+ |
+class TaskGraphRunnerTestBase { |
+ public: |
+ struct TaskInfo { |
+ TaskInfo(int namespace_index, |
+ unsigned id, |
+ unsigned dependent_id, |
+ unsigned dependent_count, |
+ unsigned priority) |
+ : namespace_index(namespace_index), |
+ id(id), |
+ dependent_id(dependent_id), |
+ dependent_count(dependent_count), |
+ priority(priority) {} |
+ |
+ int namespace_index; |
+ unsigned id; |
+ unsigned dependent_id; |
+ unsigned dependent_count; |
+ unsigned priority; |
+ }; |
+ |
+ TaskGraphRunnerTestBase() {} |
+ |
+ void SetTaskGraphRunner(TaskGraphRunner* task_graph_runner); |
+ void ResetIds(int namespace_index); |
+ void RunAllTasks(int namespace_index); |
+ void RunTaskOnWorkerThread(int namespace_index, unsigned id); |
+ void OnTaskCompleted(int namespace_index, unsigned id); |
+ const std::vector<unsigned>& run_task_ids(int namespace_index); |
+ const std::vector<unsigned>& on_task_completed_ids(int namespace_index); |
+ void ScheduleTasks(int namespace_index, const std::vector<TaskInfo>& tasks); |
+ |
+ static const int kNamespaceCount = 3; |
+ |
+ protected: |
+ class FakeTaskImpl : public Task { |
+ public: |
+ FakeTaskImpl(TaskGraphRunnerTestBase* test, int namespace_index, int id) |
+ : test_(test), namespace_index_(namespace_index), id_(id) {} |
+ |
+ // Overridden from Task: |
+ void RunOnWorkerThread() override; |
+ |
+ virtual void CompleteOnOriginThread(); |
+ |
+ protected: |
+ ~FakeTaskImpl() override {} |
+ |
+ private: |
+ TaskGraphRunnerTestBase* test_; |
+ int namespace_index_; |
+ int id_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(FakeTaskImpl); |
+ }; |
+ |
+ class FakeDependentTaskImpl : public FakeTaskImpl { |
+ public: |
+ FakeDependentTaskImpl(TaskGraphRunnerTestBase* test, |
+ int namespace_index, |
+ int id) |
+ : FakeTaskImpl(test, namespace_index, id) {} |
+ |
+ // Overridden from FakeTaskImpl: |
+ void CompleteOnOriginThread() override {} |
+ |
+ private: |
+ ~FakeDependentTaskImpl() override {} |
+ |
+ DISALLOW_COPY_AND_ASSIGN(FakeDependentTaskImpl); |
+ }; |
+ |
+ TaskGraphRunner* task_graph_runner_; |
+ NamespaceToken namespace_token_[kNamespaceCount]; |
+ Task::Vector tasks_[kNamespaceCount]; |
+ Task::Vector dependents_[kNamespaceCount]; |
+ std::vector<unsigned> run_task_ids_[kNamespaceCount]; |
+ base::Lock run_task_ids_lock_; |
+ std::vector<unsigned> on_task_completed_ids_[kNamespaceCount]; |
+}; |
+ |
+template <typename TaskRunnerTestDelegate> |
+class TaskGraphRunnerTest : public TaskGraphRunnerTestBase, |
+ public testing::Test { |
+ public: |
+ // Overridden from testing::Test: |
+ void SetUp() override { |
+ delegate_.StartTaskGraphRunner(); |
+ SetTaskGraphRunner(delegate_.GetTaskGraphRunner()); |
+ |
+ for (int i = 0; i < kNamespaceCount; ++i) |
+ namespace_token_[i] = task_graph_runner_->GetNamespaceToken(); |
+ } |
+ void TearDown() override { delegate_.StopTaskGraphRunner(); } |
+ |
+ private: |
+ TaskRunnerTestDelegate delegate_; |
+}; |
+ |
+TYPED_TEST_CASE_P(TaskGraphRunnerTest); |
+ |
+TYPED_TEST_P(TaskGraphRunnerTest, Basic) { |
+ const int kNamespaceCount = TaskGraphRunnerTestBase::kNamespaceCount; |
+ using TaskInfo = TaskGraphRunnerTestBase::TaskInfo; |
+ |
+ for (int i = 0; i < kNamespaceCount; ++i) { |
+ EXPECT_EQ(0u, this->run_task_ids(i).size()); |
+ EXPECT_EQ(0u, this->on_task_completed_ids(i).size()); |
+ |
+ this->ScheduleTasks(i, |
+ std::vector<TaskInfo>(1, TaskInfo(i, 0u, 0u, 0u, 0u))); |
+ } |
+ |
+ for (int i = 0; i < kNamespaceCount; ++i) { |
+ this->RunAllTasks(i); |
+ |
+ EXPECT_EQ(1u, this->run_task_ids(i).size()); |
+ EXPECT_EQ(1u, this->on_task_completed_ids(i).size()); |
+ } |
+ |
+ for (int i = 0; i < kNamespaceCount; ++i) |
+ this->ScheduleTasks(i, |
+ std::vector<TaskInfo>(1, TaskInfo(i, 0u, 0u, 1u, 0u))); |
+ |
+ for (int i = 0; i < kNamespaceCount; ++i) { |
+ this->RunAllTasks(i); |
+ |
+ EXPECT_EQ(3u, this->run_task_ids(i).size()); |
+ EXPECT_EQ(2u, this->on_task_completed_ids(i).size()); |
+ } |
+ |
+ for (int i = 0; i < kNamespaceCount; ++i) |
+ this->ScheduleTasks(i, |
+ std::vector<TaskInfo>(1, TaskInfo(i, 0u, 0u, 2u, 0u))); |
+ |
+ for (int i = 0; i < kNamespaceCount; ++i) { |
+ this->RunAllTasks(i); |
+ |
+ EXPECT_EQ(6u, this->run_task_ids(i).size()); |
+ EXPECT_EQ(3u, this->on_task_completed_ids(i).size()); |
+ } |
+} |
+ |
+TYPED_TEST_P(TaskGraphRunnerTest, Dependencies) { |
+ const int kNamespaceCount = TaskGraphRunnerTestBase::kNamespaceCount; |
+ using TaskInfo = TaskGraphRunnerTestBase::TaskInfo; |
+ |
+ for (int i = 0; i < kNamespaceCount; ++i) { |
+ this->ScheduleTasks(i, std::vector<TaskInfo>(1, TaskInfo(i, 0u, 1u, |
+ 1u, // 1 dependent |
+ 0u))); |
+ } |
+ |
+ for (int i = 0; i < kNamespaceCount; ++i) { |
+ this->RunAllTasks(i); |
+ |
+ // Check if task ran before dependent. |
+ ASSERT_EQ(2u, this->run_task_ids(i).size()); |
+ EXPECT_EQ(0u, this->run_task_ids(i)[0]); |
+ EXPECT_EQ(1u, this->run_task_ids(i)[1]); |
+ ASSERT_EQ(1u, this->on_task_completed_ids(i).size()); |
+ EXPECT_EQ(0u, this->on_task_completed_ids(i)[0]); |
+ } |
+ |
+ for (int i = 0; i < kNamespaceCount; ++i) { |
+ this->ScheduleTasks(i, |
+ std::vector<TaskInfo>(1, TaskInfo(i, 2u, 3u, |
+ 2u, // 2 dependents |
+ 0u))); |
+ } |
+ |
+ for (int i = 0; i < kNamespaceCount; ++i) { |
+ this->RunAllTasks(i); |
+ |
+ // Task should only run once. |
+ ASSERT_EQ(5u, this->run_task_ids(i).size()); |
+ EXPECT_EQ(2u, this->run_task_ids(i)[2]); |
+ EXPECT_EQ(3u, this->run_task_ids(i)[3]); |
+ EXPECT_EQ(3u, this->run_task_ids(i)[4]); |
+ ASSERT_EQ(2u, this->on_task_completed_ids(i).size()); |
+ EXPECT_EQ(2u, this->on_task_completed_ids(i)[1]); |
+ } |
+} |
+ |
+REGISTER_TYPED_TEST_CASE_P(TaskGraphRunnerTest, Basic, Dependencies); |
+ |
+template <typename TaskRunnerTestDelegate> |
+using SingleThreadTaskGraphRunnerTest = |
+ TaskGraphRunnerTest<TaskRunnerTestDelegate>; |
+ |
+TYPED_TEST_CASE_P(SingleThreadTaskGraphRunnerTest); |
+ |
+TYPED_TEST_P(SingleThreadTaskGraphRunnerTest, Priority) { |
+ const int kNamespaceCount = TaskGraphRunnerTestBase::kNamespaceCount; |
+ using TaskInfo = TaskGraphRunnerTestBase::TaskInfo; |
+ |
+ for (int i = 0; i < kNamespaceCount; ++i) { |
+ TaskInfo tasks[] = { |
+ TaskInfo(i, 0u, 2u, 1u, 1u), // Priority 1 |
+ TaskInfo(i, 1u, 3u, 1u, 0u) // Priority 0 |
+ }; |
+ this->ScheduleTasks(i, |
+ std::vector<TaskInfo>(tasks, tasks + arraysize(tasks))); |
+ } |
+ |
+ for (int i = 0; i < kNamespaceCount; ++i) { |
+ this->RunAllTasks(i); |
+ |
+ // Check if tasks ran in order of priority. |
+ ASSERT_EQ(4u, this->run_task_ids(i).size()); |
+ EXPECT_EQ(1u, this->run_task_ids(i)[0]); |
+ EXPECT_EQ(3u, this->run_task_ids(i)[1]); |
+ EXPECT_EQ(0u, this->run_task_ids(i)[2]); |
+ EXPECT_EQ(2u, this->run_task_ids(i)[3]); |
+ ASSERT_EQ(2u, this->on_task_completed_ids(i).size()); |
+ EXPECT_EQ(1u, this->on_task_completed_ids(i)[0]); |
+ EXPECT_EQ(0u, this->on_task_completed_ids(i)[1]); |
+ } |
+} |
+ |
+REGISTER_TYPED_TEST_CASE_P(SingleThreadTaskGraphRunnerTest, Priority); |
+ |
+} // namespace cc |
+ |
+#endif // CC_TEST_TASK_GRAPH_RUNNER_TEST_TEMPLATE_H_ |