| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/mac/libdispatch_task_runner.h" | 5 #include "base/mac/libdispatch_task_runner.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/mac/bind_objc_block.h" | 8 #include "base/mac/bind_objc_block.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
| 11 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
| 12 | 12 |
| 13 class LibDispatchTaskRunnerTest : public testing::Test { | 13 class LibDispatchTaskRunnerTest : public testing::Test { |
| 14 public: | 14 public: |
| 15 virtual void SetUp() OVERRIDE { | 15 virtual void SetUp() OVERRIDE { |
| 16 task_runner_ = new base::mac::LibDispatchTaskRunner( | 16 task_runner_ = new base::mac::LibDispatchTaskRunner( |
| 17 "org.chromium.LibDispatchTaskRunnerTest"); | 17 "org.chromium.LibDispatchTaskRunnerTest"); |
| 18 } | 18 } |
| 19 | 19 |
| 20 // DispatchLastTask is used to run the main test thread's MessageLoop until | 20 // DispatchLastTask is used to run the main test thread's MessageLoop until |
| 21 // all non-delayed tasks are run on the LibDispatchTaskRunner. | 21 // all non-delayed tasks are run on the LibDispatchTaskRunner. |
| 22 void DispatchLastTask() { | 22 void DispatchLastTask() { |
| 23 dispatch_async(task_runner_->GetDispatchQueue(), ^{ | 23 dispatch_async(task_runner_->GetDispatchQueue(), ^{ |
| 24 (&message_loop_)->PostTask(FROM_HERE, | 24 (&message_loop_)->PostTask(FROM_HERE, |
| 25 MessageLoop::QuitWhenIdleClosure()); | 25 base::MessageLoop::QuitWhenIdleClosure()); |
| 26 }); | 26 }); |
| 27 message_loop_.Run(); | 27 message_loop_.Run(); |
| 28 task_runner_->Shutdown(); | 28 task_runner_->Shutdown(); |
| 29 } | 29 } |
| 30 | 30 |
| 31 // VerifyTaskOrder takes the expectations from TaskOrderMarkers and compares | 31 // VerifyTaskOrder takes the expectations from TaskOrderMarkers and compares |
| 32 // them against the recorded values. | 32 // them against the recorded values. |
| 33 void VerifyTaskOrder(const char* const expectations[], | 33 void VerifyTaskOrder(const char* const expectations[], |
| 34 size_t num_expectations) { | 34 size_t num_expectations) { |
| 35 size_t actual_size = task_order_.size(); | 35 size_t actual_size = task_order_.size(); |
| 36 | 36 |
| 37 for (size_t i = 0; i < num_expectations; ++i) { | 37 for (size_t i = 0; i < num_expectations; ++i) { |
| 38 if (i >= actual_size) { | 38 if (i >= actual_size) { |
| 39 EXPECT_LE(i, actual_size) << "Expected " << expectations[i]; | 39 EXPECT_LE(i, actual_size) << "Expected " << expectations[i]; |
| 40 continue; | 40 continue; |
| 41 } | 41 } |
| 42 | 42 |
| 43 EXPECT_EQ(expectations[i], task_order_[i]); | 43 EXPECT_EQ(expectations[i], task_order_[i]); |
| 44 } | 44 } |
| 45 | 45 |
| 46 if (actual_size > num_expectations) { | 46 if (actual_size > num_expectations) { |
| 47 EXPECT_LE(actual_size, num_expectations) << "Extra tasks were run:"; | 47 EXPECT_LE(actual_size, num_expectations) << "Extra tasks were run:"; |
| 48 for (size_t i = num_expectations; i < actual_size; ++i) { | 48 for (size_t i = num_expectations; i < actual_size; ++i) { |
| 49 EXPECT_EQ("<none>", task_order_[i]) << " (i=" << i << ")"; | 49 EXPECT_EQ("<none>", task_order_[i]) << " (i=" << i << ")"; |
| 50 } | 50 } |
| 51 } | 51 } |
| 52 } | 52 } |
| 53 | 53 |
| 54 // The message loop for the test main thread. | 54 // The message loop for the test main thread. |
| 55 MessageLoop message_loop_; | 55 base::MessageLoop message_loop_; |
| 56 | 56 |
| 57 // The task runner under test. | 57 // The task runner under test. |
| 58 scoped_refptr<base::mac::LibDispatchTaskRunner> task_runner_; | 58 scoped_refptr<base::mac::LibDispatchTaskRunner> task_runner_; |
| 59 | 59 |
| 60 // Vector that records data from TaskOrderMarker. | 60 // Vector that records data from TaskOrderMarker. |
| 61 std::vector<std::string> task_order_; | 61 std::vector<std::string> task_order_; |
| 62 }; | 62 }; |
| 63 | 63 |
| 64 // Scoper that records the beginning and end of a running task. | 64 // Scoper that records the beginning and end of a running task. |
| 65 class TaskOrderMarker { | 65 class TaskOrderMarker { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 "END Outer", | 110 "END Outer", |
| 111 "BEGIN Inner", | 111 "BEGIN Inner", |
| 112 "END Inner" | 112 "END Inner" |
| 113 }; | 113 }; |
| 114 VerifyTaskOrder(expectations, arraysize(expectations)); | 114 VerifyTaskOrder(expectations, arraysize(expectations)); |
| 115 } | 115 } |
| 116 | 116 |
| 117 TEST_F(LibDispatchTaskRunnerTest, NoMessageLoop) { | 117 TEST_F(LibDispatchTaskRunnerTest, NoMessageLoop) { |
| 118 task_runner_->PostTask(FROM_HERE, base::BindBlock(^{ | 118 task_runner_->PostTask(FROM_HERE, base::BindBlock(^{ |
| 119 TaskOrderMarker marker(this, | 119 TaskOrderMarker marker(this, |
| 120 base::StringPrintf("MessageLoop = %p", MessageLoop::current())); | 120 base::StringPrintf("MessageLoop = %p", base::MessageLoop::current())); |
| 121 })); | 121 })); |
| 122 DispatchLastTask(); | 122 DispatchLastTask(); |
| 123 | 123 |
| 124 const char* const expectations[] = { | 124 const char* const expectations[] = { |
| 125 "BEGIN MessageLoop = 0x0", | 125 "BEGIN MessageLoop = 0x0", |
| 126 "END MessageLoop = 0x0" | 126 "END MessageLoop = 0x0" |
| 127 }; | 127 }; |
| 128 VerifyTaskOrder(expectations, arraysize(expectations)); | 128 VerifyTaskOrder(expectations, arraysize(expectations)); |
| 129 } | 129 } |
| 130 | 130 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 151 }; | 151 }; |
| 152 VerifyTaskOrder(expectations, arraysize(expectations)); | 152 VerifyTaskOrder(expectations, arraysize(expectations)); |
| 153 } | 153 } |
| 154 | 154 |
| 155 TEST_F(LibDispatchTaskRunnerTest, NonNestable) { | 155 TEST_F(LibDispatchTaskRunnerTest, NonNestable) { |
| 156 task_runner_->PostTask(FROM_HERE, base::BindBlock(^{ | 156 task_runner_->PostTask(FROM_HERE, base::BindBlock(^{ |
| 157 TaskOrderMarker marker(this, "First"); | 157 TaskOrderMarker marker(this, "First"); |
| 158 task_runner_->PostNonNestableTask(FROM_HERE, base::BindBlock(^{ | 158 task_runner_->PostNonNestableTask(FROM_HERE, base::BindBlock(^{ |
| 159 TaskOrderMarker marker(this, "Second NonNestable"); | 159 TaskOrderMarker marker(this, "Second NonNestable"); |
| 160 (&message_loop_)->PostTask(FROM_HERE, | 160 (&message_loop_)->PostTask(FROM_HERE, |
| 161 MessageLoop::QuitWhenIdleClosure()); | 161 base::MessageLoop::QuitWhenIdleClosure()); |
| 162 })); | 162 })); |
| 163 })); | 163 })); |
| 164 message_loop_.Run(); | 164 message_loop_.Run(); |
| 165 task_runner_->Shutdown(); | 165 task_runner_->Shutdown(); |
| 166 | 166 |
| 167 const char* const expectations[] = { | 167 const char* const expectations[] = { |
| 168 "BEGIN First", | 168 "BEGIN First", |
| 169 "END First", | 169 "END First", |
| 170 "BEGIN Second NonNestable", | 170 "BEGIN Second NonNestable", |
| 171 "END Second NonNestable" | 171 "END Second NonNestable" |
| 172 }; | 172 }; |
| 173 VerifyTaskOrder(expectations, arraysize(expectations)); | 173 VerifyTaskOrder(expectations, arraysize(expectations)); |
| 174 } | 174 } |
| 175 | 175 |
| 176 TEST_F(LibDispatchTaskRunnerTest, PostDelayed) { | 176 TEST_F(LibDispatchTaskRunnerTest, PostDelayed) { |
| 177 base::TimeTicks post_time; | 177 base::TimeTicks post_time; |
| 178 __block base::TimeTicks run_time; | 178 __block base::TimeTicks run_time; |
| 179 const base::TimeDelta delta = base::TimeDelta::FromMilliseconds(50); | 179 const base::TimeDelta delta = base::TimeDelta::FromMilliseconds(50); |
| 180 | 180 |
| 181 task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "First")); | 181 task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "First")); |
| 182 post_time = base::TimeTicks::Now(); | 182 post_time = base::TimeTicks::Now(); |
| 183 task_runner_->PostDelayedTask(FROM_HERE, base::BindBlock(^{ | 183 task_runner_->PostDelayedTask(FROM_HERE, base::BindBlock(^{ |
| 184 TaskOrderMarker marker(this, "Timed"); | 184 TaskOrderMarker marker(this, "Timed"); |
| 185 run_time = base::TimeTicks::Now(); | 185 run_time = base::TimeTicks::Now(); |
| 186 (&message_loop_)->PostTask(FROM_HERE, MessageLoop::QuitWhenIdleClosure()); | 186 (&message_loop_)->PostTask(FROM_HERE, |
| 187 base::MessageLoop::QuitWhenIdleClosure()); |
| 187 }), delta); | 188 }), delta); |
| 188 task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "Second")); | 189 task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "Second")); |
| 189 message_loop_.Run(); | 190 message_loop_.Run(); |
| 190 task_runner_->Shutdown(); | 191 task_runner_->Shutdown(); |
| 191 | 192 |
| 192 const char* const expectations[] = { | 193 const char* const expectations[] = { |
| 193 "BEGIN First", | 194 "BEGIN First", |
| 194 "END First", | 195 "END First", |
| 195 "BEGIN Second", | 196 "BEGIN Second", |
| 196 "END Second", | 197 "END Second", |
| (...skipping 17 matching lines...) Expand all Loading... |
| 214 }))); | 215 }))); |
| 215 | 216 |
| 216 const char* const expectations[] = { | 217 const char* const expectations[] = { |
| 217 "BEGIN First", | 218 "BEGIN First", |
| 218 "END First", | 219 "END First", |
| 219 "BEGIN Second", | 220 "BEGIN Second", |
| 220 "END Second" | 221 "END Second" |
| 221 }; | 222 }; |
| 222 VerifyTaskOrder(expectations, arraysize(expectations)); | 223 VerifyTaskOrder(expectations, arraysize(expectations)); |
| 223 } | 224 } |
| OLD | NEW |