Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / base / deferred_sequenced_task_runner_unittest.cc
blob81f2a0a00c9beb39b0934ce4e942d6bfd9671837
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/deferred_sequenced_task_runner.h"
7 #include "base/basictypes.h"
8 #include "base/bind.h"
9 #include "base/bind_helpers.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/message_loop/message_loop_proxy.h"
13 #include "base/threading/non_thread_safe.h"
14 #include "base/threading/thread.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 namespace {
20 class DeferredSequencedTaskRunnerTest : public testing::Test,
21 public base::NonThreadSafe {
22 public:
23 class ExecuteTaskOnDestructor :
24 public base::RefCounted<ExecuteTaskOnDestructor> {
25 public:
26 ExecuteTaskOnDestructor(
27 DeferredSequencedTaskRunnerTest* executor,
28 int task_id)
29 : executor_(executor),
30 task_id_(task_id) {
32 private:
33 friend class base::RefCounted<ExecuteTaskOnDestructor>;
34 virtual ~ExecuteTaskOnDestructor() {
35 executor_->ExecuteTask(task_id_);
37 DeferredSequencedTaskRunnerTest* executor_;
38 int task_id_;
41 void ExecuteTask(int task_id) {
42 base::AutoLock lock(lock_);
43 executed_task_ids_.push_back(task_id);
46 void PostExecuteTask(int task_id) {
47 runner_->PostTask(FROM_HERE,
48 base::Bind(&DeferredSequencedTaskRunnerTest::ExecuteTask,
49 base::Unretained(this),
50 task_id));
53 void StartRunner() {
54 runner_->Start();
57 void DoNothing(ExecuteTaskOnDestructor* object) {
60 protected:
61 DeferredSequencedTaskRunnerTest() :
62 loop_(),
63 runner_(
64 new base::DeferredSequencedTaskRunner(loop_.message_loop_proxy())) {
67 base::MessageLoop loop_;
68 scoped_refptr<base::DeferredSequencedTaskRunner> runner_;
69 mutable base::Lock lock_;
70 std::vector<int> executed_task_ids_;
73 TEST_F(DeferredSequencedTaskRunnerTest, Stopped) {
74 PostExecuteTask(1);
75 loop_.RunUntilIdle();
76 EXPECT_THAT(executed_task_ids_, testing::ElementsAre());
79 TEST_F(DeferredSequencedTaskRunnerTest, Start) {
80 StartRunner();
81 PostExecuteTask(1);
82 loop_.RunUntilIdle();
83 EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1));
86 TEST_F(DeferredSequencedTaskRunnerTest, StartWithMultipleElements) {
87 StartRunner();
88 for (int i = 1; i < 5; ++i)
89 PostExecuteTask(i);
91 loop_.RunUntilIdle();
92 EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1, 2, 3, 4));
95 TEST_F(DeferredSequencedTaskRunnerTest, DeferredStart) {
96 PostExecuteTask(1);
97 loop_.RunUntilIdle();
98 EXPECT_THAT(executed_task_ids_, testing::ElementsAre());
100 StartRunner();
101 loop_.RunUntilIdle();
102 EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1));
104 PostExecuteTask(2);
105 loop_.RunUntilIdle();
106 EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1, 2));
109 TEST_F(DeferredSequencedTaskRunnerTest, DeferredStartWithMultipleElements) {
110 for (int i = 1; i < 5; ++i)
111 PostExecuteTask(i);
112 loop_.RunUntilIdle();
113 EXPECT_THAT(executed_task_ids_, testing::ElementsAre());
115 StartRunner();
116 for (int i = 5; i < 9; ++i)
117 PostExecuteTask(i);
118 loop_.RunUntilIdle();
119 EXPECT_THAT(executed_task_ids_, testing::ElementsAre(1, 2, 3, 4, 5, 6, 7, 8));
122 TEST_F(DeferredSequencedTaskRunnerTest, DeferredStartWithMultipleThreads) {
124 base::Thread thread1("DeferredSequencedTaskRunnerTestThread1");
125 base::Thread thread2("DeferredSequencedTaskRunnerTestThread2");
126 thread1.Start();
127 thread2.Start();
128 for (int i = 0; i < 5; ++i) {
129 thread1.message_loop()->PostTask(
130 FROM_HERE,
131 base::Bind(&DeferredSequencedTaskRunnerTest::PostExecuteTask,
132 base::Unretained(this),
133 2 * i));
134 thread2.message_loop()->PostTask(
135 FROM_HERE,
136 base::Bind(&DeferredSequencedTaskRunnerTest::PostExecuteTask,
137 base::Unretained(this),
138 2 * i + 1));
139 if (i == 2) {
140 thread1.message_loop()->PostTask(
141 FROM_HERE,
142 base::Bind(&DeferredSequencedTaskRunnerTest::StartRunner,
143 base::Unretained(this)));
148 loop_.RunUntilIdle();
149 EXPECT_THAT(executed_task_ids_,
150 testing::WhenSorted(testing::ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)));
153 TEST_F(DeferredSequencedTaskRunnerTest, ObjectDestructionOrder) {
155 base::Thread thread("DeferredSequencedTaskRunnerTestThread");
156 thread.Start();
157 runner_ =
158 new base::DeferredSequencedTaskRunner(thread.message_loop_proxy());
159 for (int i = 0; i < 5; ++i) {
161 // Use a block to ensure that no reference to |short_lived_object|
162 // is kept on the main thread after it is posted to |runner_|.
163 scoped_refptr<ExecuteTaskOnDestructor> short_lived_object =
164 new ExecuteTaskOnDestructor(this, 2 * i);
165 runner_->PostTask(
166 FROM_HERE,
167 base::Bind(&DeferredSequencedTaskRunnerTest::DoNothing,
168 base::Unretained(this),
169 short_lived_object));
171 // |short_lived_object| with id |2 * i| should be destroyed before the
172 // task |2 * i + 1| is executed.
173 PostExecuteTask(2 * i + 1);
175 StartRunner();
178 // All |short_lived_object| with id |2 * i| are destroyed before the task
179 // |2 * i + 1| is executed.
180 EXPECT_THAT(executed_task_ids_,
181 testing::ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
184 } // namespace