1*635a8641SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors. All rights reserved. 2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file. 4*635a8641SAndroid Build Coastguard Worker 5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_TEST_SCOPED_TASK_ENVIRONMENT_H_ 6*635a8641SAndroid Build Coastguard Worker #define BASE_TEST_SCOPED_TASK_ENVIRONMENT_H_ 7*635a8641SAndroid Build Coastguard Worker 8*635a8641SAndroid Build Coastguard Worker #include "base/macros.h" 9*635a8641SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h" 10*635a8641SAndroid Build Coastguard Worker #include "base/single_thread_task_runner.h" 11*635a8641SAndroid Build Coastguard Worker #include "base/task_scheduler/lazy_task_runner.h" 12*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h" 13*635a8641SAndroid Build Coastguard Worker 14*635a8641SAndroid Build Coastguard Worker namespace base { 15*635a8641SAndroid Build Coastguard Worker 16*635a8641SAndroid Build Coastguard Worker namespace internal { 17*635a8641SAndroid Build Coastguard Worker class ScopedSetSequenceLocalStorageMapForCurrentThread; 18*635a8641SAndroid Build Coastguard Worker class SequenceLocalStorageMap; 19*635a8641SAndroid Build Coastguard Worker } // namespace internal 20*635a8641SAndroid Build Coastguard Worker 21*635a8641SAndroid Build Coastguard Worker class FileDescriptorWatcher; 22*635a8641SAndroid Build Coastguard Worker class MessageLoop; 23*635a8641SAndroid Build Coastguard Worker class TaskScheduler; 24*635a8641SAndroid Build Coastguard Worker class TestMockTimeTaskRunner; 25*635a8641SAndroid Build Coastguard Worker class TickClock; 26*635a8641SAndroid Build Coastguard Worker 27*635a8641SAndroid Build Coastguard Worker namespace test { 28*635a8641SAndroid Build Coastguard Worker 29*635a8641SAndroid Build Coastguard Worker // ScopedTaskEnvironment allows usage of these APIs within its scope: 30*635a8641SAndroid Build Coastguard Worker // - (Thread|Sequenced)TaskRunnerHandle, on the thread where it lives 31*635a8641SAndroid Build Coastguard Worker // - base/task_scheduler/post_task.h, on any thread 32*635a8641SAndroid Build Coastguard Worker // 33*635a8641SAndroid Build Coastguard Worker // Tests that need either of these APIs should instantiate a 34*635a8641SAndroid Build Coastguard Worker // ScopedTaskEnvironment. 35*635a8641SAndroid Build Coastguard Worker // 36*635a8641SAndroid Build Coastguard Worker // Tasks posted to the (Thread|Sequenced)TaskRunnerHandle run synchronously when 37*635a8641SAndroid Build Coastguard Worker // RunLoop::Run(UntilIdle) or ScopedTaskEnvironment::RunUntilIdle is called on 38*635a8641SAndroid Build Coastguard Worker // the thread where the ScopedTaskEnvironment lives. 39*635a8641SAndroid Build Coastguard Worker // 40*635a8641SAndroid Build Coastguard Worker // Tasks posted through base/task_scheduler/post_task.h run on dedicated 41*635a8641SAndroid Build Coastguard Worker // threads. If ExecutionMode is QUEUED, they run when RunUntilIdle() or 42*635a8641SAndroid Build Coastguard Worker // ~ScopedTaskEnvironment is called. If ExecutionMode is ASYNC, they run 43*635a8641SAndroid Build Coastguard Worker // as they are posted. 44*635a8641SAndroid Build Coastguard Worker // 45*635a8641SAndroid Build Coastguard Worker // All methods of ScopedTaskEnvironment must be called from the same thread. 46*635a8641SAndroid Build Coastguard Worker // 47*635a8641SAndroid Build Coastguard Worker // Usage: 48*635a8641SAndroid Build Coastguard Worker // 49*635a8641SAndroid Build Coastguard Worker // class MyTestFixture : public testing::Test { 50*635a8641SAndroid Build Coastguard Worker // public: 51*635a8641SAndroid Build Coastguard Worker // (...) 52*635a8641SAndroid Build Coastguard Worker // 53*635a8641SAndroid Build Coastguard Worker // protected: 54*635a8641SAndroid Build Coastguard Worker // // Must be the first member (or at least before any member that cares 55*635a8641SAndroid Build Coastguard Worker // // about tasks) to be initialized first and destroyed last. protected 56*635a8641SAndroid Build Coastguard Worker // // instead of private visibility will allow controlling the task 57*635a8641SAndroid Build Coastguard Worker // // environment (e.g. clock) once such features are added (see design doc 58*635a8641SAndroid Build Coastguard Worker // // below for details), until then it at least doesn't hurt :). 59*635a8641SAndroid Build Coastguard Worker // base::test::ScopedTaskEnvironment scoped_task_environment_; 60*635a8641SAndroid Build Coastguard Worker // 61*635a8641SAndroid Build Coastguard Worker // // Other members go here (or further below in private section.) 62*635a8641SAndroid Build Coastguard Worker // }; 63*635a8641SAndroid Build Coastguard Worker // 64*635a8641SAndroid Build Coastguard Worker // Design and future improvements documented in 65*635a8641SAndroid Build Coastguard Worker // https://docs.google.com/document/d/1QabRo8c7D9LsYY3cEcaPQbOCLo8Tu-6VLykYXyl3Pkk/edit 66*635a8641SAndroid Build Coastguard Worker class ScopedTaskEnvironment { 67*635a8641SAndroid Build Coastguard Worker public: 68*635a8641SAndroid Build Coastguard Worker enum class MainThreadType { 69*635a8641SAndroid Build Coastguard Worker // The main thread doesn't pump system messages. 70*635a8641SAndroid Build Coastguard Worker DEFAULT, 71*635a8641SAndroid Build Coastguard Worker // The main thread doesn't pump system messages and uses a mock clock for 72*635a8641SAndroid Build Coastguard Worker // delayed tasks (controllable via FastForward*() methods). 73*635a8641SAndroid Build Coastguard Worker // TODO(gab): Make this the default |main_thread_type|. 74*635a8641SAndroid Build Coastguard Worker // TODO(gab): Also mock the TaskScheduler's clock simultaneously (this 75*635a8641SAndroid Build Coastguard Worker // currently only mocks the main thread's clock). 76*635a8641SAndroid Build Coastguard Worker MOCK_TIME, 77*635a8641SAndroid Build Coastguard Worker // The main thread pumps UI messages. 78*635a8641SAndroid Build Coastguard Worker UI, 79*635a8641SAndroid Build Coastguard Worker // The main thread pumps asynchronous IO messages and supports the 80*635a8641SAndroid Build Coastguard Worker // FileDescriptorWatcher API on POSIX. 81*635a8641SAndroid Build Coastguard Worker IO, 82*635a8641SAndroid Build Coastguard Worker }; 83*635a8641SAndroid Build Coastguard Worker 84*635a8641SAndroid Build Coastguard Worker enum class ExecutionMode { 85*635a8641SAndroid Build Coastguard Worker // Tasks are queued and only executed when RunUntilIdle() is explicitly 86*635a8641SAndroid Build Coastguard Worker // called. 87*635a8641SAndroid Build Coastguard Worker QUEUED, 88*635a8641SAndroid Build Coastguard Worker // Tasks run as they are posted. RunUntilIdle() can still be used to block 89*635a8641SAndroid Build Coastguard Worker // until done. 90*635a8641SAndroid Build Coastguard Worker ASYNC, 91*635a8641SAndroid Build Coastguard Worker }; 92*635a8641SAndroid Build Coastguard Worker 93*635a8641SAndroid Build Coastguard Worker ScopedTaskEnvironment( 94*635a8641SAndroid Build Coastguard Worker MainThreadType main_thread_type = MainThreadType::DEFAULT, 95*635a8641SAndroid Build Coastguard Worker ExecutionMode execution_control_mode = ExecutionMode::ASYNC); 96*635a8641SAndroid Build Coastguard Worker 97*635a8641SAndroid Build Coastguard Worker // Waits until no undelayed TaskScheduler tasks remain. Then, unregisters the 98*635a8641SAndroid Build Coastguard Worker // TaskScheduler and the (Thread|Sequenced)TaskRunnerHandle. 99*635a8641SAndroid Build Coastguard Worker ~ScopedTaskEnvironment(); 100*635a8641SAndroid Build Coastguard Worker 101*635a8641SAndroid Build Coastguard Worker // Returns a TaskRunner that schedules tasks on the main thread. 102*635a8641SAndroid Build Coastguard Worker scoped_refptr<base::SingleThreadTaskRunner> GetMainThreadTaskRunner(); 103*635a8641SAndroid Build Coastguard Worker 104*635a8641SAndroid Build Coastguard Worker // Returns whether the main thread's TaskRunner has pending tasks. 105*635a8641SAndroid Build Coastguard Worker bool MainThreadHasPendingTask() const; 106*635a8641SAndroid Build Coastguard Worker 107*635a8641SAndroid Build Coastguard Worker // Runs tasks until both the (Thread|Sequenced)TaskRunnerHandle and the 108*635a8641SAndroid Build Coastguard Worker // TaskScheduler's non-delayed queues are empty. 109*635a8641SAndroid Build Coastguard Worker void RunUntilIdle(); 110*635a8641SAndroid Build Coastguard Worker 111*635a8641SAndroid Build Coastguard Worker // Only valid for instances with a MOCK_TIME MainThreadType. Fast-forwards 112*635a8641SAndroid Build Coastguard Worker // virtual time by |delta|, causing all tasks on the main thread with a 113*635a8641SAndroid Build Coastguard Worker // remaining delay less than or equal to |delta| to be executed before this 114*635a8641SAndroid Build Coastguard Worker // returns. |delta| must be non-negative. 115*635a8641SAndroid Build Coastguard Worker // TODO(gab): Make this apply to TaskScheduler delayed tasks as well 116*635a8641SAndroid Build Coastguard Worker // (currently only main thread time is mocked). 117*635a8641SAndroid Build Coastguard Worker void FastForwardBy(TimeDelta delta); 118*635a8641SAndroid Build Coastguard Worker 119*635a8641SAndroid Build Coastguard Worker // Only valid for instances with a MOCK_TIME MainThreadType. 120*635a8641SAndroid Build Coastguard Worker // Short for FastForwardBy(TimeDelta::Max()). 121*635a8641SAndroid Build Coastguard Worker void FastForwardUntilNoTasksRemain(); 122*635a8641SAndroid Build Coastguard Worker 123*635a8641SAndroid Build Coastguard Worker // Only valid for instances with a MOCK_TIME MainThreadType. Returns a 124*635a8641SAndroid Build Coastguard Worker // TickClock whose time is updated by FastForward(By|UntilNoTasksRemain). 125*635a8641SAndroid Build Coastguard Worker const TickClock* GetMockTickClock(); 126*635a8641SAndroid Build Coastguard Worker std::unique_ptr<TickClock> DeprecatedGetMockTickClock(); 127*635a8641SAndroid Build Coastguard Worker 128*635a8641SAndroid Build Coastguard Worker // Only valid for instances with a MOCK_TIME MainThreadType. 129*635a8641SAndroid Build Coastguard Worker // Returns the number of pending tasks of the main thread's TaskRunner. 130*635a8641SAndroid Build Coastguard Worker size_t GetPendingMainThreadTaskCount() const; 131*635a8641SAndroid Build Coastguard Worker 132*635a8641SAndroid Build Coastguard Worker // Only valid for instances with a MOCK_TIME MainThreadType. 133*635a8641SAndroid Build Coastguard Worker // Returns the delay until the next delayed pending task of the main thread's 134*635a8641SAndroid Build Coastguard Worker // TaskRunner. 135*635a8641SAndroid Build Coastguard Worker TimeDelta NextMainThreadPendingTaskDelay() const; 136*635a8641SAndroid Build Coastguard Worker 137*635a8641SAndroid Build Coastguard Worker private: 138*635a8641SAndroid Build Coastguard Worker class TestTaskTracker; 139*635a8641SAndroid Build Coastguard Worker 140*635a8641SAndroid Build Coastguard Worker const ExecutionMode execution_control_mode_; 141*635a8641SAndroid Build Coastguard Worker 142*635a8641SAndroid Build Coastguard Worker // Exactly one of these will be non-null to provide the task environment on 143*635a8641SAndroid Build Coastguard Worker // the main thread. Users of this class should NOT rely on the presence of a 144*635a8641SAndroid Build Coastguard Worker // MessageLoop beyond (Thread|Sequenced)TaskRunnerHandle and RunLoop as 145*635a8641SAndroid Build Coastguard Worker // the backing implementation of each MainThreadType may change over time. 146*635a8641SAndroid Build Coastguard Worker const std::unique_ptr<MessageLoop> message_loop_; 147*635a8641SAndroid Build Coastguard Worker const scoped_refptr<TestMockTimeTaskRunner> mock_time_task_runner_; 148*635a8641SAndroid Build Coastguard Worker 149*635a8641SAndroid Build Coastguard Worker // Non-null in MOCK_TIME, where an explicit SequenceLocalStorageMap needs to 150*635a8641SAndroid Build Coastguard Worker // be provided. TODO(gab): This can be removed once mock time support is added 151*635a8641SAndroid Build Coastguard Worker // to MessageLoop directly. 152*635a8641SAndroid Build Coastguard Worker const std::unique_ptr<internal::SequenceLocalStorageMap> slsm_for_mock_time_; 153*635a8641SAndroid Build Coastguard Worker const std::unique_ptr< 154*635a8641SAndroid Build Coastguard Worker internal::ScopedSetSequenceLocalStorageMapForCurrentThread> 155*635a8641SAndroid Build Coastguard Worker slsm_registration_for_mock_time_; 156*635a8641SAndroid Build Coastguard Worker 157*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) 158*635a8641SAndroid Build Coastguard Worker // Enables the FileDescriptorWatcher API iff running a MainThreadType::IO. 159*635a8641SAndroid Build Coastguard Worker const std::unique_ptr<FileDescriptorWatcher> file_descriptor_watcher_; 160*635a8641SAndroid Build Coastguard Worker #endif 161*635a8641SAndroid Build Coastguard Worker 162*635a8641SAndroid Build Coastguard Worker const TaskScheduler* task_scheduler_ = nullptr; 163*635a8641SAndroid Build Coastguard Worker 164*635a8641SAndroid Build Coastguard Worker // Owned by |task_scheduler_|. 165*635a8641SAndroid Build Coastguard Worker TestTaskTracker* const task_tracker_; 166*635a8641SAndroid Build Coastguard Worker 167*635a8641SAndroid Build Coastguard Worker // Ensures destruction of lazy TaskRunners when this is destroyed. 168*635a8641SAndroid Build Coastguard Worker internal::ScopedLazyTaskRunnerListForTesting 169*635a8641SAndroid Build Coastguard Worker scoped_lazy_task_runner_list_for_testing_; 170*635a8641SAndroid Build Coastguard Worker 171*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(ScopedTaskEnvironment); 172*635a8641SAndroid Build Coastguard Worker }; 173*635a8641SAndroid Build Coastguard Worker 174*635a8641SAndroid Build Coastguard Worker } // namespace test 175*635a8641SAndroid Build Coastguard Worker } // namespace base 176*635a8641SAndroid Build Coastguard Worker 177*635a8641SAndroid Build Coastguard Worker #endif // BASE_TEST_SCOPED_ASYNC_TASK_SCHEDULER_H_ 178