| 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, MessageLoop::QuitClosure()); | 24 (&message_loop_)->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| 25 }); | 25 }); |
| 26 message_loop_.Run(); | 26 message_loop_.Run(); |
| 27 task_runner_->Shutdown(); |
| 27 } | 28 } |
| 28 | 29 |
| 29 // VerifyTaskOrder takes the expectations from TaskOrderMarkers and compares | 30 // VerifyTaskOrder takes the expectations from TaskOrderMarkers and compares |
| 30 // them against the recorded values. | 31 // them against the recorded values. |
| 31 void VerifyTaskOrder(const char* const expectations[], | 32 void VerifyTaskOrder(const char* const expectations[], |
| 32 size_t num_expectations) { | 33 size_t num_expectations) { |
| 33 size_t actual_size = task_order_.size(); | 34 size_t actual_size = task_order_.size(); |
| 34 | 35 |
| 35 for (size_t i = 0; i < num_expectations; ++i) { | 36 for (size_t i = 0; i < num_expectations; ++i) { |
| 36 if (i >= actual_size) { | 37 if (i >= actual_size) { |
| 37 EXPECT_LT(i, actual_size) << "Expected " << expectations[i]; | 38 EXPECT_LE(i, actual_size) << "Expected " << expectations[i]; |
| 38 continue; | 39 continue; |
| 39 } | 40 } |
| 40 | 41 |
| 41 EXPECT_EQ(expectations[i], task_order_[i]); | 42 EXPECT_EQ(expectations[i], task_order_[i]); |
| 42 } | 43 } |
| 43 | 44 |
| 44 if (actual_size > num_expectations) { | 45 if (actual_size > num_expectations) { |
| 45 EXPECT_LE(actual_size, num_expectations) << "Extra tasks were run:"; | 46 EXPECT_LE(actual_size, num_expectations) << "Extra tasks were run:"; |
| 46 for (size_t i = num_expectations; i < actual_size; ++i) { | 47 for (size_t i = num_expectations; i < actual_size; ++i) { |
| 47 EXPECT_EQ("<none>", task_order_[i]) << " (i=" << i << ")"; | 48 EXPECT_EQ("<none>", task_order_[i]) << " (i=" << i << ")"; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 })); | 120 })); |
| 120 DispatchLastTask(); | 121 DispatchLastTask(); |
| 121 | 122 |
| 122 const char* const expectations[] = { | 123 const char* const expectations[] = { |
| 123 "BEGIN MessageLoop = 0x0", | 124 "BEGIN MessageLoop = 0x0", |
| 124 "END MessageLoop = 0x0" | 125 "END MessageLoop = 0x0" |
| 125 }; | 126 }; |
| 126 VerifyTaskOrder(expectations, arraysize(expectations)); | 127 VerifyTaskOrder(expectations, arraysize(expectations)); |
| 127 } | 128 } |
| 128 | 129 |
| 129 // This test is flaky, see http://crbug.com/165117. | 130 TEST_F(LibDispatchTaskRunnerTest, DispatchAndPostTasks) { |
| 130 TEST_F(LibDispatchTaskRunnerTest, FLAKY_DispatchAndPostTasks) { | |
| 131 dispatch_async(task_runner_->GetDispatchQueue(), ^{ | 131 dispatch_async(task_runner_->GetDispatchQueue(), ^{ |
| 132 TaskOrderMarker marker(this, "First Block"); | 132 TaskOrderMarker marker(this, "First Block"); |
| 133 task_runner_->PostTask(FROM_HERE, | |
| 134 BoundRecordTaskOrder(this, "Second Task")); | |
| 135 }); | 133 }); |
| 136 task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "First Task")); | 134 task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "First Task")); |
| 137 dispatch_async(task_runner_->GetDispatchQueue(), ^{ | 135 dispatch_async(task_runner_->GetDispatchQueue(), ^{ |
| 138 TaskOrderMarker marker(this, "Second Block"); | 136 TaskOrderMarker marker(this, "Second Block"); |
| 139 }); | 137 }); |
| 138 task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "Second Task")); |
| 140 DispatchLastTask(); | 139 DispatchLastTask(); |
| 141 | 140 |
| 142 const char* const expectations[] = { | 141 const char* const expectations[] = { |
| 143 "BEGIN First Block", | 142 "BEGIN First Block", |
| 144 "END First Block", | 143 "END First Block", |
| 145 "BEGIN First Task", | 144 "BEGIN First Task", |
| 146 "END First Task", | 145 "END First Task", |
| 147 "BEGIN Second Block", | 146 "BEGIN Second Block", |
| 148 "END Second Block", | 147 "END Second Block", |
| 149 "BEGIN Second Task", | 148 "BEGIN Second Task", |
| 150 "END Second Task", | 149 "END Second Task", |
| 151 }; | 150 }; |
| 152 VerifyTaskOrder(expectations, arraysize(expectations)); | 151 VerifyTaskOrder(expectations, arraysize(expectations)); |
| 153 } | 152 } |
| 154 | 153 |
| 155 // This test is flaky, see http://crbug.com/165118. | 154 TEST_F(LibDispatchTaskRunnerTest, NonNestable) { |
| 156 TEST_F(LibDispatchTaskRunnerTest, FLAKY_NonNestable) { | |
| 157 task_runner_->PostTask(FROM_HERE, base::BindBlock(^{ | 155 task_runner_->PostTask(FROM_HERE, base::BindBlock(^{ |
| 158 TaskOrderMarker marker(this, "First"); | 156 TaskOrderMarker marker(this, "First"); |
| 159 task_runner_->PostNonNestableTask(FROM_HERE, base::BindBlock(^{ | 157 task_runner_->PostNonNestableTask(FROM_HERE, base::BindBlock(^{ |
| 160 TaskOrderMarker marker(this, "Third NonNestable"); | 158 TaskOrderMarker marker(this, "Second NonNestable"); |
| 159 (&message_loop_)->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| 161 })); | 160 })); |
| 162 })); | 161 })); |
| 163 task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "Second")); | 162 message_loop_.Run(); |
| 164 DispatchLastTask(); | 163 task_runner_->Shutdown(); |
| 165 | 164 |
| 166 const char* const expectations[] = { | 165 const char* const expectations[] = { |
| 167 "BEGIN First", | 166 "BEGIN First", |
| 168 "END First", | 167 "END First", |
| 169 "BEGIN Second", | 168 "BEGIN Second NonNestable", |
| 170 "END Second", | 169 "END Second NonNestable" |
| 171 "BEGIN Third NonNestable", | |
| 172 "END Third NonNestable" | |
| 173 }; | 170 }; |
| 174 VerifyTaskOrder(expectations, arraysize(expectations)); | 171 VerifyTaskOrder(expectations, arraysize(expectations)); |
| 175 } | 172 } |
| 176 | 173 |
| 177 TEST_F(LibDispatchTaskRunnerTest, PostDelayed) { | 174 TEST_F(LibDispatchTaskRunnerTest, PostDelayed) { |
| 178 base::TimeTicks post_time; | 175 base::TimeTicks post_time; |
| 179 __block base::TimeTicks run_time; | 176 __block base::TimeTicks run_time; |
| 180 const base::TimeDelta delta = base::TimeDelta::FromMilliseconds(50); | 177 const base::TimeDelta delta = base::TimeDelta::FromMilliseconds(50); |
| 181 | 178 |
| 182 task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "First")); | 179 task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "First")); |
| 183 post_time = base::TimeTicks::Now(); | 180 post_time = base::TimeTicks::Now(); |
| 184 task_runner_->PostDelayedTask(FROM_HERE, base::BindBlock(^{ | 181 task_runner_->PostDelayedTask(FROM_HERE, base::BindBlock(^{ |
| 185 TaskOrderMarker marker(this, "Timed"); | 182 TaskOrderMarker marker(this, "Timed"); |
| 186 run_time = base::TimeTicks::Now(); | 183 run_time = base::TimeTicks::Now(); |
| 187 (&message_loop_)->PostTask(FROM_HERE, MessageLoop::QuitClosure()); | 184 (&message_loop_)->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| 188 }), delta); | 185 }), delta); |
| 189 task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "Second")); | 186 task_runner_->PostTask(FROM_HERE, BoundRecordTaskOrder(this, "Second")); |
| 190 message_loop_.Run(); | 187 message_loop_.Run(); |
| 188 task_runner_->Shutdown(); |
| 191 | 189 |
| 192 const char* const expectations[] = { | 190 const char* const expectations[] = { |
| 193 "BEGIN First", | 191 "BEGIN First", |
| 194 "END First", | 192 "END First", |
| 195 "BEGIN Second", | 193 "BEGIN Second", |
| 196 "END Second", | 194 "END Second", |
| 197 "BEGIN Timed", | 195 "BEGIN Timed", |
| 198 "END Timed", | 196 "END Timed", |
| 199 }; | 197 }; |
| 200 VerifyTaskOrder(expectations, arraysize(expectations)); | 198 VerifyTaskOrder(expectations, arraysize(expectations)); |
| 201 | 199 |
| 202 EXPECT_GE(run_time, post_time + delta); | 200 EXPECT_GE(run_time, post_time + delta); |
| 203 } | 201 } |
| 202 |
| 203 TEST_F(LibDispatchTaskRunnerTest, PostAfterShutdown) { |
| 204 EXPECT_TRUE(task_runner_->PostTask(FROM_HERE, |
| 205 BoundRecordTaskOrder(this, "First"))); |
| 206 EXPECT_TRUE(task_runner_->PostTask(FROM_HERE, |
| 207 BoundRecordTaskOrder(this, "Second"))); |
| 208 task_runner_->Shutdown(); |
| 209 EXPECT_FALSE(task_runner_->PostTask(FROM_HERE, base::BindBlock(^{ |
| 210 TaskOrderMarker marker(this, "Not Run"); |
| 211 ADD_FAILURE() << "Should not run a task after Shutdown"; |
| 212 }))); |
| 213 |
| 214 const char* const expectations[] = { |
| 215 "BEGIN First", |
| 216 "END First", |
| 217 "BEGIN Second", |
| 218 "END Second" |
| 219 }; |
| 220 VerifyTaskOrder(expectations, arraysize(expectations)); |
| 221 } |
| OLD | NEW |