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 #ifndef BASE_TEST_TASK_ENVIRONMENT_H_ 6 #define BASE_TEST_TASK_ENVIRONMENT_H_ 7 8 #include <memory> 9 10 #include "base/compiler_specific.h" 11 #include "base/functional/callback_forward.h" 12 #include "base/memory/raw_ptr_exclusion.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/observer_list_types.h" 15 #include "base/run_loop.h" 16 #include "base/task/lazy_thread_pool_task_runner.h" 17 #include "base/task/sequence_manager/sequence_manager.h" 18 #include "base/task/single_thread_task_runner.h" 19 #include "base/test/scoped_run_loop_timeout.h" 20 #include "base/threading/thread_checker.h" 21 #include "base/time/time.h" 22 #include "base/traits_bag.h" 23 #include "build/build_config.h" 24 25 namespace base { 26 27 class Clock; 28 class FileDescriptorWatcher; 29 class TickClock; 30 31 namespace subtle { 32 class ScopedTimeClockOverrides; 33 } 34 35 namespace test { 36 37 // This header exposes SingleThreadTaskEnvironment and TaskEnvironment. 38 // 39 // SingleThreadTaskEnvironment enables the following APIs within its scope: 40 // - (SingleThread|Sequenced)TaskRunner::CurrentDefaultHandle on the main 41 // thread 42 // - RunLoop on the main thread 43 // 44 // TaskEnvironment additionally enables: 45 // - posting to base::ThreadPool through base/task/thread_pool.h. 46 // 47 // Hint: For content::BrowserThreads, use content::BrowserTaskEnvironment. 48 // 49 // Tests should prefer SingleThreadTaskEnvironment over TaskEnvironment when the 50 // former is sufficient. 51 // 52 // Tasks posted to the (SingleThread|Sequenced)TaskRunner::CurrentDefaultHandle 53 // run synchronously when RunLoop::Run(UntilIdle) or 54 // TaskEnvironment::RunUntil(Idle|Quit) is called on the main thread. 55 // 56 // The TaskEnvironment requires TestTimeouts::Initialize() to be called in order 57 // to run posted tasks, so that it can watch for problematic long-running tasks. 58 // 59 // The TimeSource trait can be used to request that delayed tasks be under the 60 // manual control of RunLoop::Run() and TaskEnvironment::FastForward*() methods. 61 // 62 // If a TaskEnvironment's ThreadPoolExecutionMode is QUEUED, ThreadPool tasks 63 // run when RunUntilIdle(), RunUntilQuit(), or ~TaskEnvironment is called. If 64 // ThreadPoolExecutionMode is ASYNC, they run as they are posted. 65 // 66 // All TaskEnvironment methods must be called from the main thread. 67 // 68 // Usage: 69 // 70 // class MyTestFixture : public testing::Test { 71 // public: 72 // (...) 73 // 74 // // protected rather than private visibility will allow controlling the 75 // // task environment (e.g. RunUntilIdle(), FastForwardBy(), etc.). from the 76 // // test body. 77 // protected: 78 // // Must generally be the first member to be initialized first and 79 // // destroyed last (some members that require single-threaded 80 // // initialization and tear down may need to come before -- e.g. 81 // // base::test::ScopedFeatureList). Extra traits, like TimeSource, are 82 // // best provided inline when declaring the TaskEnvironment, as 83 // // such: 84 // base::test::TaskEnvironment task_environment_{ 85 // base::test::TaskEnvironment::TimeSource::MOCK_TIME}; 86 // 87 // // Other members go here (or further below in private section.) 88 // }; 89 class TaskEnvironment { 90 protected: 91 // This enables a two-phase initialization for sub classes such as 92 // content::BrowserTaskEnvironment which need to provide the default task 93 // queue because they instantiate a scheduler on the same thread. Subclasses 94 // using this trait must invoke DeferredInitFromSubclass() before running the 95 // task environment. 96 struct SubclassCreatesDefaultTaskRunner {}; 97 98 public: 99 enum class TimeSource { 100 // Delayed tasks and Time/TimeTicks::Now() use the real-time system clock. 101 SYSTEM_TIME, 102 103 // Delayed tasks use a mock clock which only advances when reaching "idle" 104 // during a RunLoop::Run() call on the main thread or a FastForward*() call 105 // to this TaskEnvironment. "idle" is defined as the main thread and thread 106 // pool being out of ready tasks. In that situation : time advances to the 107 // soonest delay between main thread and thread pool delayed tasks, 108 // according to the semantics of the current Run*() or FastForward*() call. 109 // 110 // This also mocks Time/TimeTicks::Now() with the same mock clock. 111 // Time::Now() and TimeTicks::Now() (with respect to its origin) start 112 // without submillisecond components. 113 // 114 // Warning some platform APIs are still real-time, e.g.: 115 // * PlatformThread::Sleep 116 // * WaitableEvent::TimedWait 117 // * ConditionVariable::TimedWait 118 // * Delayed tasks on unmanaged base::Thread's and other custom task 119 // runners. 120 MOCK_TIME, 121 122 DEFAULT = SYSTEM_TIME 123 }; 124 125 // This type will determine what types of messages will get pumped by the main 126 // thread. 127 // Note: If your test needs to use a custom MessagePump you should 128 // consider using a SingleThreadTaskExecutor instead. 129 enum class MainThreadType { 130 // The main thread doesn't pump system messages. 131 DEFAULT, 132 // The main thread pumps UI messages. 133 UI, 134 // The main thread pumps asynchronous IO messages and supports the 135 // FileDescriptorWatcher API on POSIX. 136 IO, 137 }; 138 139 // Note that this is irrelevant (and ignored) under 140 // ThreadingMode::MAIN_THREAD_ONLY 141 enum class ThreadPoolExecutionMode { 142 // Thread pool tasks are queued and only executed when RunUntilIdle(), 143 // FastForwardBy(), or FastForwardUntilNoTasksRemain() are explicitly 144 // called. Note: RunLoop::Run() does *not* unblock the ThreadPool in this 145 // mode (it strictly runs only the main thread). 146 QUEUED, 147 // Thread pool tasks run as they are posted. RunUntilIdle() can still be 148 // used to block until done. 149 // Note that regardless of this trait, delayed tasks are always "queued" 150 // under TimeSource::MOCK_TIME mode. 151 ASYNC, 152 DEFAULT = ASYNC 153 }; 154 155 enum class ThreadingMode { 156 // ThreadPool will be initialized, thus adding support for multi-threaded 157 // tests. 158 MULTIPLE_THREADS, 159 // No thread pool will be initialized. Useful for tests that want to run 160 // single threaded. Prefer using SingleThreadTaskEnvironment over this 161 // trait. 162 MAIN_THREAD_ONLY, 163 DEFAULT = MULTIPLE_THREADS 164 }; 165 166 // On Windows, sets the COM environment for the ThreadPoolInstance. Ignored 167 // on other platforms. 168 enum class ThreadPoolCOMEnvironment { 169 // Do not initialize COM for the pool's workers. 170 NONE, 171 172 // Place the pool's workers in a COM MTA. 173 COM_MTA, 174 175 // Enable the MTA by default in unit tests to match the browser process's 176 // ThreadPoolInstance configuration. 177 // 178 // This has the adverse side-effect of enabling the MTA in non-browser unit 179 // tests as well but the downside there is not as bad as not having it in 180 // browser unit tests. It just means some COM asserts may pass in unit 181 // tests where they wouldn't in integration tests or prod. That's okay 182 // because unit tests are already generally very loose on allowing I/O, 183 // waits, etc. Such misuse will still be caught in later phases (and COM 184 // usage should already be pretty much inexistent in sandboxed processes). 185 DEFAULT = COM_MTA, 186 }; 187 188 // List of traits that are valid inputs for the constructor below. 189 struct ValidTraits { 190 ValidTraits(TimeSource); 191 ValidTraits(MainThreadType); 192 ValidTraits(ThreadPoolExecutionMode); 193 ValidTraits(SubclassCreatesDefaultTaskRunner); 194 ValidTraits(ThreadingMode); 195 ValidTraits(ThreadPoolCOMEnvironment); 196 }; 197 198 // Constructor accepts zero or more traits which customize the testing 199 // environment. 200 template <typename... TaskEnvironmentTraits, 201 class CheckArgumentsAreValid = std::enable_if_t< 202 trait_helpers::AreValidTraits<ValidTraits, 203 TaskEnvironmentTraits...>::value>> TaskEnvironment(TaskEnvironmentTraits...traits)204 NOINLINE explicit TaskEnvironment(TaskEnvironmentTraits... traits) 205 : TaskEnvironment(sequence_manager::SequenceManager::PrioritySettings:: 206 CreateDefault(), 207 traits...) {} 208 209 TaskEnvironment(const TaskEnvironment&) = delete; 210 TaskEnvironment& operator=(const TaskEnvironment&) = delete; 211 212 // Waits until no undelayed ThreadPool tasks remain. Then, unregisters the 213 // ThreadPoolInstance and the 214 // (SingleThread|Sequenced)TaskRunner::CurrentDefaultHandle. 215 virtual ~TaskEnvironment(); 216 217 // Returns a TaskRunner that schedules tasks on the main thread. 218 scoped_refptr<base::SingleThreadTaskRunner> GetMainThreadTaskRunner(); 219 220 // Returns whether the main thread's TaskRunner has pending tasks. This will 221 // always return true if called right after RunUntilIdle. 222 bool MainThreadIsIdle() const; 223 224 // Returns a RepeatingClosure that ends the next call to RunUntilQuit(). The 225 // quit closures must be obtained from the thread owning the TaskEnvironment 226 // but may then be invoked from any thread. To avoid a potential race 227 // condition, do not call QuitClosure() while RunUntilQuit() is running. 228 RepeatingClosure QuitClosure(); 229 230 // Runs tasks on both the main thread and the thread pool, until a quit 231 // closure is executed. When RunUntilQuit() returns, all previous quit 232 // closures are invalidated, and will have no effect on future calls. Be sure 233 // to create a new quit closure before calling RunUntilQuit() again. 234 void RunUntilQuit(); 235 236 // Runs tasks until both the 237 // (SingleThread|Sequenced)TaskRunner::CurrentDefaultHandle and the 238 // ThreadPool's non-delayed queues are empty. While RunUntilIdle() is quite 239 // practical and sometimes even necessary -- for example, to flush all tasks 240 // bound to Unretained() state before destroying test members -- it should be 241 // used with caution per the following warnings: 242 // 243 // WARNING #1: This may run long (flakily timeout) and even never return! Do 244 // not use this when repeating tasks such as animated web pages 245 // are present. 246 // WARNING #2: This may return too early! For example, if used to run until an 247 // incoming event has occurred but that event depends on a task in 248 // a different queue -- e.g. a standalone base::Thread or a system 249 // event. 250 // 251 // As such, prefer RunLoop::Run() with an explicit RunLoop::QuitClosure() when 252 // possible. 253 void RunUntilIdle(); 254 255 // Only valid for instances using TimeSource::MOCK_TIME. Fast-forwards 256 // virtual time by |delta|, causing all tasks on the main thread and thread 257 // pool with a remaining delay less than or equal to |delta| to be executed in 258 // their natural order before this returns. |delta| must be non-negative. Upon 259 // returning from this method, NowTicks() will be >= the initial |NowTicks() + 260 // delta|. It is guaranteed to be == iff tasks executed in this 261 // FastForwardBy() didn't result in nested calls to time-advancing-methods. 262 void FastForwardBy(TimeDelta delta); 263 264 // Only valid for instances using TimeSource::MOCK_TIME. 265 // Short for FastForwardBy(TimeDelta::Max()). 266 // 267 // WARNING: This has the same caveat as RunUntilIdle() and is even more likely 268 // to spin forever (any RepeatingTimer will cause this). 269 void FastForwardUntilNoTasksRemain(); 270 271 // Only valid for instances using TimeSource::MOCK_TIME. Advances virtual time 272 // by |delta|. Unlike FastForwardBy, this does not run tasks. Prefer 273 // FastForwardBy() when possible but this can be useful when testing blocked 274 // pending tasks where being idle (required to fast-forward) is not possible. 275 // 276 // Delayed tasks that are ripe as a result of this will be scheduled. 277 // RunUntilIdle() can be used after this call to ensure those tasks have run. 278 // Note: AdvanceClock(delta) + RunUntilIdle() is slightly different from 279 // FastForwardBy(delta) in that time passes instantly before running any task 280 // (whereas FastForwardBy() will advance the clock in the smallest increments 281 // possible at a time). Hence FastForwardBy() is more realistic but 282 // AdvanceClock() can be useful when testing edge case scenarios that 283 // specifically handle more time than expected to have passed. 284 void AdvanceClock(TimeDelta delta); 285 UsesMockTime()286 bool UsesMockTime() const { return !!mock_clock_; } 287 288 // Only valid for instances using TimeSource::MOCK_TIME. Returns a 289 // TickClock whose time is updated by FastForward(By|UntilNoTasksRemain). 290 const TickClock* GetMockTickClock() const; 291 292 // Only valid for instances using TimeSource::MOCK_TIME. Returns a 293 // Clock whose time is updated by FastForward(By|UntilNoTasksRemain). The 294 // initial value is implementation defined and should be queried by tests that 295 // depend on it. 296 // TickClock should be used instead of Clock to measure elapsed time in a 297 // process. See time.h. 298 const Clock* GetMockClock() const; 299 300 // Only valid for instances using TimeSource::MOCK_TIME. Returns the current 301 // virtual tick time (based on a realistic Now(), sampled when this 302 // TaskEnvironment was created, and manually advanced from that point on). 303 // This is always equivalent to base::TimeTicks::Now() under 304 // TimeSource::MOCK_TIME. 305 base::TimeTicks NowTicks() const; 306 307 // Only valid for instances using TimeSource::MOCK_TIME. Returns the number of 308 // pending tasks (delayed and non-delayed) of the main thread's TaskRunner. 309 // When debugging, you can use DescribeCurrentTasks() to see what those are. 310 size_t GetPendingMainThreadTaskCount() const; 311 312 // Only valid for instances using TimeSource::MOCK_TIME. 313 // Returns the delay until the next pending task of the main thread's 314 // TaskRunner if there is one, otherwise it returns TimeDelta::Max(). 315 TimeDelta NextMainThreadPendingTaskDelay() const; 316 317 // Only valid for instances using TimeSource::MOCK_TIME. 318 // Returns true iff the next task is delayed. Returns false if the next task 319 // is immediate or if there is no next task. 320 bool NextTaskIsDelayed() const; 321 322 // For debugging purposes: Dumps information about pending tasks on the main 323 // thread, and currently running tasks on the thread pool. 324 void DescribeCurrentTasks() const; 325 326 // Detach ThreadCheckers (will rebind on next usage), useful for the odd test 327 // suite which doesn't run on the main thread but still has exclusive access 328 // to driving this TaskEnvironment (e.g. WaylandClientTestSuiteServer). 329 void DetachFromThread(); 330 331 class TestTaskTracker; 332 // Callers outside of TaskEnvironment may not use the returned pointer. They 333 // should just use base::ThreadPoolInstance::Get(). 334 static TestTaskTracker* CreateThreadPool(); 335 336 class DestructionObserver : public CheckedObserver { 337 public: 338 DestructionObserver() = default; 339 ~DestructionObserver() override = default; 340 341 DestructionObserver(const DestructionObserver&) = delete; 342 DestructionObserver& operator=(const DestructionObserver&) = delete; 343 344 virtual void WillDestroyCurrentTaskEnvironment() = 0; 345 }; 346 347 // Adds/removes a DestructionObserver to any TaskEnvironment. Observers are 348 // notified when any TaskEnvironment goes out of scope (other than with a move 349 // operation). Must be called on the main thread. 350 static void AddDestructionObserver(DestructionObserver* observer); 351 static void RemoveDestructionObserver(DestructionObserver* observer); 352 353 // Instantiating a ParallelExecutionFence waits for all currently running 354 // ThreadPool tasks before the constructor returns and from then on prevents 355 // additional tasks from running during its lifetime. 356 // 357 // Must be instantiated from the test main thread. 358 class ParallelExecutionFence { 359 public: 360 // Instantiates a ParallelExecutionFence, crashes with an optional 361 // |error_message| if not invoked from test main thread. 362 explicit ParallelExecutionFence(const char* error_message = ""); 363 ~ParallelExecutionFence(); 364 365 ParallelExecutionFence(const ParallelExecutionFence&) = delete; 366 ParallelExecutionFence& operator=(const ParallelExecutionFence& other) = 367 delete; 368 369 private: 370 bool previously_allowed_to_run_ = false; 371 }; 372 373 // The number of foreground workers in the ThreadPool managed by a 374 // TaskEnvironment instance. This can be used to determine the maximum 375 // parallelism in tests that require each parallel task it spawns to be 376 // running at once. Having multiple threads prevents deadlocks should some 377 // blocking APIs not use ScopedBlockingCall. It also allows enough concurrency 378 // to allow TSAN to spot data races. 379 static constexpr int kNumForegroundThreadPoolThreads = 4; 380 381 protected: 382 template <typename... TaskEnvironmentTraits, 383 class CheckArgumentsAreValid = std::enable_if_t< 384 trait_helpers::AreValidTraits<ValidTraits, 385 TaskEnvironmentTraits...>::value>> CreateTaskEnvironmentWithPriorities(sequence_manager::SequenceManager::PrioritySettings priority_settings,TaskEnvironmentTraits...traits)386 NOINLINE static TaskEnvironment CreateTaskEnvironmentWithPriorities( 387 sequence_manager::SequenceManager::PrioritySettings priority_settings, 388 TaskEnvironmentTraits... traits) { 389 return TaskEnvironment(std::move(priority_settings), traits...); 390 } 391 392 // Constructor accepts zero or more traits which customize the testing 393 // environment. 394 template <typename... TaskEnvironmentTraits, 395 class CheckArgumentsAreValid = std::enable_if_t< 396 trait_helpers::AreValidTraits<ValidTraits, 397 TaskEnvironmentTraits...>::value>> TaskEnvironment(sequence_manager::SequenceManager::PrioritySettings priority_settings,TaskEnvironmentTraits...traits)398 NOINLINE explicit TaskEnvironment( 399 sequence_manager::SequenceManager::PrioritySettings priority_settings, 400 TaskEnvironmentTraits... traits) 401 : TaskEnvironment( 402 std::move(priority_settings), 403 trait_helpers::GetEnum<TimeSource, TimeSource::DEFAULT>(traits...), 404 trait_helpers::GetEnum<MainThreadType, MainThreadType::DEFAULT>( 405 traits...), 406 trait_helpers::GetEnum<ThreadPoolExecutionMode, 407 ThreadPoolExecutionMode::DEFAULT>(traits...), 408 trait_helpers::GetEnum<ThreadingMode, ThreadingMode::DEFAULT>( 409 traits...), 410 trait_helpers::GetEnum<ThreadPoolCOMEnvironment, 411 ThreadPoolCOMEnvironment::DEFAULT>( 412 traits...), 413 trait_helpers::HasTrait<SubclassCreatesDefaultTaskRunner, 414 TaskEnvironmentTraits...>(), 415 trait_helpers::NotATraitTag()) {} 416 417 TaskEnvironment(TaskEnvironment&& other); 418 main_thread_type()419 constexpr MainThreadType main_thread_type() const { 420 return main_thread_type_; 421 } 422 thread_pool_execution_mode()423 constexpr ThreadPoolExecutionMode thread_pool_execution_mode() const { 424 return thread_pool_execution_mode_; 425 } 426 427 // Returns the MockTimeDomain driving this TaskEnvironment if this instance is 428 // using TimeSource::MOCK_TIME, nullptr otherwise. 429 sequence_manager::TimeDomain* GetMockTimeDomain() const; 430 431 sequence_manager::SequenceManager* sequence_manager() const; 432 433 void DeferredInitFromSubclass( 434 scoped_refptr<base::SingleThreadTaskRunner> task_runner); 435 436 // Derived classes may need to control when the task environment goes away 437 // (e.g. ~FooTaskEnvironment() may want to effectively trigger 438 // ~TaskEnvironment() before its members are destroyed). 439 void DestroyTaskEnvironment(); 440 441 private: 442 class MockTimeDomain; 443 444 void InitializeThreadPool(); 445 void ShutdownAndJoinThreadPool(); 446 void DestroyThreadPool(); 447 448 void CompleteInitialization(); 449 450 // The template constructor has to be in the header but it delegates to this 451 // constructor to initialize all other members out-of-line. 452 TaskEnvironment( 453 sequence_manager::SequenceManager::PrioritySettings priority_settings, 454 TimeSource time_source, 455 MainThreadType main_thread_type, 456 ThreadPoolExecutionMode thread_pool_execution_mode, 457 ThreadingMode threading_mode, 458 ThreadPoolCOMEnvironment thread_pool_com_environment, 459 bool subclass_creates_default_taskrunner, 460 trait_helpers::NotATraitTag tag); 461 462 const MainThreadType main_thread_type_; 463 const ThreadPoolExecutionMode thread_pool_execution_mode_; 464 const ThreadingMode threading_mode_; 465 const ThreadPoolCOMEnvironment thread_pool_com_environment_; 466 const bool subclass_creates_default_taskrunner_; 467 468 std::unique_ptr<sequence_manager::SequenceManager> sequence_manager_; 469 470 // Manages the clock under TimeSource::MOCK_TIME modes. Null in 471 // TimeSource::SYSTEM_TIME mode. 472 std::unique_ptr<MockTimeDomain> mock_time_domain_; 473 474 // Overrides Time/TimeTicks::Now() under TimeSource::MOCK_TIME mode. 475 // Null in other modes. 476 std::unique_ptr<subtle::ScopedTimeClockOverrides> time_overrides_; 477 478 scoped_refptr<sequence_manager::TaskQueue> task_queue_; 479 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 480 481 // Only set for instances using TimeSource::MOCK_TIME. 482 std::unique_ptr<Clock> mock_clock_; 483 484 #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) 485 // Enables the FileDescriptorWatcher API iff running a MainThreadType::IO. 486 std::unique_ptr<FileDescriptorWatcher> file_descriptor_watcher_; 487 #endif 488 489 // Owned by the ThreadPoolInstance. 490 // This field is not a raw_ptr<> because it was filtered by the rewriter for: 491 // #union 492 RAW_PTR_EXCLUSION TestTaskTracker* task_tracker_ = nullptr; 493 494 // Ensures destruction of lazy TaskRunners when this is destroyed. 495 std::unique_ptr<base::internal::ScopedLazyTaskRunnerListForTesting> 496 scoped_lazy_task_runner_list_for_testing_; 497 498 // Sets RunLoop::Run() to LOG(FATAL) if not Quit() in a timely manner. 499 std::unique_ptr<ScopedRunLoopTimeout> run_loop_timeout_; 500 501 std::unique_ptr<bool> owns_instance_ = std::make_unique<bool>(true); 502 503 std::unique_ptr<RunLoop> run_until_quit_loop_; 504 505 // Used to verify thread-affinity of operations that must occur on the main 506 // thread. This is the case for anything that modifies or drives the 507 // |sequence_manager_|. 508 THREAD_CHECKER(main_thread_checker_); 509 }; 510 511 // SingleThreadTaskEnvironment takes the same traits as TaskEnvironment and is 512 // used the exact same way. It's a short-form for 513 // TaskEnvironment{TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY, ...}; 514 class SingleThreadTaskEnvironment : public TaskEnvironment { 515 public: 516 template <class... ArgTypes> SingleThreadTaskEnvironment(ArgTypes...args)517 SingleThreadTaskEnvironment(ArgTypes... args) 518 : TaskEnvironment(ThreadingMode::MAIN_THREAD_ONLY, args...) {} 519 }; 520 521 } // namespace test 522 } // namespace base 523 524 #endif // BASE_TEST_TASK_ENVIRONMENT_H_ 525