OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/test/scoped_task_scheduler.h" | 5 #include "base/test/scoped_task_scheduler.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 ThreadCheckerImpl thread_checker; | 37 ThreadCheckerImpl thread_checker; |
38 | 38 |
39 // Detach |sequence_checker| and |thread_checker|. Otherwise, they are bound | 39 // Detach |sequence_checker| and |thread_checker|. Otherwise, they are bound |
40 // to the current thread without a SequenceToken or TaskToken (i.e. | 40 // to the current thread without a SequenceToken or TaskToken (i.e. |
41 // CalledOnValidSequence/Thread() will always return true on the current | 41 // CalledOnValidSequence/Thread() will always return true on the current |
42 // thread, even when the SequenceToken or TaskToken changes). | 42 // thread, even when the SequenceToken or TaskToken changes). |
43 sequence_checker.DetachFromSequence(); | 43 sequence_checker.DetachFromSequence(); |
44 thread_checker.DetachFromThread(); | 44 thread_checker.DetachFromThread(); |
45 | 45 |
46 PostTask(FROM_HERE, | 46 PostTask(FROM_HERE, |
47 Bind( | 47 BindOnce( |
48 [](SequenceCheckerImpl* sequence_checker, | 48 [](SequenceCheckerImpl* sequence_checker, |
49 ThreadCheckerImpl* thread_checker, bool* first_task_ran) { | 49 ThreadCheckerImpl* thread_checker, bool* first_task_ran) { |
50 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); | 50 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); |
51 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); | 51 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
52 EXPECT_TRUE(sequence_checker->CalledOnValidSequence()); | 52 EXPECT_TRUE(sequence_checker->CalledOnValidSequence()); |
53 EXPECT_TRUE(thread_checker->CalledOnValidThread()); | 53 EXPECT_TRUE(thread_checker->CalledOnValidThread()); |
54 *first_task_ran = true; | 54 *first_task_ran = true; |
55 }, | 55 }, |
56 Unretained(&sequence_checker), Unretained(&thread_checker), | 56 Unretained(&sequence_checker), Unretained(&thread_checker), |
57 Unretained(&first_task_ran))); | 57 Unretained(&first_task_ran))); |
58 | 58 |
59 PostTask(FROM_HERE, | 59 PostTask(FROM_HERE, |
60 Bind( | 60 BindOnce( |
61 [](SequenceCheckerImpl* sequence_checker, | 61 [](SequenceCheckerImpl* sequence_checker, |
62 ThreadCheckerImpl* thread_checker, bool* second_task_ran) { | 62 ThreadCheckerImpl* thread_checker, bool* second_task_ran) { |
63 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); | 63 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); |
64 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); | 64 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
65 EXPECT_FALSE(sequence_checker->CalledOnValidSequence()); | 65 EXPECT_FALSE(sequence_checker->CalledOnValidSequence()); |
66 EXPECT_FALSE(thread_checker->CalledOnValidThread()); | 66 EXPECT_FALSE(thread_checker->CalledOnValidThread()); |
67 *second_task_ran = true; | 67 *second_task_ran = true; |
68 }, | 68 }, |
69 Unretained(&sequence_checker), Unretained(&thread_checker), | 69 Unretained(&sequence_checker), Unretained(&thread_checker), |
70 Unretained(&second_task_ran))); | 70 Unretained(&second_task_ran))); |
(...skipping 16 matching lines...) Expand all Loading... |
87 | 87 |
88 // Detach |sequence_checker| and |thread_checker|. Otherwise, they are bound | 88 // Detach |sequence_checker| and |thread_checker|. Otherwise, they are bound |
89 // to the current thread without a SequenceToken or TaskToken (i.e. | 89 // to the current thread without a SequenceToken or TaskToken (i.e. |
90 // CalledOnValidSequence/Thread() will always return true on the current | 90 // CalledOnValidSequence/Thread() will always return true on the current |
91 // thread, even when the SequenceToken or TaskToken changes). | 91 // thread, even when the SequenceToken or TaskToken changes). |
92 sequence_checker.DetachFromSequence(); | 92 sequence_checker.DetachFromSequence(); |
93 thread_checker.DetachFromThread(); | 93 thread_checker.DetachFromThread(); |
94 | 94 |
95 task_runner->PostTask( | 95 task_runner->PostTask( |
96 FROM_HERE, | 96 FROM_HERE, |
97 Bind( | 97 BindOnce( |
98 [](SequenceCheckerImpl* sequence_checker, | 98 [](SequenceCheckerImpl* sequence_checker, |
99 ThreadCheckerImpl* thread_checker, bool* first_task_ran) { | 99 ThreadCheckerImpl* thread_checker, bool* first_task_ran) { |
100 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); | 100 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); |
101 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); | 101 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
102 EXPECT_TRUE(sequence_checker->CalledOnValidSequence()); | 102 EXPECT_TRUE(sequence_checker->CalledOnValidSequence()); |
103 EXPECT_TRUE(thread_checker->CalledOnValidThread()); | 103 EXPECT_TRUE(thread_checker->CalledOnValidThread()); |
104 *first_task_ran = true; | 104 *first_task_ran = true; |
105 }, | 105 }, |
106 Unretained(&sequence_checker), Unretained(&thread_checker), | 106 Unretained(&sequence_checker), Unretained(&thread_checker), |
107 Unretained(&first_task_ran))); | 107 Unretained(&first_task_ran))); |
108 | 108 |
109 task_runner->PostTask( | 109 task_runner->PostTask( |
110 FROM_HERE, | 110 FROM_HERE, |
111 Bind( | 111 BindOnce( |
112 [](SequenceCheckerImpl* sequence_checker, | 112 [](SequenceCheckerImpl* sequence_checker, |
113 ThreadCheckerImpl* thread_checker, bool* second_task_ran) { | 113 ThreadCheckerImpl* thread_checker, bool* second_task_ran) { |
114 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); | 114 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); |
115 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); | 115 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
116 EXPECT_FALSE(sequence_checker->CalledOnValidSequence()); | 116 EXPECT_FALSE(sequence_checker->CalledOnValidSequence()); |
117 EXPECT_FALSE(thread_checker->CalledOnValidThread()); | 117 EXPECT_FALSE(thread_checker->CalledOnValidThread()); |
118 *second_task_ran = true; | 118 *second_task_ran = true; |
119 }, | 119 }, |
120 Unretained(&sequence_checker), Unretained(&thread_checker), | 120 Unretained(&sequence_checker), Unretained(&thread_checker), |
121 Unretained(&second_task_ran))); | 121 Unretained(&second_task_ran))); |
(...skipping 16 matching lines...) Expand all Loading... |
138 | 138 |
139 // Detach |sequence_checker| and |thread_checker|. Otherwise, they are bound | 139 // Detach |sequence_checker| and |thread_checker|. Otherwise, they are bound |
140 // to the current thread without a SequenceToken or TaskToken (i.e. | 140 // to the current thread without a SequenceToken or TaskToken (i.e. |
141 // CalledOnValidSequence/Thread() will always return true on the current | 141 // CalledOnValidSequence/Thread() will always return true on the current |
142 // thread, even when the SequenceToken or TaskToken changes). | 142 // thread, even when the SequenceToken or TaskToken changes). |
143 sequence_checker.DetachFromSequence(); | 143 sequence_checker.DetachFromSequence(); |
144 thread_checker.DetachFromThread(); | 144 thread_checker.DetachFromThread(); |
145 | 145 |
146 task_runner->PostTask( | 146 task_runner->PostTask( |
147 FROM_HERE, | 147 FROM_HERE, |
148 Bind( | 148 BindOnce( |
149 [](SequenceCheckerImpl* sequence_checker, | 149 [](SequenceCheckerImpl* sequence_checker, |
150 ThreadCheckerImpl* thread_checker, bool* first_task_ran) { | 150 ThreadCheckerImpl* thread_checker, bool* first_task_ran) { |
151 EXPECT_TRUE(SequencedTaskRunnerHandle::IsSet()); | 151 EXPECT_TRUE(SequencedTaskRunnerHandle::IsSet()); |
152 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); | 152 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
153 EXPECT_TRUE(sequence_checker->CalledOnValidSequence()); | 153 EXPECT_TRUE(sequence_checker->CalledOnValidSequence()); |
154 EXPECT_TRUE(thread_checker->CalledOnValidThread()); | 154 EXPECT_TRUE(thread_checker->CalledOnValidThread()); |
155 *first_task_ran = true; | 155 *first_task_ran = true; |
156 }, | 156 }, |
157 Unretained(&sequence_checker), Unretained(&thread_checker), | 157 Unretained(&sequence_checker), Unretained(&thread_checker), |
158 Unretained(&first_task_ran))); | 158 Unretained(&first_task_ran))); |
159 | 159 |
160 task_runner->PostTask( | 160 task_runner->PostTask( |
161 FROM_HERE, | 161 FROM_HERE, |
162 Bind( | 162 BindOnce( |
163 [](SequenceCheckerImpl* sequence_checker, | 163 [](SequenceCheckerImpl* sequence_checker, |
164 ThreadCheckerImpl* thread_checker, bool* second_task_ran) { | 164 ThreadCheckerImpl* thread_checker, bool* second_task_ran) { |
165 EXPECT_TRUE(SequencedTaskRunnerHandle::IsSet()); | 165 EXPECT_TRUE(SequencedTaskRunnerHandle::IsSet()); |
166 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); | 166 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
167 EXPECT_TRUE(sequence_checker->CalledOnValidSequence()); | 167 EXPECT_TRUE(sequence_checker->CalledOnValidSequence()); |
168 EXPECT_FALSE(thread_checker->CalledOnValidThread()); | 168 EXPECT_FALSE(thread_checker->CalledOnValidThread()); |
169 *second_task_ran = true; | 169 *second_task_ran = true; |
170 }, | 170 }, |
171 Unretained(&sequence_checker), Unretained(&thread_checker), | 171 Unretained(&sequence_checker), Unretained(&thread_checker), |
172 Unretained(&second_task_ran))); | 172 Unretained(&second_task_ran))); |
(...skipping 16 matching lines...) Expand all Loading... |
189 | 189 |
190 // Detach |sequence_checker| and |thread_checker|. Otherwise, they are bound | 190 // Detach |sequence_checker| and |thread_checker|. Otherwise, they are bound |
191 // to the current thread without a SequenceToken or TaskToken (i.e. | 191 // to the current thread without a SequenceToken or TaskToken (i.e. |
192 // CalledOnValidSequence/Thread() will always return true on the current | 192 // CalledOnValidSequence/Thread() will always return true on the current |
193 // thread, even when the SequenceToken or TaskToken changes). | 193 // thread, even when the SequenceToken or TaskToken changes). |
194 sequence_checker.DetachFromSequence(); | 194 sequence_checker.DetachFromSequence(); |
195 thread_checker.DetachFromThread(); | 195 thread_checker.DetachFromThread(); |
196 | 196 |
197 task_runner->PostTask( | 197 task_runner->PostTask( |
198 FROM_HERE, | 198 FROM_HERE, |
199 Bind( | 199 BindOnce( |
200 [](SequenceCheckerImpl* sequence_checker, | 200 [](SequenceCheckerImpl* sequence_checker, |
201 ThreadCheckerImpl* thread_checker, bool* first_task_ran) { | 201 ThreadCheckerImpl* thread_checker, bool* first_task_ran) { |
202 EXPECT_TRUE(SequencedTaskRunnerHandle::IsSet()); | 202 EXPECT_TRUE(SequencedTaskRunnerHandle::IsSet()); |
203 EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet()); | 203 EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet()); |
204 EXPECT_TRUE(sequence_checker->CalledOnValidSequence()); | 204 EXPECT_TRUE(sequence_checker->CalledOnValidSequence()); |
205 EXPECT_TRUE(thread_checker->CalledOnValidThread()); | 205 EXPECT_TRUE(thread_checker->CalledOnValidThread()); |
206 *first_task_ran = true; | 206 *first_task_ran = true; |
207 }, | 207 }, |
208 Unretained(&sequence_checker), Unretained(&thread_checker), | 208 Unretained(&sequence_checker), Unretained(&thread_checker), |
209 Unretained(&first_task_ran))); | 209 Unretained(&first_task_ran))); |
210 | 210 |
211 task_runner->PostTask( | 211 task_runner->PostTask( |
212 FROM_HERE, | 212 FROM_HERE, |
213 Bind( | 213 BindOnce( |
214 [](SequenceCheckerImpl* sequence_checker, | 214 [](SequenceCheckerImpl* sequence_checker, |
215 ThreadCheckerImpl* thread_checker, bool* second_task_ran) { | 215 ThreadCheckerImpl* thread_checker, bool* second_task_ran) { |
216 EXPECT_TRUE(SequencedTaskRunnerHandle::IsSet()); | 216 EXPECT_TRUE(SequencedTaskRunnerHandle::IsSet()); |
217 EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet()); | 217 EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet()); |
218 EXPECT_TRUE(sequence_checker->CalledOnValidSequence()); | 218 EXPECT_TRUE(sequence_checker->CalledOnValidSequence()); |
219 EXPECT_TRUE(thread_checker->CalledOnValidThread()); | 219 EXPECT_TRUE(thread_checker->CalledOnValidThread()); |
220 *second_task_ran = true; | 220 *second_task_ran = true; |
221 }, | 221 }, |
222 Unretained(&sequence_checker), Unretained(&thread_checker), | 222 Unretained(&sequence_checker), Unretained(&thread_checker), |
223 Unretained(&second_task_ran))); | 223 Unretained(&second_task_ran))); |
(...skipping 26 matching lines...) Expand all Loading... |
250 | 250 |
251 RunLoop().RunUntilIdle(); | 251 RunLoop().RunUntilIdle(); |
252 | 252 |
253 EXPECT_TRUE(com_task_ran); | 253 EXPECT_TRUE(com_task_ran); |
254 } | 254 } |
255 #endif // defined(OS_WIN) | 255 #endif // defined(OS_WIN) |
256 | 256 |
257 TEST(ScopedTaskSchedulerTest, NonBlockShutdownTasksPostedAfterShutdownDontRun) { | 257 TEST(ScopedTaskSchedulerTest, NonBlockShutdownTasksPostedAfterShutdownDontRun) { |
258 ScopedTaskScheduler scoped_task_scheduler; | 258 ScopedTaskScheduler scoped_task_scheduler; |
259 TaskScheduler::GetInstance()->Shutdown(); | 259 TaskScheduler::GetInstance()->Shutdown(); |
260 PostTaskWithTraits(FROM_HERE, TaskTraits().WithShutdownBehavior( | 260 PostTaskWithTraits(FROM_HERE, |
261 TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN), | 261 TaskTraits().WithShutdownBehavior( |
262 Bind([]() { | 262 TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN), |
| 263 BindOnce([]() { |
263 ADD_FAILURE() | 264 ADD_FAILURE() |
264 << "CONTINUE_ON_SHUTDOWN task should not run"; | 265 << "CONTINUE_ON_SHUTDOWN task should not run"; |
265 })); | 266 })); |
266 PostTaskWithTraits( | 267 PostTaskWithTraits( |
267 FROM_HERE, | 268 FROM_HERE, |
268 TaskTraits().WithShutdownBehavior(TaskShutdownBehavior::SKIP_ON_SHUTDOWN), | 269 TaskTraits().WithShutdownBehavior(TaskShutdownBehavior::SKIP_ON_SHUTDOWN), |
269 Bind([]() { ADD_FAILURE() << "SKIP_ON_SHUTDOWN task should not run"; })); | 270 BindOnce( |
| 271 []() { ADD_FAILURE() << "SKIP_ON_SHUTDOWN task should not run"; })); |
270 | 272 |
271 // This should not run anything. | 273 // This should not run anything. |
272 RunLoop().RunUntilIdle(); | 274 RunLoop().RunUntilIdle(); |
273 } | 275 } |
274 | 276 |
275 TEST(ScopedTaskSchedulerTest, DestructorRunsBlockShutdownTasksOnly) { | 277 TEST(ScopedTaskSchedulerTest, DestructorRunsBlockShutdownTasksOnly) { |
276 bool block_shutdown_task_ran = false; | 278 bool block_shutdown_task_ran = false; |
277 { | 279 { |
278 ScopedTaskScheduler scoped_task_scheduler; | 280 ScopedTaskScheduler scoped_task_scheduler; |
279 PostTaskWithTraits( | 281 PostTaskWithTraits(FROM_HERE, |
280 FROM_HERE, TaskTraits().WithShutdownBehavior( | 282 TaskTraits().WithShutdownBehavior( |
281 TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN), | 283 TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN), |
282 Bind([]() { | 284 BindOnce([]() { |
283 ADD_FAILURE() << "CONTINUE_ON_SHUTDOWN task should not run"; | 285 ADD_FAILURE() |
284 })); | 286 << "CONTINUE_ON_SHUTDOWN task should not run"; |
285 PostTaskWithTraits(FROM_HERE, TaskTraits().WithShutdownBehavior( | 287 })); |
286 TaskShutdownBehavior::SKIP_ON_SHUTDOWN), | 288 PostTaskWithTraits(FROM_HERE, |
287 Bind([]() { | 289 TaskTraits().WithShutdownBehavior( |
| 290 TaskShutdownBehavior::SKIP_ON_SHUTDOWN), |
| 291 BindOnce([]() { |
288 ADD_FAILURE() | 292 ADD_FAILURE() |
289 << "SKIP_ON_SHUTDOWN task should not run"; | 293 << "SKIP_ON_SHUTDOWN task should not run"; |
290 })); | 294 })); |
291 PostTaskWithTraits(FROM_HERE, TaskTraits().WithShutdownBehavior( | 295 PostTaskWithTraits( |
292 TaskShutdownBehavior::BLOCK_SHUTDOWN), | 296 FROM_HERE, |
293 Bind( | 297 TaskTraits().WithShutdownBehavior(TaskShutdownBehavior::BLOCK_SHUTDOWN), |
294 [](bool* block_shutdown_task_ran) { | 298 BindOnce( |
295 *block_shutdown_task_ran = true; | 299 [](bool* block_shutdown_task_ran) { |
296 }, | 300 *block_shutdown_task_ran = true; |
297 Unretained(&block_shutdown_task_ran))); | 301 }, |
| 302 Unretained(&block_shutdown_task_ran))); |
298 } | 303 } |
299 EXPECT_TRUE(block_shutdown_task_ran); | 304 EXPECT_TRUE(block_shutdown_task_ran); |
300 } | 305 } |
301 | 306 |
302 TEST(ScopedTaskSchedulerTest, ReassignCurrentTaskRunner) { | 307 TEST(ScopedTaskSchedulerTest, ReassignCurrentTaskRunner) { |
303 bool first_task_ran = false; | 308 bool first_task_ran = false; |
304 bool second_task_ran = false; | 309 bool second_task_ran = false; |
305 | 310 |
306 auto TestTaskRan = [](bool* task_ran) { *task_ran = true; }; | 311 auto TestTaskRan = [](bool* task_ran) { *task_ran = true; }; |
307 | 312 |
308 ScopedTaskScheduler scoped_task_scheduler; | 313 ScopedTaskScheduler scoped_task_scheduler; |
309 { | 314 { |
310 ScopedMockTimeMessageLoopTaskRunner mock_time_task_runner; | 315 ScopedMockTimeMessageLoopTaskRunner mock_time_task_runner; |
311 PostDelayedTask(FROM_HERE, Bind(TestTaskRan, Unretained(&first_task_ran)), | 316 PostDelayedTask(FROM_HERE, |
| 317 BindOnce(TestTaskRan, Unretained(&first_task_ran)), |
312 TimeDelta::FromSeconds(1)); | 318 TimeDelta::FromSeconds(1)); |
313 | 319 |
314 // The delayed task should be queued on |mock_time_task_runner|, not the | 320 // The delayed task should be queued on |mock_time_task_runner|, not the |
315 // default task runner. | 321 // default task runner. |
316 EXPECT_TRUE(mock_time_task_runner.task_runner()->HasPendingTask()); | 322 EXPECT_TRUE(mock_time_task_runner.task_runner()->HasPendingTask()); |
317 } | 323 } |
318 | 324 |
319 PostDelayedTask(FROM_HERE, Bind(TestTaskRan, Unretained(&second_task_ran)), | 325 PostDelayedTask(FROM_HERE, |
| 326 BindOnce(TestTaskRan, Unretained(&second_task_ran)), |
320 TimeDelta()); | 327 TimeDelta()); |
321 | 328 |
322 RunLoop().RunUntilIdle(); | 329 RunLoop().RunUntilIdle(); |
323 | 330 |
324 // We never pumped |mock_time_task_runner| so the first task should not have | 331 // We never pumped |mock_time_task_runner| so the first task should not have |
325 // run. | 332 // run. |
326 EXPECT_FALSE(first_task_ran); | 333 EXPECT_FALSE(first_task_ran); |
327 EXPECT_TRUE(second_task_ran); | 334 EXPECT_TRUE(second_task_ran); |
328 } | 335 } |
329 | 336 |
330 // Verify that a task can be posted from a task running in ScopedTaskScheduler. | 337 // Verify that a task can be posted from a task running in ScopedTaskScheduler. |
331 TEST(ScopedTaskSchedulerTest, ReentrantTaskRunner) { | 338 TEST(ScopedTaskSchedulerTest, ReentrantTaskRunner) { |
332 bool task_ran = false; | 339 bool task_ran = false; |
333 ScopedTaskScheduler scoped_task_scheduler; | 340 ScopedTaskScheduler scoped_task_scheduler; |
334 PostTask(FROM_HERE, Bind( | 341 PostTask(FROM_HERE, |
335 [](bool* task_ran) { | 342 BindOnce( |
336 PostTask( | 343 [](bool* task_ran) { |
337 FROM_HERE, | 344 PostTask(FROM_HERE, |
338 Bind([](bool* task_ran) { *task_ran = true; }, | 345 BindOnce([](bool* task_ran) { *task_ran = true; }, |
339 Unretained(task_ran))); | 346 Unretained(task_ran))); |
340 }, | 347 }, |
341 Unretained(&task_ran))); | 348 Unretained(&task_ran))); |
342 RunLoop().RunUntilIdle(); | 349 RunLoop().RunUntilIdle(); |
343 EXPECT_TRUE(task_ran); | 350 EXPECT_TRUE(task_ran); |
344 } | 351 } |
345 | 352 |
346 } // namespace test | 353 } // namespace test |
347 } // namespace base | 354 } // namespace base |
OLD | NEW |