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

Unified 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: Address CR comments from patch set #1. 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 side-by-side diff with in-line comments
Download patch
Index: chromecast/media/cma/base/balanced_media_task_runner_unittest.cc
diff --git a/chromecast/media/cma/base/balanced_media_task_runner_unittest.cc b/chromecast/media/cma/base/balanced_media_task_runner_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e3448f67cace9f3c947a84af3e709f5a25febad2
--- /dev/null
+++ b/chromecast/media/cma/base/balanced_media_task_runner_unittest.cc
@@ -0,0 +1,263 @@
+// Copyright 2014 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 <list>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/threading/thread.h"
+#include "base/time/time.h"
+#include "chromecast/media/cma/base/balanced_media_task_runner_factory.h"
+#include "chromecast/media/cma/base/media_task_runner.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromecast {
+namespace media {
+
+namespace {
+
+struct MediaTaskRunnerTestContext {
+ MediaTaskRunnerTestContext();
+ ~MediaTaskRunnerTestContext();
+
+ scoped_refptr<MediaTaskRunner> media_task_runner;
+
+ bool is_pending_task;
+
+ std::vector<base::TimeDelta> task_timestamp_list;
+
+ size_t task_index;
+ base::TimeDelta max_timestamp;
+};
+
+MediaTaskRunnerTestContext::MediaTaskRunnerTestContext() {
+}
+
+MediaTaskRunnerTestContext::~MediaTaskRunnerTestContext() {
+}
+
+} // namespace
+
+class BalancedMediaTaskRunnerTest : public testing::Test {
+ public:
+ BalancedMediaTaskRunnerTest();
+ virtual ~BalancedMediaTaskRunnerTest();
+
+ void SetupTest(base::TimeDelta max_delta,
+ const std::vector<std::vector<int> >& timestamps_in_ms,
+ const std::vector<size_t>& pattern,
+ const std::vector<int>& expected_task_timestamps_ms);
+ void ProcessAllTasks();
+
+ protected:
+ // Expected task order based on their timestamps.
+ std::list<base::TimeDelta> expected_task_timestamps_;
+
+ private:
+ void ScheduleTask();
+ void Task(size_t task_runner_id, base::TimeDelta timestamp);
+
+ void OnTestTimeout();
+
+ scoped_refptr<BalancedMediaTaskRunnerFactory> media_task_runner_factory_;
+
+ // Schedule first a task on media task runner #scheduling_pattern[0]
+ // then a task on media task runner #scheduling_pattern[1] and so on.
+ // Wrap around when reaching the end of the pattern.
+ std::vector<size_t> scheduling_pattern_;
+ size_t pattern_index_;
+
+ // For each media task runner, keep a track of which task has already been
+ // scheduled.
+ std::vector<MediaTaskRunnerTestContext> contexts_;
+
+ DISALLOW_COPY_AND_ASSIGN(BalancedMediaTaskRunnerTest);
+};
+
+BalancedMediaTaskRunnerTest::BalancedMediaTaskRunnerTest() {
+}
+
+BalancedMediaTaskRunnerTest::~BalancedMediaTaskRunnerTest() {
+}
+
+void BalancedMediaTaskRunnerTest::SetupTest(
+ base::TimeDelta max_delta,
+ const std::vector<std::vector<int> >& timestamps_in_ms,
+ const std::vector<size_t>& pattern,
+ const std::vector<int>& expected_task_timestamps_ms) {
+ media_task_runner_factory_ = new BalancedMediaTaskRunnerFactory(max_delta);
+
+ scheduling_pattern_ = pattern;
+ pattern_index_ = 0;
+
+ // Setup each task runner.
+ size_t n = timestamps_in_ms.size();
+ contexts_.resize(n);
+ for (size_t k = 0; k < n; k++) {
+ contexts_[k].media_task_runner =
+ media_task_runner_factory_->CreateMediaTaskRunner(
+ base::MessageLoopProxy::current());
+ contexts_[k].is_pending_task = false;
+ contexts_[k].task_index = 0;
+ contexts_[k].task_timestamp_list.resize(
+ timestamps_in_ms[k].size());
+ for (size_t i = 0; i < timestamps_in_ms[k].size(); i++) {
+ contexts_[k].task_timestamp_list[i] =
+ base::TimeDelta::FromMilliseconds(timestamps_in_ms[k][i]);
+ }
+ }
+
+ // Expected task order (for tasks that are actually run).
+ for (size_t k = 0; k < expected_task_timestamps_ms.size(); k++) {
+ expected_task_timestamps_.push_back(
+ base::TimeDelta::FromMilliseconds(expected_task_timestamps_ms[k]));
+ }
+}
+
+void BalancedMediaTaskRunnerTest::ProcessAllTasks() {
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&BalancedMediaTaskRunnerTest::OnTestTimeout,
+ base::Unretained(this)),
+ base::TimeDelta::FromSeconds(5));
+ ScheduleTask();
+}
+
+void BalancedMediaTaskRunnerTest::ScheduleTask() {
+ bool has_task = false;
+ for (size_t k = 0; k < contexts_.size(); k++) {
+ if (contexts_[k].task_index < contexts_[k].task_timestamp_list.size())
+ has_task = true;
+ }
+ if (!has_task) {
+ base::MessageLoop::current()->QuitWhenIdle();
+ return;
+ }
+
+ size_t next_pattern_index =
+ (pattern_index_ + 1) % scheduling_pattern_.size();
+
+ size_t task_runner_id = scheduling_pattern_[pattern_index_];
+ MediaTaskRunnerTestContext& context = contexts_[task_runner_id];
+
+ // Check whether all tasks have been scheduled for that task runner
+ // or if there is already one pending task.
+ if (context.task_index >= context.task_timestamp_list.size() ||
+ context.is_pending_task) {
+ pattern_index_ = next_pattern_index;
+ base::MessageLoopProxy::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&BalancedMediaTaskRunnerTest::ScheduleTask,
+ base::Unretained(this)));
+ return;
+ }
+
+ bool expected_may_run = false;
+ if (context.task_timestamp_list[context.task_index] >=
+ context.max_timestamp) {
+ expected_may_run = true;
+ context.max_timestamp = context.task_timestamp_list[context.task_index];
+ }
+
+ bool may_run = context.media_task_runner->PostMediaTask(
+ FROM_HERE,
+ base::Bind(&BalancedMediaTaskRunnerTest::Task,
+ base::Unretained(this),
+ task_runner_id,
+ context.task_timestamp_list[context.task_index]),
+ context.task_timestamp_list[context.task_index]);
+ EXPECT_EQ(may_run, expected_may_run);
+
+ if (may_run)
+ context.is_pending_task = true;
+
+ context.task_index++;
+ pattern_index_ = next_pattern_index;
+ base::MessageLoopProxy::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&BalancedMediaTaskRunnerTest::ScheduleTask,
+ base::Unretained(this)));
+}
+
+void BalancedMediaTaskRunnerTest::Task(
+ size_t task_runner_id, base::TimeDelta timestamp) {
+ ASSERT_FALSE(expected_task_timestamps_.empty());
+ EXPECT_EQ(timestamp, expected_task_timestamps_.front());
+ expected_task_timestamps_.pop_front();
+
+ contexts_[task_runner_id].is_pending_task = false;
+}
+
+void BalancedMediaTaskRunnerTest::OnTestTimeout() {
+ ADD_FAILURE() << "Test timed out";
+ if (base::MessageLoop::current())
+ base::MessageLoop::current()->QuitWhenIdle();
+}
+
+TEST_F(BalancedMediaTaskRunnerTest, OneTaskRunner) {
+ scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
+ // Timestamps of tasks for the single task runner.
+ int timestamps0_ms[] = {0, 10, 20, 30, 40, 30, 50, 60, 20, 30, 70};
+ std::vector<std::vector<int> > timestamps_ms(1);
+ timestamps_ms[0] = std::vector<int>(
+ timestamps0_ms, timestamps0_ms + arraysize(timestamps0_ms));
+
+ // Scheduling pattern.
+ std::vector<size_t> scheduling_pattern(1);
+ scheduling_pattern[0] = 0;
+
+ // Expected results.
+ int expected_timestamps[] = {0, 10, 20, 30, 40, 50, 60, 70};
+ std::vector<int> expected_timestamps_ms(std::vector<int>(
+ expected_timestamps,
+ expected_timestamps + arraysize(expected_timestamps)));
+
+ SetupTest(base::TimeDelta::FromMilliseconds(30),
+ timestamps_ms,
+ scheduling_pattern,
+ expected_timestamps_ms);
+ ProcessAllTasks();
+ message_loop->Run();
+ EXPECT_TRUE(expected_task_timestamps_.empty());
+}
+
+TEST_F(BalancedMediaTaskRunnerTest, TwoTaskRunnerUnbalanced) {
+ scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
+ // Timestamps of tasks for the 2 task runners.
+ int timestamps0_ms[] = {0, 10, 20, 30, 40, 30, 50, 60, 20, 30, 70};
+ int timestamps1_ms[] = {5, 15, 25, 35, 45, 35, 55, 65, 25, 35, 75};
+ std::vector<std::vector<int> > timestamps_ms(2);
+ timestamps_ms[0] = std::vector<int>(
+ timestamps0_ms, timestamps0_ms + arraysize(timestamps0_ms));
+ timestamps_ms[1] = std::vector<int>(
+ timestamps1_ms, timestamps1_ms + arraysize(timestamps1_ms));
+
+ // Scheduling pattern.
+ size_t pattern[] = {1, 0, 0, 0, 0};
+ std::vector<size_t> scheduling_pattern = std::vector<size_t>(
+ pattern, pattern + arraysize(pattern));
+
+ // Expected results.
+ int expected_timestamps[] = {
+ 5, 0, 10, 20, 30, 15, 40, 25, 50, 35, 60, 45, 70, 55, 65, 75 };
+ std::vector<int> expected_timestamps_ms(std::vector<int>(
+ expected_timestamps,
+ expected_timestamps + arraysize(expected_timestamps)));
+
+ SetupTest(base::TimeDelta::FromMilliseconds(30),
+ timestamps_ms,
+ scheduling_pattern,
+ expected_timestamps_ms);
+ ProcessAllTasks();
+ message_loop->Run();
+ EXPECT_TRUE(expected_task_timestamps_.empty());
+}
+
+} // namespace media
+} // namespace chromecast

Powered by Google App Engine
This is Rietveld 408576698