• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/test/task_environment.h"
6 
7 #include <algorithm>
8 #include <memory>
9 #include <ostream>
10 
11 #include "base/check.h"
12 #include "base/debug/stack_trace.h"
13 #include "base/functional/callback_forward.h"
14 #include "base/functional/callback_helpers.h"
15 #include "base/lazy_instance.h"
16 #include "base/location.h"
17 #include "base/logging.h"
18 #include "base/memory/ptr_util.h"
19 #include "base/memory/raw_ptr.h"
20 #include "base/memory/raw_ref.h"
21 #include "base/message_loop/message_pump.h"
22 #include "base/message_loop/message_pump_type.h"
23 #include "base/no_destructor.h"
24 #include "base/process/process.h"
25 #include "base/run_loop.h"
26 #include "base/synchronization/condition_variable.h"
27 #include "base/synchronization/lock.h"
28 #include "base/task/common/lazy_now.h"
29 #include "base/task/sequence_manager/sequence_manager.h"
30 #include "base/task/sequence_manager/sequence_manager_impl.h"
31 #include "base/task/sequence_manager/task_queue.h"
32 #include "base/task/sequence_manager/time_domain.h"
33 #include "base/task/single_thread_task_runner.h"
34 #include "base/task/thread_pool/thread_pool_impl.h"
35 #include "base/task/thread_pool/thread_pool_instance.h"
36 #include "base/test/bind.h"
37 #include "base/test/test_mock_time_task_runner.h"
38 #include "base/test/test_timeouts.h"
39 #include "base/thread_annotations.h"
40 #include "base/threading/platform_thread.h"
41 #include "base/threading/sequence_local_storage_map.h"
42 #include "base/threading/thread_checker_impl.h"
43 #include "base/threading/thread_local.h"
44 #include "base/threading/thread_restrictions.h"
45 #include "base/time/clock.h"
46 #include "base/time/tick_clock.h"
47 #include "base/time/time.h"
48 #include "base/time/time_override.h"
49 #include "build/build_config.h"
50 #include "testing/gtest/include/gtest/gtest.h"
51 
52 #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
53 #include <optional>
54 
55 #include "base/files/file_descriptor_watcher_posix.h"
56 #endif
57 
58 #if BUILDFLAG(ENABLE_BASE_TRACING)
59 #include "base/trace_event/trace_log.h"  // nogncheck
60 #endif                                   // BUILDFLAG(ENABLE_BASE_TRACING)
61 
62 namespace base {
63 namespace test {
64 
65 namespace {
66 
GetDestructionObservers()67 ObserverList<TaskEnvironment::DestructionObserver>& GetDestructionObservers() {
68   static NoDestructor<ObserverList<TaskEnvironment::DestructionObserver>>
69       instance;
70   return *instance;
71 }
72 
73 // A pointer to the current TestTaskTracker, if any, constant throughout the
74 // lifetime of a ThreadPoolInstance managed by a TaskEnvironment.
75 TaskEnvironment::TestTaskTracker* g_task_tracker = nullptr;
76 
GetMessagePumpTypeForMainThreadType(TaskEnvironment::MainThreadType main_thread_type)77 base::MessagePumpType GetMessagePumpTypeForMainThreadType(
78     TaskEnvironment::MainThreadType main_thread_type) {
79   switch (main_thread_type) {
80     case TaskEnvironment::MainThreadType::DEFAULT:
81       return MessagePumpType::DEFAULT;
82     case TaskEnvironment::MainThreadType::UI:
83       return MessagePumpType::UI;
84     case TaskEnvironment::MainThreadType::IO:
85       return MessagePumpType::IO;
86   }
87   NOTREACHED();
88 }
89 
90 std::unique_ptr<sequence_manager::SequenceManager>
CreateSequenceManagerForMainThreadType(TaskEnvironment::MainThreadType main_thread_type,sequence_manager::SequenceManager::PrioritySettings priority_settings)91 CreateSequenceManagerForMainThreadType(
92     TaskEnvironment::MainThreadType main_thread_type,
93     sequence_manager::SequenceManager::PrioritySettings priority_settings) {
94   auto type = GetMessagePumpTypeForMainThreadType(main_thread_type);
95   return sequence_manager::CreateSequenceManagerOnCurrentThreadWithPump(
96       MessagePump::Create(type),
97       base::sequence_manager::SequenceManager::Settings::Builder()
98           .SetMessagePumpType(type)
99           .SetPrioritySettings(std::move(priority_settings))
100           .Build());
101 }
102 
103 class TickClockBasedClock : public Clock {
104  public:
TickClockBasedClock(const TickClock * tick_clock)105   explicit TickClockBasedClock(const TickClock* tick_clock)
106       : tick_clock_(*tick_clock),
107         start_ticks_(tick_clock_->NowTicks()),
108         start_time_(Time::UnixEpoch()) {}
109 
Now() const110   Time Now() const override {
111     return start_time_ + (tick_clock_->NowTicks() - start_ticks_);
112   }
113 
114  private:
115   const raw_ref<const TickClock> tick_clock_;
116   const TimeTicks start_ticks_;
117   const Time start_time_;
118 };
119 
120 }  // namespace
121 
122 class TaskEnvironment::TestTaskTracker
123     : public internal::ThreadPoolImpl::TaskTrackerImpl {
124  public:
125   TestTaskTracker();
126 
127   TestTaskTracker(const TestTaskTracker&) = delete;
128   TestTaskTracker& operator=(const TestTaskTracker&) = delete;
129 
130   // Allow running tasks. Returns whether tasks were previously allowed to run.
131   bool AllowRunTasks();
132 
133   // Disallow running tasks. Returns true on success; success requires there to
134   // be no tasks currently running. Returns false if >0 tasks are currently
135   // running. Prior to returning false, it will attempt to block until at least
136   // one task has completed (in an attempt to avoid callers busy-looping
137   // DisallowRunTasks() calls with the same set of slowly ongoing tasks).
138   // Returns false if none of the ongoing tasks complete within |timeout| in an
139   // attempt to prevent a deadlock in the event that the only task remaining is
140   // blocked on the main thread.
141   bool DisallowRunTasks(TimeDelta timeout = Milliseconds(1));
142 
143   // Returns true if tasks are currently allowed to run.
144   bool TasksAllowedToRun() const;
145 
146   // For debugging purposes. Returns a string with information about all the
147   // currently running tasks on the thread pool.
148   std::string DescribeRunningTasks() const;
149 
150   // Returns true if this is invoked on this TaskTracker's owning thread
151   // (i.e. test main thread).
OnControllerThread() const152   bool OnControllerThread() const {
153     return controller_thread_checker_.CalledOnValidThread();
154   }
155 
156  private:
157   friend class TaskEnvironment;
158 
159   // internal::ThreadPoolImpl::TaskTrackerImpl:
160   void RunTask(internal::Task task,
161                internal::TaskSource* sequence,
162                const TaskTraits& traits) override;
163   void BeginCompleteShutdown(base::WaitableEvent& shutdown_event) override;
164   void AssertFlushForTestingAllowed() override;
165 
166   // Synchronizes accesses to members below.
167   mutable Lock lock_;
168 
169   // True if running tasks is allowed.
170   bool can_run_tasks_ GUARDED_BY(lock_) = true;
171 
172   // Signaled when |can_run_tasks_| becomes true.
173   ConditionVariable can_run_tasks_cv_ GUARDED_BY(lock_);
174 
175   // Signaled when a task is completed.
176   ConditionVariable task_completed_cv_ GUARDED_BY(lock_);
177 
178   // Next task number so that each task has some unique-ish id.
179   int64_t next_task_number_ GUARDED_BY(lock_) = 1;
180   // The set of tasks currently running, keyed by the id from
181   // |next_task_number_|.
182   base::flat_map<int64_t, Location> running_tasks_ GUARDED_BY(lock_);
183 
184   // Used to implement OnControllerThread().
185   ThreadCheckerImpl controller_thread_checker_;
186 };
187 
188 class TaskEnvironment::MockTimeDomain : public sequence_manager::TimeDomain {
189  public:
MockTimeDomain(sequence_manager::internal::SequenceManagerImpl * sequence_manager)190   explicit MockTimeDomain(
191       sequence_manager::internal::SequenceManagerImpl* sequence_manager)
192       : sequence_manager_(sequence_manager) {
193     DCHECK_EQ(nullptr, current_mock_time_domain_);
194     current_mock_time_domain_ = this;
195   }
196 
~MockTimeDomain()197   ~MockTimeDomain() override {
198     DCHECK_EQ(this, current_mock_time_domain_);
199     current_mock_time_domain_ = nullptr;
200   }
201 
202   static MockTimeDomain* current_mock_time_domain_;
203 
GetTime()204   static Time GetTime() {
205     return Time::UnixEpoch() +
206            (current_mock_time_domain_->NowTicks() - TimeTicks());
207   }
208 
GetTimeTicks()209   static TimeTicks GetTimeTicks() {
210     return current_mock_time_domain_->NowTicks();
211   }
212 
GetLiveTicks()213   static LiveTicks GetLiveTicks() {
214     return current_mock_time_domain_->NowLiveTicks();
215   }
216 
AdvanceClock(TimeDelta delta)217   void AdvanceClock(TimeDelta delta) {
218     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
219     {
220       AutoLock lock(now_ticks_lock_);
221       now_ticks_ += delta;
222       live_ticks_ += delta;
223     }
224 
225     if (thread_pool_) {
226       thread_pool_->ProcessRipeDelayedTasksForTesting();
227     }
228   }
229 
SuspendedAdvanceClock(TimeDelta delta)230   void SuspendedAdvanceClock(TimeDelta delta) {
231     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
232     {
233       AutoLock lock(now_ticks_lock_);
234       now_ticks_ += delta;
235     }
236 
237     if (thread_pool_) {
238       thread_pool_->ProcessRipeDelayedTasksForTesting();
239     }
240   }
241 
SetThreadPool(internal::ThreadPoolImpl * thread_pool,const TestTaskTracker * thread_pool_task_tracker)242   void SetThreadPool(internal::ThreadPoolImpl* thread_pool,
243                      const TestTaskTracker* thread_pool_task_tracker) {
244     DCHECK(!thread_pool_);
245     DCHECK(!thread_pool_task_tracker_);
246     thread_pool_ = thread_pool;
247     thread_pool_task_tracker_ = thread_pool_task_tracker;
248   }
249 
250   // sequence_manager::TimeDomain:
251 
252   // This method is called when the underlying message pump has run out of
253   // non-delayed work. Advances time to the next task unless
254   // |quit_when_idle_requested| or TaskEnvironment controls mock time.
MaybeFastForwardToWakeUp(std::optional<sequence_manager::WakeUp> next_wake_up,bool quit_when_idle_requested)255   bool MaybeFastForwardToWakeUp(
256       std::optional<sequence_manager::WakeUp> next_wake_up,
257       bool quit_when_idle_requested) override {
258     if (quit_when_idle_requested) {
259       return false;
260     }
261 
262     return FastForwardToNextTaskOrCap(next_wake_up, TimeTicks::Max(),
263                                       /*advance_live_ticks=*/true) ==
264            NextTaskSource::kMainThreadHasWork;
265   }
266 
GetName() const267   const char* GetName() const override { return "MockTimeDomain"; }
268 
269   // TickClock implementation:
NowTicks() const270   TimeTicks NowTicks() const override {
271     // This can be called from any thread.
272     AutoLock lock(now_ticks_lock_);
273     return now_ticks_;
274   }
275 
NowLiveTicks() const276   LiveTicks NowLiveTicks() const {
277     AutoLock lock(now_ticks_lock_);
278     return live_ticks_;
279   }
280 
281   // Used by FastForwardToNextTaskOrCap() to return which task source time was
282   // advanced to.
283   enum class NextTaskSource {
284     // Out of tasks under |fast_forward_cap|.
285     kNone,
286     // There's now >=1 immediate task on the main thread (ThreadPool might have
287     // some too).
288     kMainThreadHasWork,
289     // There's now >=1 immediate task in the thread pool.
290     kThreadPoolOnly,
291   };
292 
AdvanceTimesToNextTaskTimeOrCap(TimeTicks next_task_time,bool advance_live_ticks)293   void AdvanceTimesToNextTaskTimeOrCap(TimeTicks next_task_time,
294                                        bool advance_live_ticks) {
295     AutoLock lock(now_ticks_lock_);
296 
297     TimeTicks next_now = std::max(now_ticks_, next_task_time);
298     if (advance_live_ticks) {
299       live_ticks_ += (next_now - now_ticks_);
300     }
301     now_ticks_ = next_now;
302   }
303 
304   // Advances time to the first of : next main thread delayed task, next thread
305   // pool task, or |fast_forward_cap| (if it's not Max()). Ignores immediate
306   // tasks, expected to be called after being just idle, racily scheduling
307   // immediate tasks doesn't affect the outcome of this call.
308   // If `advance_live_ticks` is true, the mock `LiveTicks` will also be advanced
309   // by the same amount. If false, `LiveTicks` won't be advanced (behaving as if
310   // the system was suspended).
FastForwardToNextTaskOrCap(std::optional<sequence_manager::WakeUp> next_main_thread_wake_up,TimeTicks fast_forward_cap,bool advance_live_ticks)311   NextTaskSource FastForwardToNextTaskOrCap(
312       std::optional<sequence_manager::WakeUp> next_main_thread_wake_up,
313       TimeTicks fast_forward_cap,
314       bool advance_live_ticks) {
315     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
316 
317     // Consider the next thread pool tasks iff they're running.
318     std::optional<TimeTicks> next_thread_pool_task_time;
319     if (thread_pool_ && thread_pool_task_tracker_->TasksAllowedToRun()) {
320       next_thread_pool_task_time =
321           thread_pool_->NextScheduledRunTimeForTesting();
322     }
323 
324     // Custom comparison logic to consider nullopt the largest rather than
325     // smallest value. Could consider using TimeTicks::Max() instead of nullopt
326     // to represent out-of-tasks?
327     std::optional<TimeTicks> next_task_time;
328     if (!next_main_thread_wake_up) {
329       next_task_time = next_thread_pool_task_time;
330     } else if (!next_thread_pool_task_time) {
331       next_task_time = next_main_thread_wake_up->time;
332     } else {
333       next_task_time =
334           std::min(next_main_thread_wake_up->time, *next_thread_pool_task_time);
335     }
336 
337     if (next_task_time && *next_task_time <= fast_forward_cap) {
338       {
339         // It's possible for |next_task_time| to be in the past in the following
340         // scenario:
341         // Start with Now() == 100ms
342         // Thread A : Post 200ms delayed task T (construct and enqueue)
343         // Thread B : Construct 20ms delayed task U
344         //              => |delayed_run_time| == 120ms.
345         // Thread A : FastForwardToNextTaskOrCap() => fast-forwards to T @
346         //            300ms (task U is not yet in queue).
347         // Thread B : Complete enqueue of task U.
348         // Thread A : FastForwardToNextTaskOrCap() => must stay at 300ms and run
349         //            U, not go back to 120ms.
350         // Hence we need std::max() to protect against this because construction
351         // and enqueuing isn't atomic in time (LazyNow support in
352         // base/task/thread_pool could help).
353         AdvanceTimesToNextTaskTimeOrCap(*next_task_time, advance_live_ticks);
354       }
355 
356       if (next_task_time == next_thread_pool_task_time) {
357         thread_pool_->ProcessRipeDelayedTasksForTesting();
358       }
359 
360       if (next_main_thread_wake_up &&
361           next_task_time == next_main_thread_wake_up->time) {
362         return NextTaskSource::kMainThreadHasWork;
363       }
364 
365       // The main thread doesn't have immediate work so it'll go to sleep after
366       // returning from this call. We must make sure it wakes up when the
367       // ThreadPool is done or the test may stall : crbug.com/1263149.
368       //
369       // Note: It is necessary to reach in SequenceManagerImpl to ScheduleWork
370       // instead of alternatives to waking the main thread, like posting a
371       // no-op task, as alternatives would prevent the main thread from
372       // achieving quiescence (which some task monitoring tests verify).
373       thread_pool_->FlushAsyncForTesting(BindOnce(
374           &sequence_manager::internal::SequenceManagerImpl::ScheduleWork,
375           Unretained(sequence_manager_)));
376       return NextTaskSource::kThreadPoolOnly;
377     }
378 
379     if (!fast_forward_cap.is_max()) {
380       // It's possible that Now() is already beyond |fast_forward_cap| when the
381       // caller nests multiple FastForwardBy() calls.
382       AdvanceTimesToNextTaskTimeOrCap(fast_forward_cap, advance_live_ticks);
383     }
384 
385     return NextTaskSource::kNone;
386   }
387 
388  private:
389   SEQUENCE_CHECKER(sequence_checker_);
390 
391   raw_ptr<internal::ThreadPoolImpl, DanglingUntriaged> thread_pool_ = nullptr;
392   raw_ptr<const TestTaskTracker, DanglingUntriaged> thread_pool_task_tracker_ =
393       nullptr;
394 
395   const raw_ptr<sequence_manager::internal::SequenceManagerImpl,
396                 DanglingUntriaged>
397       sequence_manager_;
398 
399   // Protects `now_ticks_` and `live_ticks_`
400   mutable Lock now_ticks_lock_;
401 
402   // Only ever written to from the main sequence. Start from real Now() instead
403   // of zero to give a more realistic view to tests.
GUARDED_BY(now_ticks_lock_)404   TimeTicks now_ticks_ GUARDED_BY(now_ticks_lock_){
405       base::subtle::TimeTicksNowIgnoringOverride()
406           .SnappedToNextTick(TimeTicks(), Milliseconds(1))};
407 
408   // Only ever written to from the main sequence. Start from real Now() instead
409   // of zero to give a more realistic view to tests.
GUARDED_BY(now_ticks_lock_)410   LiveTicks live_ticks_ GUARDED_BY(now_ticks_lock_){
411       base::subtle::LiveTicksNowIgnoringOverride()};
412 };
413 
414 TaskEnvironment::MockTimeDomain*
415     TaskEnvironment::MockTimeDomain::current_mock_time_domain_ = nullptr;
416 
TaskEnvironment(sequence_manager::SequenceManager::PrioritySettings priority_settings,TimeSource time_source,MainThreadType main_thread_type,ThreadPoolExecutionMode thread_pool_execution_mode,ThreadingMode threading_mode,ThreadPoolCOMEnvironment thread_pool_com_environment,bool subclass_creates_default_taskrunner,trait_helpers::NotATraitTag)417 TaskEnvironment::TaskEnvironment(
418     sequence_manager::SequenceManager::PrioritySettings priority_settings,
419     TimeSource time_source,
420     MainThreadType main_thread_type,
421     ThreadPoolExecutionMode thread_pool_execution_mode,
422     ThreadingMode threading_mode,
423     ThreadPoolCOMEnvironment thread_pool_com_environment,
424     bool subclass_creates_default_taskrunner,
425     trait_helpers::NotATraitTag)
426     : main_thread_type_(main_thread_type),
427       thread_pool_execution_mode_(thread_pool_execution_mode),
428       threading_mode_(threading_mode),
429       thread_pool_com_environment_(thread_pool_com_environment),
430       subclass_creates_default_taskrunner_(subclass_creates_default_taskrunner),
431       sequence_manager_(
432           CreateSequenceManagerForMainThreadType(main_thread_type,
433                                                  std::move(priority_settings))),
434       mock_time_domain_(
435           time_source != TimeSource::SYSTEM_TIME
436               ? std::make_unique<TaskEnvironment::MockTimeDomain>(
437                     static_cast<
438                         sequence_manager::internal::SequenceManagerImpl*>(
439                         sequence_manager_.get()))
440               : nullptr),
441       time_overrides_(time_source == TimeSource::MOCK_TIME
442                           ? std::make_unique<subtle::ScopedTimeClockOverrides>(
443                                 &MockTimeDomain::GetTime,
444                                 &MockTimeDomain::GetTimeTicks,
445                                 nullptr,
446                                 &MockTimeDomain::GetLiveTicks)
447                           : nullptr),
448       mock_clock_(mock_time_domain_ ? std::make_unique<TickClockBasedClock>(
449                                           mock_time_domain_.get())
450                                     : nullptr),
451       scoped_lazy_task_runner_list_for_testing_(
452           std::make_unique<internal::ScopedLazyTaskRunnerListForTesting>()),
453       // TODO(crbug.com/41435712): Enable Run() timeouts even for
454       // instances created with TimeSource::MOCK_TIME.
455       run_loop_timeout_(
456           mock_time_domain_
457               ? nullptr
458               : std::make_unique<ScopedRunLoopTimeout>(
459                     FROM_HERE,
460                     TestTimeouts::action_timeout(),
461                     BindRepeating(&sequence_manager::SequenceManager::
462                                       DescribeAllPendingTasks,
463                                   Unretained(sequence_manager_.get())))) {
464   CHECK(!base::SingleThreadTaskRunner::HasCurrentDefault());
465   // If |subclass_creates_default_taskrunner| is true then initialization is
466   // deferred until DeferredInitFromSubclass().
467   if (!subclass_creates_default_taskrunner) {
468     task_queue_ =
469         sequence_manager_->CreateTaskQueue(sequence_manager::TaskQueue::Spec(
470             sequence_manager::QueueName::TASK_ENVIRONMENT_DEFAULT_TQ));
471     task_runner_ = task_queue_->task_runner();
472     sequence_manager_->SetDefaultTaskRunner(task_runner_);
473     if (mock_time_domain_) {
474       sequence_manager_->SetTimeDomain(mock_time_domain_.get());
475     }
476     CHECK(base::SingleThreadTaskRunner::HasCurrentDefault())
477         << "SingleThreadTaskRunner::CurrentDefaultHandle should've been set "
478            "now.";
479     CompleteInitialization();
480   }
481 
482   if (threading_mode_ != ThreadingMode::MAIN_THREAD_ONLY) {
483     InitializeThreadPool();
484   }
485 
486   if (thread_pool_execution_mode_ == ThreadPoolExecutionMode::QUEUED &&
487       task_tracker_) {
488     CHECK(task_tracker_->DisallowRunTasks());
489   }
490 }
491 
492 // static
CreateThreadPool()493 TaskEnvironment::TestTaskTracker* TaskEnvironment::CreateThreadPool() {
494   CHECK(!ThreadPoolInstance::Get())
495       << "Someone has already installed a ThreadPoolInstance. If nothing in "
496          "your test does so, then a test that ran earlier may have installed "
497          "one and leaked it. base::TestSuite will trap leaked globals, unless "
498          "someone has explicitly disabled it with "
499          "DisableCheckForLeakedGlobals().";
500 
501   auto task_tracker = std::make_unique<TestTaskTracker>();
502   TestTaskTracker* raw_task_tracker = task_tracker.get();
503   // Disable background threads to avoid hangs when flushing background tasks.
504   auto thread_pool = std::make_unique<internal::ThreadPoolImpl>(
505       std::string(), std::move(task_tracker),
506       /*use_background_threads=*/false);
507   ThreadPoolInstance::Set(std::move(thread_pool));
508   DCHECK(!g_task_tracker);
509   g_task_tracker = raw_task_tracker;
510   return raw_task_tracker;
511 }
512 
InitializeThreadPool()513 void TaskEnvironment::InitializeThreadPool() {
514 #if BUILDFLAG(ENABLE_BASE_TRACING)
515   // Force the creation of TraceLog instance before starting ThreadPool and
516   // creating additional threads to avoid race conditions.
517   trace_event::TraceLog::GetInstance();
518 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
519 
520   task_tracker_ = CreateThreadPool();
521   if (mock_time_domain_) {
522     mock_time_domain_->SetThreadPool(
523         static_cast<internal::ThreadPoolImpl*>(ThreadPoolInstance::Get()),
524         task_tracker_);
525   }
526 
527   ThreadPoolInstance::InitParams init_params(kNumForegroundThreadPoolThreads);
528   init_params.suggested_reclaim_time = TimeDelta::Max();
529 #if BUILDFLAG(IS_WIN)
530   if (thread_pool_com_environment_ == ThreadPoolCOMEnvironment::COM_MTA) {
531     init_params.common_thread_pool_environment =
532         ThreadPoolInstance::InitParams::CommonThreadPoolEnvironment::COM_MTA;
533   }
534 #endif
535   ThreadPoolInstance::Get()->Start(init_params);
536 }
537 
CompleteInitialization()538 void TaskEnvironment::CompleteInitialization() {
539   DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
540 
541 #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
542   if (main_thread_type() == MainThreadType::IO) {
543     file_descriptor_watcher_ =
544         std::make_unique<FileDescriptorWatcher>(GetMainThreadTaskRunner());
545   }
546 #endif  // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
547 }
548 
549 TaskEnvironment::TaskEnvironment(TaskEnvironment&& other) = default;
550 
~TaskEnvironment()551 TaskEnvironment::~TaskEnvironment() {
552   DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
553   DestroyTaskEnvironment();
554 }
555 
DestroyTaskEnvironment()556 void TaskEnvironment::DestroyTaskEnvironment() {
557   DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
558 
559   // If we've been moved or already destroyed (i.e. subclass invoked
560   // DestroyTaskEnvironment() before ~TaskEnvironment()) then bail out.
561   if (!owns_instance_) {
562     return;
563   }
564   owns_instance_.reset();
565 
566   for (auto& observer : GetDestructionObservers()) {
567     observer.WillDestroyCurrentTaskEnvironment();
568   }
569 
570   ShutdownAndJoinThreadPool();
571   task_queue_.reset();
572   // SequenceManagerImpl must outlive the threads in the ThreadPoolInstance()
573   // (ShutdownAndJoinThreadPool() above) as TaskEnvironment::MockTimeDomain can
574   // invoke its SequenceManagerImpl* from worker threads.
575   // Additionally, Tasks owned by `sequence_manager_` can have referencees to
576   // PooledTaskRunnerDelegates. These are owned by the thread pool, so destroy
577   // `sequence_manager` before the thread pool itself.
578   sequence_manager_.reset();
579   DestroyThreadPool();
580 }
581 
ShutdownAndJoinThreadPool()582 void TaskEnvironment::ShutdownAndJoinThreadPool() {
583   DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
584 
585   if (threading_mode_ == ThreadingMode::MAIN_THREAD_ONLY) {
586     return;
587   }
588   DCHECK(ThreadPoolInstance::Get());
589 
590   // Ideally this would RunLoop().RunUntilIdle() here to catch any errors or
591   // infinite post loop in the remaining work but this isn't possible right now
592   // because base::~MessageLoop() didn't use to do this and adding it here would
593   // make the migration away from MessageLoop that much harder.
594 
595   // Without FlushForTesting(), DeleteSoon() and ReleaseSoon() tasks could be
596   // skipped, resulting in memory leaks.
597   task_tracker_->AllowRunTasks();
598   ThreadPoolInstance::Get()->FlushForTesting();
599   ThreadPoolInstance::Get()->Shutdown();
600   ThreadPoolInstance::Get()->JoinForTesting();
601   DCHECK_EQ(g_task_tracker, task_tracker_);
602   g_task_tracker = nullptr;
603 }
604 
DestroyThreadPool()605 void TaskEnvironment::DestroyThreadPool() {
606   DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
607 
608   if (threading_mode_ == ThreadingMode::MAIN_THREAD_ONLY) {
609     return;
610   }
611   DCHECK(ThreadPoolInstance::Get());
612 
613   // Task runner lists will be destroyed when resetting thread pool instance.
614   scoped_lazy_task_runner_list_for_testing_.reset();
615 
616   // Destroying ThreadPoolInstance state can result in waiting on worker
617   // threads. Make sure this is allowed to avoid flaking tests that have
618   // disallowed waits on their main thread.
619   ScopedAllowBaseSyncPrimitivesForTesting allow_waits_to_destroy_task_tracker;
620 
621   // Drop unowned resource before destroying thread pool which owns it.
622   task_tracker_ = nullptr;
623   ThreadPoolInstance::Set(nullptr);
624 }
625 
GetMockTimeDomain() const626 sequence_manager::TimeDomain* TaskEnvironment::GetMockTimeDomain() const {
627   return mock_time_domain_.get();
628 }
629 
sequence_manager() const630 sequence_manager::SequenceManager* TaskEnvironment::sequence_manager() const {
631   DCHECK(subclass_creates_default_taskrunner_);
632   return sequence_manager_.get();
633 }
634 
DeferredInitFromSubclass(scoped_refptr<base::SingleThreadTaskRunner> task_runner)635 void TaskEnvironment::DeferredInitFromSubclass(
636     scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
637   DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
638 
639   task_runner_ = std::move(task_runner);
640   sequence_manager_->SetDefaultTaskRunner(task_runner_);
641   CompleteInitialization();
642 }
643 
644 scoped_refptr<base::SingleThreadTaskRunner>
GetMainThreadTaskRunner()645 TaskEnvironment::GetMainThreadTaskRunner() {
646   DCHECK(task_runner_);
647   return task_runner_;
648 }
649 
MainThreadIsIdle() const650 bool TaskEnvironment::MainThreadIsIdle() const {
651   DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
652 
653   sequence_manager::internal::SequenceManagerImpl* sequence_manager_impl =
654       static_cast<sequence_manager::internal::SequenceManagerImpl*>(
655           sequence_manager_.get());
656   // ReclaimMemory sweeps canceled delayed tasks.
657   sequence_manager_impl->ReclaimMemory();
658   return sequence_manager_impl->IsIdleForTesting();
659 }
660 
QuitClosure()661 RepeatingClosure TaskEnvironment::QuitClosure() {
662   DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
663 
664   if (!run_until_quit_loop_) {
665     run_until_quit_loop_ =
666         std::make_unique<RunLoop>(RunLoop::Type::kNestableTasksAllowed);
667   }
668 
669   return run_until_quit_loop_->QuitClosure();
670 }
671 
RunUntilQuit()672 void TaskEnvironment::RunUntilQuit() {
673   DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
674   DCHECK(run_until_quit_loop_)
675       << "QuitClosure() not called before RunUntilQuit()";
676 
677   const bool could_run_tasks = task_tracker_->AllowRunTasks();
678 
679   run_until_quit_loop_->Run();
680   // Make the next call to RunUntilQuit() use a new RunLoop. This also
681   // invalidates all existing quit closures.
682   run_until_quit_loop_.reset();
683 
684   if (!could_run_tasks) {
685     EXPECT_TRUE(
686         task_tracker_->DisallowRunTasks(TestTimeouts::action_max_timeout()))
687         << "Could not bring ThreadPool back to ThreadPoolExecutionMode::QUEUED "
688            "after Quit() because some tasks were long running:\n"
689         << task_tracker_->DescribeRunningTasks();
690   }
691 }
692 
RunUntilIdle()693 void TaskEnvironment::RunUntilIdle() {
694   DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
695 
696   if (threading_mode_ == ThreadingMode::MAIN_THREAD_ONLY) {
697     RunLoop(RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
698     return;
699   }
700 
701   // TODO(gab): This can be heavily simplified to essentially:
702   //     bool HasMainThreadTasks() {
703   //      if (message_loop_)
704   //        return !message_loop_->IsIdleForTesting();
705   //      return mock_time_task_runner_->NextPendingTaskDelay().is_zero();
706   //     }
707   //     while (task_tracker_->HasIncompleteTasks() || HasMainThreadTasks()) {
708   //       base::RunLoop().RunUntilIdle();
709   //       // Avoid busy-looping.
710   //       if (task_tracker_->HasIncompleteTasks())
711   //         PlatformThread::Sleep(Milliseconds(1));
712   //     }
713   // Update: This can likely be done now that MessageLoop::IsIdleForTesting()
714   // checks all queues.
715   //
716   // Other than that it works because once |task_tracker_->HasIncompleteTasks()|
717   // is false we know for sure that the only thing that can make it true is a
718   // main thread task (TaskEnvironment owns all the threads). As such we can't
719   // racily see it as false on the main thread and be wrong as if it the main
720   // thread sees the atomic count at zero, it's the only one that can make it go
721   // up. And the only thing that can make it go up on the main thread are main
722   // thread tasks and therefore we're done if there aren't any left.
723   //
724   // This simplification further allows simplification of DisallowRunTasks().
725   //
726   // This can also be simplified even further once TaskTracker becomes directly
727   // aware of main thread tasks. https://crbug.com/660078.
728 
729   const bool could_run_tasks = task_tracker_->AllowRunTasks();
730 
731   for (;;) {
732     task_tracker_->AllowRunTasks();
733 
734     // First run as many tasks as possible on the main thread in parallel with
735     // tasks in ThreadPool. This increases likelihood of TSAN catching
736     // threading errors and eliminates possibility of hangs should a
737     // ThreadPool task synchronously block on a main thread task
738     // (ThreadPoolInstance::FlushForTesting() can't be used here for that
739     // reason).
740     RunLoop(RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
741 
742     // Then halt ThreadPool. DisallowRunTasks() failing indicates that there
743     // were ThreadPool tasks currently running. In that case, try again from
744     // top when DisallowRunTasks() yields control back to this thread as they
745     // may have posted main thread tasks.
746     if (!task_tracker_->DisallowRunTasks()) {
747       continue;
748     }
749 
750     // Once ThreadPool is halted. Run any remaining main thread tasks (which
751     // may have been posted by ThreadPool tasks that completed between the
752     // above main thread RunUntilIdle() and ThreadPool DisallowRunTasks()).
753     // Note: this assumes that no main thread task synchronously blocks on a
754     // ThreadPool tasks (it certainly shouldn't); this call could otherwise
755     // hang.
756     RunLoop(RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
757 
758     // The above RunUntilIdle() guarantees there are no remaining main thread
759     // tasks (the ThreadPool being halted during the last RunUntilIdle() is
760     // key as it prevents a task being posted to it racily with it determining
761     // it had no work remaining). Therefore, we're done if there is no more work
762     // on ThreadPool either (there can be ThreadPool work remaining if
763     // DisallowRunTasks() preempted work and/or the last RunUntilIdle() posted
764     // more ThreadPool tasks).
765     // Note: this last |if| couldn't be turned into a |do {} while();|. A
766     // conditional loop makes it such that |continue;| results in checking the
767     // condition (not unconditionally loop again) which would be incorrect for
768     // the above logic as it'd then be possible for a ThreadPool task to be
769     // running during the DisallowRunTasks() test, causing it to fail, but then
770     // post to the main thread and complete before the loop's condition is
771     // verified which could result in HasIncompleteUndelayedTasksForTesting()
772     // returning false and the loop erroneously exiting with a pending task on
773     // the main thread.
774     if (!task_tracker_->HasIncompleteTaskSourcesForTesting()) {
775       break;
776     }
777   }
778 
779   // The above loop always ends with running tasks being disallowed. Re-enable
780   // parallel execution before returning if it was allowed at the beginning of
781   // this call.
782   if (could_run_tasks) {
783     task_tracker_->AllowRunTasks();
784   }
785 }
786 
FastForwardBy(TimeDelta delta)787 void TaskEnvironment::FastForwardBy(TimeDelta delta) {
788   FastForwardByInternal(delta, /*advance_live_ticks=*/true);
789 }
790 
SuspendedFastForwardBy(TimeDelta delta)791 void TaskEnvironment::SuspendedFastForwardBy(TimeDelta delta) {
792   FastForwardByInternal(delta, /*advance_live_ticks=*/false);
793 }
794 
FastForwardByInternal(TimeDelta delta,bool advance_live_ticks)795 void TaskEnvironment::FastForwardByInternal(TimeDelta delta,
796                                             bool advance_live_ticks) {
797   DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
798   DCHECK(mock_time_domain_);
799   DCHECK_GE(delta, TimeDelta());
800 
801   const bool could_run_tasks = task_tracker_ && task_tracker_->AllowRunTasks();
802 
803   const TimeTicks fast_forward_until = mock_time_domain_->NowTicks() + delta;
804   do {
805     RunUntilIdle();
806     // ReclaimMemory sweeps canceled delayed tasks, making sure
807     // FastForwardToNextTaskOrCap isn't affected by canceled tasks.
808     sequence_manager_->ReclaimMemory();
809   } while (mock_time_domain_->FastForwardToNextTaskOrCap(
810                sequence_manager_->GetNextDelayedWakeUp(), fast_forward_until,
811                advance_live_ticks) != MockTimeDomain::NextTaskSource::kNone);
812 
813   if (task_tracker_ && !could_run_tasks) {
814     task_tracker_->DisallowRunTasks();
815   }
816 }
817 
FastForwardUntilNoTasksRemain()818 void TaskEnvironment::FastForwardUntilNoTasksRemain() {
819   // TimeTicks::operator+(TimeDelta) uses saturated arithmetic so it's safe to
820   // pass in TimeDelta::Max().
821   FastForwardBy(TimeDelta::Max());
822 }
823 
AdvanceClock(TimeDelta delta)824 void TaskEnvironment::AdvanceClock(TimeDelta delta) {
825   DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
826   DCHECK(mock_time_domain_);
827   DCHECK_GE(delta, TimeDelta());
828   mock_time_domain_->AdvanceClock(delta);
829 }
830 
SuspendedAdvanceClock(TimeDelta delta)831 void TaskEnvironment::SuspendedAdvanceClock(TimeDelta delta) {
832   DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
833   DCHECK(mock_time_domain_);
834   DCHECK_GE(delta, TimeDelta());
835   mock_time_domain_->SuspendedAdvanceClock(delta);
836 }
837 
GetMockTickClock() const838 const TickClock* TaskEnvironment::GetMockTickClock() const {
839   DCHECK(mock_time_domain_);
840   return mock_time_domain_.get();
841 }
842 
NowTicks() const843 base::TimeTicks TaskEnvironment::NowTicks() const {
844   DCHECK(mock_time_domain_);
845   return mock_time_domain_->NowTicks();
846 }
847 
NowLiveTicks() const848 base::LiveTicks TaskEnvironment::NowLiveTicks() const {
849   DCHECK(mock_time_domain_);
850   return mock_time_domain_->NowLiveTicks();
851 }
852 
GetMockClock() const853 const Clock* TaskEnvironment::GetMockClock() const {
854   DCHECK(mock_clock_);
855   return mock_clock_.get();
856 }
857 
GetPendingMainThreadTaskCount() const858 size_t TaskEnvironment::GetPendingMainThreadTaskCount() const {
859   DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
860 
861   // ReclaimMemory sweeps canceled delayed tasks.
862   sequence_manager_->ReclaimMemory();
863   return sequence_manager_->GetPendingTaskCountForTesting();
864 }
865 
NextMainThreadPendingTaskDelay() const866 TimeDelta TaskEnvironment::NextMainThreadPendingTaskDelay() const {
867   DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
868 
869   // ReclaimMemory sweeps canceled delayed tasks.
870   sequence_manager_->ReclaimMemory();
871   DCHECK(mock_time_domain_);
872   LazyNow lazy_now(mock_time_domain_->NowTicks());
873   if (!sequence_manager_->IsIdleForTesting()) {
874     return TimeDelta();
875   }
876   std::optional<sequence_manager::WakeUp> wake_up =
877       sequence_manager_->GetNextDelayedWakeUp();
878   return wake_up ? wake_up->time - lazy_now.Now() : TimeDelta::Max();
879 }
880 
NextTaskIsDelayed() const881 bool TaskEnvironment::NextTaskIsDelayed() const {
882   DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
883 
884   TimeDelta delay = NextMainThreadPendingTaskDelay();
885   return !delay.is_zero() && !delay.is_max();
886 }
887 
DescribeCurrentTasks() const888 void TaskEnvironment::DescribeCurrentTasks() const {
889   DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
890   LOG(INFO) << task_tracker_->DescribeRunningTasks();
891   LOG(INFO) << sequence_manager_->DescribeAllPendingTasks();
892 }
893 
DetachFromThread()894 void TaskEnvironment::DetachFromThread() {
895   DETACH_FROM_THREAD(main_thread_checker_);
896   if (task_tracker_) {
897     task_tracker_->controller_thread_checker_.DetachFromThread();
898   }
899 }
900 
901 // static
AddDestructionObserver(DestructionObserver * observer)902 void TaskEnvironment::AddDestructionObserver(DestructionObserver* observer) {
903   GetDestructionObservers().AddObserver(observer);
904 }
905 
906 // static
RemoveDestructionObserver(DestructionObserver * observer)907 void TaskEnvironment::RemoveDestructionObserver(DestructionObserver* observer) {
908   GetDestructionObservers().RemoveObserver(observer);
909 }
910 
ParallelExecutionFence(const char * error_message)911 TaskEnvironment::ParallelExecutionFence::ParallelExecutionFence(
912     const char* error_message) {
913   CHECK(!g_task_tracker || g_task_tracker->OnControllerThread())
914       << error_message;
915   if (g_task_tracker) {
916     // Do not attempt to install a fence post shutdown, the only remaining tasks
917     // at that point are CONTINUE_ON_SHUTDOWN and attempting to wait for them
918     // causes more issues (test timeouts) than the fence solves (data races on
919     // global state). CONTINUE_ON_SHUTDOWN tasks should generally not be
920     // touching global state and while not all users of ParallelExecutionFence
921     // (FeatureList) guard against access from CONTINUE_ON_SHUTDOWN tasks, any
922     // such tasks abusing this would be flagged by TSAN and have to be fixed
923     // manually. Note: this is only relevant in browser tests as unit tests
924     // already go through a full join in TaskEnvironment::DestroyThreadPool().
925     previously_allowed_to_run_ = g_task_tracker->TasksAllowedToRun() &&
926                                  !g_task_tracker->IsShutdownComplete();
927 
928     // DisallowRunTasks typically yields back if it fails to reach quiescence
929     // within 1ms. This is typically done to let the main thread run tasks that
930     // could potentially be blocking main thread tasks. In this case however,
931     // main thread making progress while installing the fence would be more
932     // surprising. So allow more time but report errors after a while.
933     while (previously_allowed_to_run_ &&
934            !g_task_tracker->DisallowRunTasks(Seconds(5))) {
935       LOG(WARNING) << "Installing ParallelExecutionFence is slow because of "
936                       "these running tasks:\n"
937                    << g_task_tracker->DescribeRunningTasks()
938                    << "\nParallelExecutionFence requested by:\n"
939                    << debug::StackTrace();
940     }
941   } else if (ThreadPoolInstance::Get()) {
942     LOG(WARNING)
943         << "ParallelExecutionFence is ineffective when ThreadPoolInstance is "
944            "not managed by a TaskEnvironment.\n"
945            "Test fixtures should use a TaskEnvironment member or statically "
946            "invoke TaskEnvironment::CreateThreadPool() + "
947            "ThreadPoolInstance::Get()->StartWithDefaultParams() when the "
948            "former is not possible.";
949   }
950 }
951 
~ParallelExecutionFence()952 TaskEnvironment::ParallelExecutionFence::~ParallelExecutionFence() {
953   if (previously_allowed_to_run_) {
954     g_task_tracker->AllowRunTasks();
955   }
956 }
957 
TestTaskTracker()958 TaskEnvironment::TestTaskTracker::TestTaskTracker()
959     : can_run_tasks_cv_(&lock_), task_completed_cv_(&lock_) {
960   // Consider threads blocked on these as idle (avoids instantiating
961   // ScopedBlockingCalls and confusing some //base internals tests).
962   can_run_tasks_cv_.declare_only_used_while_idle();
963   task_completed_cv_.declare_only_used_while_idle();
964 }
965 
AllowRunTasks()966 bool TaskEnvironment::TestTaskTracker::AllowRunTasks() {
967   AutoLock auto_lock(lock_);
968   const bool could_run_tasks = can_run_tasks_;
969   can_run_tasks_ = true;
970   can_run_tasks_cv_.Broadcast();
971   return could_run_tasks;
972 }
973 
TasksAllowedToRun() const974 bool TaskEnvironment::TestTaskTracker::TasksAllowedToRun() const {
975   AutoLock auto_lock(lock_);
976   return can_run_tasks_;
977 }
978 
DisallowRunTasks(TimeDelta timeout)979 bool TaskEnvironment::TestTaskTracker::DisallowRunTasks(TimeDelta timeout) {
980   // Disallowing task running should only be done from the main thread to avoid
981   // racing with shutdown.
982   DCHECK(OnControllerThread());
983 
984   AutoLock auto_lock(lock_);
985 
986   // Can't disallow run task if there are tasks running.
987   for (TimeTicks now = subtle::TimeTicksNowIgnoringOverride(),
988                  end = now + timeout;
989        !running_tasks_.empty() && now < end;
990        now = subtle::TimeTicksNowIgnoringOverride()) {
991     task_completed_cv_.TimedWait(end - now);
992   }
993   // Timed out waiting for running tasks, yield to caller.
994   if (!running_tasks_.empty()) {
995     // This condition should never be sought after shutdown and this call
996     // shouldn't be racing shutdown either per the above `OnControllerThread()`
997     // contract.
998     DCHECK(!IsShutdownComplete());
999     return false;
1000   }
1001 
1002   can_run_tasks_ = false;
1003   return true;
1004 }
1005 
RunTask(internal::Task task,internal::TaskSource * sequence,const TaskTraits & traits)1006 void TaskEnvironment::TestTaskTracker::RunTask(internal::Task task,
1007                                                internal::TaskSource* sequence,
1008                                                const TaskTraits& traits) {
1009   const Location posted_from = task.posted_from;
1010   int task_number;
1011   {
1012     AutoLock auto_lock(lock_);
1013 
1014     while (!can_run_tasks_) {
1015       can_run_tasks_cv_.Wait();
1016     }
1017 
1018     task_number = next_task_number_++;
1019     auto pair = running_tasks_.emplace(task_number, posted_from);
1020     CHECK(pair.second);  // If false, the |task_number| was already present.
1021   }
1022 
1023   // Using TimeTicksNowIgnoringOverride() because in tests that mock time,
1024   // Now() can advance very far very fast, and that's not a problem. This is
1025   // watching for tests that have actually long running tasks which cause our
1026   // test suites to run slowly.
1027   base::TimeTicks before = base::subtle::TimeTicksNowIgnoringOverride();
1028   internal::ThreadPoolImpl::TaskTrackerImpl::RunTask(std::move(task), sequence,
1029                                                      traits);
1030   base::TimeTicks after = base::subtle::TimeTicksNowIgnoringOverride();
1031 
1032   const TimeDelta kTimeout = TestTimeouts::action_max_timeout();
1033   if ((after - before) > kTimeout) {
1034     ADD_FAILURE() << "TaskEnvironment: RunTask took more than "
1035                   << kTimeout.InSeconds() << " seconds. Posted from "
1036                   << posted_from.ToString();
1037   }
1038 
1039   {
1040     AutoLock auto_lock(lock_);
1041     CHECK(can_run_tasks_);
1042     size_t found = running_tasks_.erase(task_number);
1043     CHECK_EQ(1u, found);
1044 
1045     task_completed_cv_.Broadcast();
1046   }
1047 }
1048 
DescribeRunningTasks() const1049 std::string TaskEnvironment::TestTaskTracker::DescribeRunningTasks() const {
1050   base::flat_map<int64_t, Location> running_tasks_copy;
1051   {
1052     AutoLock auto_lock(lock_);
1053     running_tasks_copy = running_tasks_;
1054   }
1055   std::string running_tasks_str = "ThreadPool currently running tasks:";
1056   if (running_tasks_copy.empty()) {
1057     running_tasks_str += " none.";
1058   } else {
1059     for (auto& pair : running_tasks_copy) {
1060       running_tasks_str += "\n  Task posted from: " + pair.second.ToString();
1061     }
1062   }
1063   return running_tasks_str;
1064 }
1065 
BeginCompleteShutdown(base::WaitableEvent & shutdown_event)1066 void TaskEnvironment::TestTaskTracker::BeginCompleteShutdown(
1067     base::WaitableEvent& shutdown_event) {
1068   const TimeDelta kTimeout = TestTimeouts::action_max_timeout();
1069   if (shutdown_event.TimedWait(kTimeout)) {
1070     return;  // All tasks completed in time, yay! Yield back to shutdown.
1071   }
1072 
1073   // If we had to wait too long for the shutdown tasks to complete, then we
1074   // should fail the test and report which tasks are currently running.
1075   std::string failure_tasks = DescribeRunningTasks();
1076 
1077   ADD_FAILURE() << "TaskEnvironment: CompleteShutdown took more than "
1078                 << kTimeout.InSeconds() << " seconds.\n"
1079                 << failure_tasks;
1080   base::Process::TerminateCurrentProcessImmediately(-1);
1081 }
1082 
AssertFlushForTestingAllowed()1083 void TaskEnvironment::TestTaskTracker::AssertFlushForTestingAllowed() {
1084   AutoLock auto_lock(lock_);
1085   ASSERT_TRUE(can_run_tasks_)
1086       << "FlushForTesting() requires ThreadPool tasks to be allowed to run or "
1087          "it will hang. Note: DisallowRunTasks happens implicitly on-and-off "
1088          "during TaskEnvironment::RunUntilIdle and main thread tasks running "
1089          "under it should thus never FlushForTesting().";
1090 }
1091 
1092 }  // namespace test
1093 }  // namespace base
1094