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

Unified Diff: base/mac/libdispatch_task_runner_unittest.cc

Issue 11464009: Create LibDispatchTaskRunner, a SingleThreadTaskRunner that is backed by a libdispatch queue. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: BASE_EXPORT Created 8 years 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 | « base/mac/libdispatch_task_runner.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/mac/libdispatch_task_runner_unittest.cc
diff --git a/base/mac/libdispatch_task_runner_unittest.cc b/base/mac/libdispatch_task_runner_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e939e49ad234df077719153001265179ca3c0df3
--- /dev/null
+++ b/base/mac/libdispatch_task_runner_unittest.cc
@@ -0,0 +1,201 @@
+// Copyright (c) 2012 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 "base/mac/libdispatch_task_runner.h"
+
+#include "base/bind.h"
+#include "base/mac/bind_objc_block.h"
+#include "base/message_loop.h"
+#include "base/stringprintf.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class LibDispatchTaskRunnerTest : public testing::Test {
+ public:
+ virtual void SetUp() OVERRIDE {
+ task_runner_ = new base::mac::LibDispatchTaskRunner(
+ "org.chromium.LibDispatchTaskRunnerTest");
+ }
+
+ // DispatchLastTask is used to run the main test thread's MessageLoop until
+ // all non-delayed tasks are run on the LibDispatchTaskRunner.
+ void DispatchLastTask() {
+ dispatch_async(task_runner_->GetDispatchQueue(), ^{
+ (&message_loop_)->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ });
+ message_loop_.Run();
+ }
+
+ // VerifyTaskOrder takes the expectations from TaskOrderMarkers and compares
+ // them against the recorded values.
+ void VerifyTaskOrder(const char* const expectations[],
+ size_t num_expectations) {
+ size_t actual_size = task_order_.size();
+
+ for (size_t i = 0; i < num_expectations; ++i) {
+ if (i >= actual_size) {
+ EXPECT_LT(i, actual_size) << "Expected " << expectations[i];
+ continue;
+ }
+
+ EXPECT_EQ(expectations[i], task_order_[i]);
+ }
+
+ if (actual_size > num_expectations) {
+ EXPECT_LE(actual_size, num_expectations) << "Extra tasks were run:";
+ for (size_t i = num_expectations; i < actual_size; ++i) {
+ EXPECT_EQ("<none>", task_order_[i]) << " (i=" << i << ")";
+ }
+ }
+ }
+
+ // The message loop for the test main thread.
+ MessageLoop message_loop_;
+
+ // The task runner under test.
+ scoped_refptr<base::mac::LibDispatchTaskRunner> task_runner_;
+
+ // Vector that records data from TaskOrderMarker.
+ std::vector<std::string> task_order_;
+};
+
+// Scoper that records the beginning and end of a running task.
+class TaskOrderMarker {
+ public:
+ TaskOrderMarker(LibDispatchTaskRunnerTest* test, const std::string& name)
+ : test_(test),
+ name_(name) {
+ test->task_order_.push_back(std::string("BEGIN ") + name);
+ }
+ ~TaskOrderMarker() {
+ test_->task_order_.push_back(std::string("END ") + name_);
+ }
+
+ private:
+ LibDispatchTaskRunnerTest* test_;
+ std::string name_;
+};
+
+void RecordTaskOrder(LibDispatchTaskRunnerTest* test, const std::string& name) {
+ TaskOrderMarker marker(test, name);
+}
+
+// Returns a closure that records the task order.
+base::Closure BoundRecordTaskOrder(LibDispatchTaskRunnerTest* test,
+ const std::string& name) {
+ return base::Bind(&RecordTaskOrder, base::Unretained(test), name);
+}
+
+TEST_F(LibDispatchTaskRunnerTest, PostTask) {
+ task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "Basic Task"));
+ DispatchLastTask();
+ const char* const expectations[] = {
+ "BEGIN Basic Task",
+ "END Basic Task"
+ };
+ VerifyTaskOrder(expectations, arraysize(expectations));
+}
+
+TEST_F(LibDispatchTaskRunnerTest, PostTaskWithinTask) {
+ task_runner_->PostTask(FROM_HERE, base::BindBlock(^{
+ TaskOrderMarker marker(this, "Outer");
+ task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "Inner"));
+ }));
+ DispatchLastTask();
+
+ const char* const expectations[] = {
+ "BEGIN Outer",
+ "END Outer",
+ "BEGIN Inner",
+ "END Inner"
+ };
+ VerifyTaskOrder(expectations, arraysize(expectations));
+}
+
+TEST_F(LibDispatchTaskRunnerTest, NoMessageLoop) {
+ task_runner_->PostTask(FROM_HERE, base::BindBlock(^{
+ TaskOrderMarker marker(this,
+ base::StringPrintf("MessageLoop = %p", MessageLoop::current()));
+ }));
+ DispatchLastTask();
+
+ const char* const expectations[] = {
+ "BEGIN MessageLoop = 0x0",
+ "END MessageLoop = 0x0"
+ };
+ VerifyTaskOrder(expectations, arraysize(expectations));
+}
+
+TEST_F(LibDispatchTaskRunnerTest, DispatchAndPostTasks) {
+ dispatch_async(task_runner_->GetDispatchQueue(), ^{
+ TaskOrderMarker marker(this, "First Block");
+ task_runner_->PostTask(FROM_HERE,
+ BoundRecordTaskOrder(this, "Second Task"));
+ });
+ task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "First Task"));
+ dispatch_async(task_runner_->GetDispatchQueue(), ^{
+ TaskOrderMarker marker(this, "Second Block");
+ });
+ DispatchLastTask();
+
+ const char* const expectations[] = {
+ "BEGIN First Block",
+ "END First Block",
+ "BEGIN First Task",
+ "END First Task",
+ "BEGIN Second Block",
+ "END Second Block",
+ "BEGIN Second Task",
+ "END Second Task",
+ };
+ VerifyTaskOrder(expectations, arraysize(expectations));
+}
+
+TEST_F(LibDispatchTaskRunnerTest, NonNestable) {
+ task_runner_->PostTask(FROM_HERE, base::BindBlock(^{
+ TaskOrderMarker marker(this, "First");
+ task_runner_->PostNonNestableTask(FROM_HERE, base::BindBlock(^{
+ TaskOrderMarker marker(this, "Third NonNestable");
+ }));
+ }));
+ task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "Second"));
+ DispatchLastTask();
+
+ const char* const expectations[] = {
+ "BEGIN First",
+ "END First",
+ "BEGIN Second",
+ "END Second",
+ "BEGIN Third NonNestable",
+ "END Third NonNestable"
+ };
+ VerifyTaskOrder(expectations, arraysize(expectations));
+}
+
+TEST_F(LibDispatchTaskRunnerTest, PostDelayed) {
+ base::TimeTicks post_time;
+ __block base::TimeTicks run_time;
+ const base::TimeDelta delta = base::TimeDelta::FromMilliseconds(50);
+
+ task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "First"));
+ post_time = base::TimeTicks::Now();
+ task_runner_->PostDelayedTask(FROM_HERE, base::BindBlock(^{
+ TaskOrderMarker marker(this, "Timed");
+ run_time = base::TimeTicks::Now();
+ (&message_loop_)->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ }), delta);
+ task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "Second"));
+ message_loop_.Run();
+
+ const char* const expectations[] = {
+ "BEGIN First",
+ "END First",
+ "BEGIN Second",
+ "END Second",
+ "BEGIN Timed",
+ "END Timed",
+ };
+ VerifyTaskOrder(expectations, arraysize(expectations));
+
+ EXPECT_GE(run_time, post_time + delta);
+}
« no previous file with comments | « base/mac/libdispatch_task_runner.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698