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

Side by Side Diff: chromecast/media/cma/base/balanced_media_task_runner_unittest.cc

Issue 534893002: Introduce the concept of media task runner. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 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.
4
5 #include <list>
6 #include <vector>
7
8 #include "base/basictypes.h"
9 #include "base/bind.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/threading/thread.h"
13 #include "base/time/time.h"
14 #include "chromecast/media/cma/base/balanced_media_task_runner_factory.h"
15 #include "chromecast/media/cma/base/media_task_runner.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace chromecast {
19 namespace media {
20
21 namespace {
22
23 struct MediaTaskRunnerTestContext {
24 MediaTaskRunnerTestContext();
25 ~MediaTaskRunnerTestContext();
26
27 scoped_refptr<MediaTaskRunner> media_task_runner;
28
29 bool is_pending_task;
30
31 std::vector<base::TimeDelta> task_timestamp_list;
32
33 size_t task_index;
34 base::TimeDelta max_timestamp;
35 };
36
37 MediaTaskRunnerTestContext::MediaTaskRunnerTestContext() {
38 }
39
40 MediaTaskRunnerTestContext::~MediaTaskRunnerTestContext() {
41 }
42
43 } // namespace
44
45 class BalancedMediaTaskRunnerTest : public testing::Test {
46 public:
47 BalancedMediaTaskRunnerTest();
48 virtual ~BalancedMediaTaskRunnerTest();
49
50 void SetupTest(base::TimeDelta max_delta,
51 const std::vector<std::vector<int> >& timestamps_in_ms,
52 const std::vector<size_t>& pattern,
53 const std::vector<int>& expected_task_timestamps_ms);
54 void ProcessAllTasks();
55
56 protected:
57 // Expected task order based on their timestamps.
58 std::list<base::TimeDelta> expected_task_timestamps_;
59
60 private:
61 void ScheduleTask();
62 void Task(size_t task_runner_id, base::TimeDelta timestamp);
63
64 void OnTestTimeout();
65
66 scoped_refptr<BalancedMediaTaskRunnerFactory> media_task_runner_factory_;
67
68 // Schedule first a task on media task runner #scheduling_pattern[0]
69 // then a task on media task runner #scheduling_pattern[1] and so on.
70 // Wrap around when reaching the end of the pattern.
71 std::vector<size_t> scheduling_pattern_;
72 size_t pattern_index_;
73
74 // For each media task runner, keep a track of which task has already been
75 // scheduled.
76 std::vector<MediaTaskRunnerTestContext> contexts_;
77
78 DISALLOW_COPY_AND_ASSIGN(BalancedMediaTaskRunnerTest);
79 };
80
81 BalancedMediaTaskRunnerTest::BalancedMediaTaskRunnerTest() {
82 }
83
84 BalancedMediaTaskRunnerTest::~BalancedMediaTaskRunnerTest() {
85 }
86
87 void BalancedMediaTaskRunnerTest::SetupTest(
88 base::TimeDelta max_delta,
89 const std::vector<std::vector<int> >& timestamps_in_ms,
90 const std::vector<size_t>& pattern,
91 const std::vector<int>& expected_task_timestamps_ms) {
92 media_task_runner_factory_ = new BalancedMediaTaskRunnerFactory(max_delta);
93
94 scheduling_pattern_ = pattern;
95 pattern_index_ = 0;
96
97 // Setup each task runner.
98 size_t n = timestamps_in_ms.size();
99 contexts_.resize(n);
100 for (size_t k = 0; k < n; k++) {
101 contexts_[k].media_task_runner =
102 media_task_runner_factory_->CreateMediaTaskRunner(
103 base::MessageLoopProxy::current());
104 contexts_[k].is_pending_task = false;
105 contexts_[k].task_index = 0;
106 contexts_[k].task_timestamp_list.resize(
107 timestamps_in_ms[k].size());
108 for (size_t i = 0; i < timestamps_in_ms[k].size(); i++) {
109 contexts_[k].task_timestamp_list[i] =
110 base::TimeDelta::FromMilliseconds(timestamps_in_ms[k][i]);
111 }
112 }
113
114 // Expected task order (for tasks that are actually run).
115 for (size_t k = 0; k < expected_task_timestamps_ms.size(); k++) {
116 expected_task_timestamps_.push_back(
117 base::TimeDelta::FromMilliseconds(expected_task_timestamps_ms[k]));
118 }
119 }
120
121 void BalancedMediaTaskRunnerTest::ProcessAllTasks() {
122 base::MessageLoop::current()->PostDelayedTask(
123 FROM_HERE,
124 base::Bind(&BalancedMediaTaskRunnerTest::OnTestTimeout,
125 base::Unretained(this)),
126 base::TimeDelta::FromSeconds(5));
127 ScheduleTask();
128 }
129
130 void BalancedMediaTaskRunnerTest::ScheduleTask() {
131 bool has_task = false;
132 for (size_t k = 0; k < contexts_.size(); k++) {
133 if (contexts_[k].task_index < contexts_[k].task_timestamp_list.size())
134 has_task = true;
135 }
136 if (!has_task) {
137 base::MessageLoop::current()->QuitWhenIdle();
138 return;
139 }
140
141 size_t next_pattern_index =
142 (pattern_index_ + 1) % scheduling_pattern_.size();
143
144 size_t task_runner_id = scheduling_pattern_[pattern_index_];
145 MediaTaskRunnerTestContext& context = contexts_[task_runner_id];
146
147 // Check whether all tasks have been scheduled for that task runner
148 // or if there is already one pending task.
149 if (context.task_index >= context.task_timestamp_list.size() ||
150 context.is_pending_task) {
151 pattern_index_ = next_pattern_index;
152 base::MessageLoopProxy::current()->PostTask(
153 FROM_HERE,
154 base::Bind(&BalancedMediaTaskRunnerTest::ScheduleTask,
155 base::Unretained(this)));
156 return;
157 }
158
159 bool expected_may_run = false;
160 if (context.task_timestamp_list[context.task_index] >=
161 context.max_timestamp) {
162 expected_may_run = true;
163 context.max_timestamp = context.task_timestamp_list[context.task_index];
164 }
165
166 bool may_run = context.media_task_runner->PostMediaTask(
167 FROM_HERE,
168 base::Bind(&BalancedMediaTaskRunnerTest::Task,
169 base::Unretained(this),
170 task_runner_id,
171 context.task_timestamp_list[context.task_index]),
172 context.task_timestamp_list[context.task_index]);
173 EXPECT_EQ(may_run, expected_may_run);
174
175 if (may_run)
176 context.is_pending_task = true;
177
178 context.task_index++;
179 pattern_index_ = next_pattern_index;
180 base::MessageLoopProxy::current()->PostTask(
181 FROM_HERE,
182 base::Bind(&BalancedMediaTaskRunnerTest::ScheduleTask,
183 base::Unretained(this)));
184 }
185
186 void BalancedMediaTaskRunnerTest::Task(
187 size_t task_runner_id, base::TimeDelta timestamp) {
188 ASSERT_FALSE(expected_task_timestamps_.empty());
189 EXPECT_EQ(timestamp, expected_task_timestamps_.front());
190 expected_task_timestamps_.pop_front();
191
192 contexts_[task_runner_id].is_pending_task = false;
193 }
194
195 void BalancedMediaTaskRunnerTest::OnTestTimeout() {
196 ADD_FAILURE() << "Test timed out";
197 if (base::MessageLoop::current())
198 base::MessageLoop::current()->QuitWhenIdle();
199 }
200
201 TEST_F(BalancedMediaTaskRunnerTest, OneTaskRunner) {
202 scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
203
204 // Timestamps of tasks for the single task runner.
205 int timestamps0_ms[] = {0, 10, 20, 30, 40, 30, 50, 60, 20, 30, 70};
206 std::vector<std::vector<int> > timestamps_ms(1);
207 timestamps_ms[0] = std::vector<int>(
208 timestamps0_ms, timestamps0_ms + arraysize(timestamps0_ms));
209
210 // Scheduling pattern.
211 std::vector<size_t> scheduling_pattern(1);
212 scheduling_pattern[0] = 0;
213
214 // Expected results.
215 int expected_timestamps[] = {0, 10, 20, 30, 40, 50, 60, 70};
216 std::vector<int> expected_timestamps_ms(std::vector<int>(
217 expected_timestamps,
218 expected_timestamps + arraysize(expected_timestamps)));
219
220 SetupTest(base::TimeDelta::FromMilliseconds(30),
221 timestamps_ms,
222 scheduling_pattern,
223 expected_timestamps_ms);
224 ProcessAllTasks();
225 message_loop->Run();
226 EXPECT_TRUE(expected_task_timestamps_.empty());
227 }
228
229 TEST_F(BalancedMediaTaskRunnerTest, TwoTaskRunnerUnbalanced) {
230 scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
231
232 // Timestamps of tasks for the 2 task runners.
233 int timestamps0_ms[] = {0, 10, 20, 30, 40, 30, 50, 60, 20, 30, 70};
234 int timestamps1_ms[] = {5, 15, 25, 35, 45, 35, 55, 65, 25, 35, 75};
235 std::vector<std::vector<int> > timestamps_ms(2);
236 timestamps_ms[0] = std::vector<int>(
237 timestamps0_ms, timestamps0_ms + arraysize(timestamps0_ms));
238 timestamps_ms[1] = std::vector<int>(
239 timestamps1_ms, timestamps1_ms + arraysize(timestamps1_ms));
240
241 // Scheduling pattern.
242 size_t pattern[] = {1, 0, 0, 0, 0};
243 std::vector<size_t> scheduling_pattern = std::vector<size_t>(
244 pattern, pattern + arraysize(pattern));
245
246 // Expected results.
247 int expected_timestamps[] = {
248 5, 0, 10, 20, 30, 15, 40, 25, 50, 35, 60, 45, 70, 55, 65, 75 };
249 std::vector<int> expected_timestamps_ms(std::vector<int>(
250 expected_timestamps,
251 expected_timestamps + arraysize(expected_timestamps)));
252
253 SetupTest(base::TimeDelta::FromMilliseconds(30),
254 timestamps_ms,
255 scheduling_pattern,
256 expected_timestamps_ms);
257 ProcessAllTasks();
258 message_loop->Run();
259 EXPECT_TRUE(expected_task_timestamps_.empty());
260 }
261
262 } // namespace media
263 } // namespace chromecast
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698