Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / media / base / serial_runner_unittest.cc
blobe2e8347a5d8e7f34ff4378f1a6c4d90697779ea5
1 // Copyright 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/bind.h"
6 #include "base/debug/stack_trace.h"
7 #include "base/message_loop/message_loop.h"
8 #include "media/base/pipeline_status.h"
9 #include "media/base/serial_runner.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 namespace media {
14 class SerialRunnerTest : public ::testing::Test {
15 public:
16 SerialRunnerTest()
17 : inside_start_(false), done_called_(false), done_status_(PIPELINE_OK) {}
18 ~SerialRunnerTest() override {}
20 void RunSerialRunner() {
21 message_loop_.PostTask(FROM_HERE, base::Bind(
22 &SerialRunnerTest::StartRunnerInternal, base::Unretained(this),
23 bound_fns_));
24 message_loop_.RunUntilIdle();
27 // Pushes a bound function to the queue that will run its callback with
28 // |status|. called(i) returns whether the i'th bound function pushed to the
29 // queue was called while running the SerialRunner.
30 void PushBoundFunction(PipelineStatus status) {
31 bound_fns_.Push(base::Bind(&SerialRunnerTest::RunBoundFunction,
32 base::Unretained(this),
33 status,
34 called_.size()));
35 called_.push_back(false);
38 void PushBoundClosure() {
39 bound_fns_.Push(base::Bind(&SerialRunnerTest::RunBoundClosure,
40 base::Unretained(this),
41 called_.size()));
42 called_.push_back(false);
45 void PushClosure() {
46 bound_fns_.Push(base::Bind(&SerialRunnerTest::RunClosure,
47 base::Unretained(this),
48 called_.size()));
49 called_.push_back(false);
52 // Push a bound function to the queue that will delete the SerialRunner,
53 // which should cancel all remaining queued work.
54 void PushCancellation() {
55 bound_fns_.Push(base::Bind(&SerialRunnerTest::CancelSerialRunner,
56 base::Unretained(this)));
59 // Queries final status of pushed functions and done callback. Valid only
60 // after calling RunSerialRunner().
61 bool called(size_t index) { return called_[index]; }
62 bool done_called() { return done_called_; }
63 PipelineStatus done_status() { return done_status_; }
65 private:
66 void RunBoundFunction(PipelineStatus status,
67 size_t index,
68 const PipelineStatusCB& status_cb) {
69 EXPECT_EQ(index == 0u, inside_start_)
70 << "First bound function should run on same stack as "
71 << "SerialRunner::Run() while all others should not\n"
72 << base::debug::StackTrace().ToString();
74 called_[index] = true;
75 status_cb.Run(status);
78 void RunBoundClosure(size_t index,
79 const base::Closure& done_cb) {
80 EXPECT_EQ(index == 0u, inside_start_)
81 << "First bound function should run on same stack as "
82 << "SerialRunner::Run() while all others should not\n"
83 << base::debug::StackTrace().ToString();
85 called_[index] = true;
86 done_cb.Run();
89 void RunClosure(size_t index) {
90 EXPECT_EQ(index == 0u, inside_start_)
91 << "First bound function should run on same stack as "
92 << "SerialRunner::Run() while all others should not\n"
93 << base::debug::StackTrace().ToString();
95 called_[index] = true;
98 void StartRunnerInternal(const SerialRunner::Queue& bound_fns) {
99 inside_start_ = true;
100 runner_ = SerialRunner::Run(bound_fns_, base::Bind(
101 &SerialRunnerTest::DoneCallback, base::Unretained(this)));
102 inside_start_ = false;
105 void DoneCallback(PipelineStatus status) {
106 EXPECT_FALSE(inside_start_)
107 << "Done callback should not run on same stack as SerialRunner::Run()\n"
108 << base::debug::StackTrace().ToString();
110 done_called_ = true;
111 done_status_ = status;
112 message_loop_.QuitWhenIdle();
115 void CancelSerialRunner(const PipelineStatusCB& status_cb) {
116 // Tasks run by |runner_| shouldn't reset it, hence we post a task to do so.
117 message_loop_.PostTask(FROM_HERE, base::Bind(
118 &SerialRunnerTest::ResetSerialRunner, base::Unretained(this)));
119 status_cb.Run(PIPELINE_OK);
122 void ResetSerialRunner() {
123 runner_.reset();
126 base::MessageLoop message_loop_;
127 SerialRunner::Queue bound_fns_;
128 scoped_ptr<SerialRunner> runner_;
130 // Used to enforce calling stack guarantees of the API.
131 bool inside_start_;
133 // Tracks whether the i'th bound function was called.
134 std::vector<bool> called_;
136 // Tracks whether the final done callback was called + resulting status.
137 bool done_called_;
138 PipelineStatus done_status_;
140 DISALLOW_COPY_AND_ASSIGN(SerialRunnerTest);
143 TEST_F(SerialRunnerTest, Empty) {
144 RunSerialRunner();
146 EXPECT_TRUE(done_called());
147 EXPECT_EQ(PIPELINE_OK, done_status());
150 TEST_F(SerialRunnerTest, Single) {
151 PushBoundFunction(PIPELINE_OK);
152 RunSerialRunner();
154 EXPECT_TRUE(called(0));
155 EXPECT_TRUE(done_called());
156 EXPECT_EQ(PIPELINE_OK, done_status());
159 TEST_F(SerialRunnerTest, Single_Error) {
160 PushBoundFunction(PIPELINE_ERROR_ABORT);
161 RunSerialRunner();
163 EXPECT_TRUE(called(0));
164 EXPECT_TRUE(done_called());
165 EXPECT_EQ(PIPELINE_ERROR_ABORT, done_status());
168 TEST_F(SerialRunnerTest, Single_Cancel) {
169 PushBoundFunction(PIPELINE_OK);
170 PushCancellation();
171 RunSerialRunner();
173 EXPECT_TRUE(called(0));
174 EXPECT_FALSE(done_called());
177 TEST_F(SerialRunnerTest, Multiple) {
178 PushBoundFunction(PIPELINE_OK);
179 PushBoundFunction(PIPELINE_OK);
180 RunSerialRunner();
182 EXPECT_TRUE(called(0));
183 EXPECT_TRUE(called(1));
184 EXPECT_TRUE(done_called());
185 EXPECT_EQ(PIPELINE_OK, done_status());
188 TEST_F(SerialRunnerTest, Multiple_Error) {
189 PushBoundFunction(PIPELINE_ERROR_ABORT);
190 PushBoundFunction(PIPELINE_OK);
191 RunSerialRunner();
193 EXPECT_TRUE(called(0));
194 EXPECT_FALSE(called(1)); // A bad status cancels remaining work.
195 EXPECT_TRUE(done_called());
196 EXPECT_EQ(PIPELINE_ERROR_ABORT, done_status());
199 TEST_F(SerialRunnerTest, Multiple_Cancel) {
200 PushBoundFunction(PIPELINE_OK);
201 PushCancellation();
202 PushBoundFunction(PIPELINE_OK);
203 RunSerialRunner();
205 EXPECT_TRUE(called(0));
206 EXPECT_FALSE(called(1));
207 EXPECT_FALSE(done_called());
210 TEST_F(SerialRunnerTest, BoundClosure) {
211 PushBoundClosure();
212 RunSerialRunner();
214 EXPECT_TRUE(called(0));
215 EXPECT_TRUE(done_called());
216 EXPECT_EQ(PIPELINE_OK, done_status());
219 TEST_F(SerialRunnerTest, Closure) {
220 PushClosure();
221 RunSerialRunner();
223 EXPECT_TRUE(called(0));
224 EXPECT_TRUE(done_called());
225 EXPECT_EQ(PIPELINE_OK, done_status());
228 } // namespace media