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

Unified Diff: cc/resources/task_graph_runner_unittest.cc

Issue 141163019: Re-land: cc: Remove WorkerPool class and instead use TaskGraphRunner directly. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix mode of task_graph_runner.h Created 6 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/resources/task_graph_runner_perftest.cc ('k') | cc/resources/tile_manager.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/resources/task_graph_runner_unittest.cc
diff --git a/cc/resources/task_graph_runner_unittest.cc b/cc/resources/task_graph_runner_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..274b29c985738ec53fbdf043610dcb02e10a2574
--- /dev/null
+++ b/cc/resources/task_graph_runner_unittest.cc
@@ -0,0 +1,347 @@
+// Copyright 2013 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 "cc/resources/task_graph_runner.h"
+
+#include <vector>
+
+#include "base/bind.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+const int kNamespaceCount = 3;
+
+class TaskGraphRunnerTestBase {
+ public:
+ struct Task {
+ Task(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;
+ };
+
+ void ResetIds(int namespace_index) {
+ run_task_ids_[namespace_index].clear();
+ on_task_completed_ids_[namespace_index].clear();
+ }
+
+ void RunAllTasks(int namespace_index) {
+ task_graph_runner_->WaitForTasksToFinishRunning(
+ namespace_token_[namespace_index]);
+
+ internal::Task::Vector completed_tasks;
+ task_graph_runner_->CollectCompletedTasks(
+ namespace_token_[namespace_index], &completed_tasks);
+ for (internal::Task::Vector::const_iterator it = completed_tasks.begin();
+ it != completed_tasks.end();
+ ++it) {
+ FakeTaskImpl* task = static_cast<FakeTaskImpl*>(it->get());
+ task->CompleteOnOriginThread();
+ }
+ }
+
+ void RunTask(int namespace_index, unsigned id) {
+ run_task_ids_[namespace_index].push_back(id);
+ }
+
+ void OnTaskCompleted(int namespace_index, unsigned id) {
+ on_task_completed_ids_[namespace_index].push_back(id);
+ }
+
+ const std::vector<unsigned>& run_task_ids(int namespace_index) {
+ return run_task_ids_[namespace_index];
+ }
+
+ const std::vector<unsigned>& on_task_completed_ids(int namespace_index) {
+ return on_task_completed_ids_[namespace_index];
+ }
+
+ void ScheduleTasks(int namespace_index, const std::vector<Task>& tasks) {
+ internal::Task::Vector new_tasks;
+ internal::Task::Vector new_dependents;
+ internal::GraphNode::Map new_graph;
+
+ for (std::vector<Task>::const_iterator it = tasks.begin();
+ it != tasks.end(); ++it) {
+ scoped_refptr<FakeTaskImpl> new_task(
+ new FakeTaskImpl(this, it->namespace_index, it->id));
+ scoped_ptr<internal::GraphNode> node(
+ new internal::GraphNode(new_task.get(), it->priority));
+
+ for (unsigned i = 0; i < it->dependent_count; ++i) {
+ scoped_refptr<FakeDependentTaskImpl> new_dependent_task(
+ new FakeDependentTaskImpl(
+ this, it->namespace_index, it->dependent_id));
+ scoped_ptr<internal::GraphNode> dependent_node(
+ new internal::GraphNode(new_dependent_task.get(), it->priority));
+ node->add_dependent(dependent_node.get());
+ dependent_node->add_dependency();
+ new_graph.set(new_dependent_task.get(), dependent_node.Pass());
+ new_dependents.push_back(new_dependent_task.get());
+ }
+
+ new_graph.set(new_task.get(), node.Pass());
+ new_tasks.push_back(new_task.get());
+ }
+
+ task_graph_runner_->SetTaskGraph(
+ namespace_token_[namespace_index], &new_graph);
+
+ dependents_[namespace_index].swap(new_dependents);
+ tasks_[namespace_index].swap(new_tasks);
+ }
+
+ protected:
+ class FakeTaskImpl : public internal::Task {
+ public:
+ FakeTaskImpl(TaskGraphRunnerTestBase* test,
+ int namespace_index,
+ int id)
+ : test_(test),
+ namespace_index_(namespace_index),
+ id_(id) {
+ }
+
+ // Overridden from internal::Task:
+ virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE {
+ test_->RunTask(namespace_index_, id_);
+ }
+
+ virtual void CompleteOnOriginThread() {
+ test_->OnTaskCompleted(namespace_index_, id_);
+ }
+
+ protected:
+ virtual ~FakeTaskImpl() {}
+
+ 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:
+ virtual void CompleteOnOriginThread() OVERRIDE {}
+
+ private:
+ virtual ~FakeDependentTaskImpl() {}
+
+ DISALLOW_COPY_AND_ASSIGN(FakeDependentTaskImpl);
+ };
+
+ scoped_ptr<internal::TaskGraphRunner> task_graph_runner_;
+ internal::NamespaceToken namespace_token_[kNamespaceCount];
+ internal::Task::Vector tasks_[kNamespaceCount];
+ internal::Task::Vector dependents_[kNamespaceCount];
+ std::vector<unsigned> run_task_ids_[kNamespaceCount];
+ std::vector<unsigned> on_task_completed_ids_[kNamespaceCount];
+};
+
+class TaskGraphRunnerTest : public TaskGraphRunnerTestBase,
+ public testing::TestWithParam<int> {
+ public:
+ // Overridden from testing::Test:
+ virtual void SetUp() OVERRIDE {
+ task_graph_runner_ = make_scoped_ptr(
+ new internal::TaskGraphRunner(GetParam(), "Test"));
+ for (int i = 0; i < kNamespaceCount; ++i)
+ namespace_token_[i] = task_graph_runner_->GetNamespaceToken();
+ }
+ virtual void TearDown() OVERRIDE {
+ task_graph_runner_.reset();
+ }
+};
+
+TEST_P(TaskGraphRunnerTest, Basic) {
+ for (int i = 0; i < kNamespaceCount; ++i) {
+ EXPECT_EQ(0u, run_task_ids(i).size());
+ EXPECT_EQ(0u, on_task_completed_ids(i).size());
+
+ ScheduleTasks(i, std::vector<Task>(1, Task(i, 0u, 0u, 0u, 0u)));
+ }
+
+ for (int i = 0; i < kNamespaceCount; ++i) {
+ RunAllTasks(i);
+
+ EXPECT_EQ(1u, run_task_ids(i).size());
+ EXPECT_EQ(1u, on_task_completed_ids(i).size());
+ }
+
+ for (int i = 0; i < kNamespaceCount; ++i)
+ ScheduleTasks(i, std::vector<Task>(1, Task(i, 0u, 0u, 1u, 0u)));
+
+ for (int i = 0; i < kNamespaceCount; ++i) {
+ RunAllTasks(i);
+
+ EXPECT_EQ(3u, run_task_ids(i).size());
+ EXPECT_EQ(2u, on_task_completed_ids(i).size());
+ }
+
+ for (int i = 0; i < kNamespaceCount; ++i)
+ ScheduleTasks(i, std::vector<Task>(1, Task(i, 0u, 0u, 2u, 0u)));
+
+ for (int i = 0; i < kNamespaceCount; ++i) {
+ RunAllTasks(i);
+
+ EXPECT_EQ(6u, run_task_ids(i).size());
+ EXPECT_EQ(3u, on_task_completed_ids(i).size());
+ }
+}
+
+TEST_P(TaskGraphRunnerTest, Dependencies) {
+ for (int i = 0; i < kNamespaceCount; ++i) {
+ ScheduleTasks(i, std::vector<Task>(1, Task(i,
+ 0u,
+ 1u,
+ 1u, // 1 dependent
+ 0u)));
+ }
+
+ for (int i = 0; i < kNamespaceCount; ++i) {
+ RunAllTasks(i);
+
+ // Check if task ran before dependent.
+ ASSERT_EQ(2u, run_task_ids(i).size());
+ EXPECT_EQ(0u, run_task_ids(i)[0]);
+ EXPECT_EQ(1u, run_task_ids(i)[1]);
+ ASSERT_EQ(1u, on_task_completed_ids(i).size());
+ EXPECT_EQ(0u, on_task_completed_ids(i)[0]);
+ }
+
+ for (int i = 0; i < kNamespaceCount; ++i) {
+ ScheduleTasks(i, std::vector<Task>(1, Task(i,
+ 2u,
+ 3u,
+ 2u, // 2 dependents
+ 0u)));
+ }
+
+ for (int i = 0; i < kNamespaceCount; ++i) {
+ RunAllTasks(i);
+
+ // Task should only run once.
+ ASSERT_EQ(5u, run_task_ids(i).size());
+ EXPECT_EQ(2u, run_task_ids(i)[2]);
+ EXPECT_EQ(3u, run_task_ids(i)[3]);
+ EXPECT_EQ(3u, run_task_ids(i)[4]);
+ ASSERT_EQ(2u, on_task_completed_ids(i).size());
+ EXPECT_EQ(2u, on_task_completed_ids(i)[1]);
+ }
+}
+
+INSTANTIATE_TEST_CASE_P(TaskGraphRunnerTests,
+ TaskGraphRunnerTest,
+ ::testing::Range(1, 5));
+
+class TaskGraphRunnerSingleThreadTest : public TaskGraphRunnerTestBase,
+ public testing::Test {
+ public:
+ // Overridden from testing::Test:
+ virtual void SetUp() OVERRIDE {
+ task_graph_runner_ = make_scoped_ptr(
+ new internal::TaskGraphRunner(1, "Test"));
+ for (int i = 0; i < kNamespaceCount; ++i)
+ namespace_token_[i] = task_graph_runner_->GetNamespaceToken();
+ }
+ virtual void TearDown() OVERRIDE {
+ task_graph_runner_.reset();
+ }
+};
+
+TEST_F(TaskGraphRunnerSingleThreadTest, Priority) {
+ for (int i = 0; i < kNamespaceCount; ++i) {
+ Task tasks[] = {
+ Task(i,
+ 0u,
+ 2u,
+ 1u,
+ 1u), // Priority 1
+ Task(i,
+ 1u,
+ 3u,
+ 1u,
+ 0u) // Priority 0
+ };
+ ScheduleTasks(i, std::vector<Task>(tasks, tasks + arraysize(tasks)));
+ }
+
+ for (int i = 0; i < kNamespaceCount; ++i) {
+ RunAllTasks(i);
+
+ // Check if tasks ran in order of priority.
+ ASSERT_EQ(4u, run_task_ids(i).size());
+ EXPECT_EQ(1u, run_task_ids(i)[0]);
+ EXPECT_EQ(3u, run_task_ids(i)[1]);
+ EXPECT_EQ(0u, run_task_ids(i)[2]);
+ EXPECT_EQ(2u, run_task_ids(i)[3]);
+ ASSERT_EQ(2u, on_task_completed_ids(i).size());
+ EXPECT_EQ(1u, on_task_completed_ids(i)[0]);
+ EXPECT_EQ(0u, on_task_completed_ids(i)[1]);
+ }
+
+ for (int i = 0; i < kNamespaceCount; ++i)
+ ResetIds(i);
+
+ for (int i = 0; i < kNamespaceCount; ++i) {
+ std::vector<Task> tasks;
+ tasks.push_back(Task(i,
+ 0u,
+ 3u,
+ 1u, // 1 dependent
+ 1u)); // Priority 1
+ tasks.push_back(Task(i,
+ 1u,
+ 4u,
+ 2u, // 2 dependents
+ 1u)); // Priority 1
+ tasks.push_back(Task(i,
+ 2u,
+ 5u,
+ 1u, // 1 dependent
+ 0u)); // Priority 0
+ ScheduleTasks(i, tasks);
+ }
+
+ for (int i = 0; i < kNamespaceCount; ++i) {
+ RunAllTasks(i);
+
+ // Check if tasks ran in order of priority and that task with more
+ // dependents ran first when priority is the same.
+ ASSERT_LE(3u, run_task_ids(i).size());
+ EXPECT_EQ(2u, run_task_ids(i)[0]);
+ EXPECT_EQ(5u, run_task_ids(i)[1]);
+ EXPECT_EQ(1u, run_task_ids(i)[2]);
+ ASSERT_EQ(3u, on_task_completed_ids(i).size());
+ EXPECT_EQ(2u, on_task_completed_ids(i)[0]);
+ EXPECT_EQ(1u, on_task_completed_ids(i)[1]);
+ EXPECT_EQ(0u, on_task_completed_ids(i)[2]);
+ }
+}
+
+} // namespace
+} // namespace cc
« no previous file with comments | « cc/resources/task_graph_runner_perftest.cc ('k') | cc/resources/tile_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698