mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-24 14:26:09 +03:00
178 lines
6.6 KiB
C
178 lines
6.6 KiB
C
|
// Copyright 2017 The Chromium Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style license that can be
|
||
|
// found in the LICENSE file.
|
||
|
|
||
|
#ifndef BASE_TEST_SCOPED_TASK_ENVIRONMENT_H_
|
||
|
#define BASE_TEST_SCOPED_TASK_ENVIRONMENT_H_
|
||
|
|
||
|
#include "base/macros.h"
|
||
|
#include "base/memory/ref_counted.h"
|
||
|
#include "base/single_thread_task_runner.h"
|
||
|
#include "base/task/lazy_task_runner.h"
|
||
|
#include "build/build_config.h"
|
||
|
|
||
|
namespace base {
|
||
|
|
||
|
namespace internal {
|
||
|
class ScopedSetSequenceLocalStorageMapForCurrentThread;
|
||
|
class SequenceLocalStorageMap;
|
||
|
} // namespace internal
|
||
|
|
||
|
class FileDescriptorWatcher;
|
||
|
class MessageLoop;
|
||
|
class TaskScheduler;
|
||
|
class TestMockTimeTaskRunner;
|
||
|
class TickClock;
|
||
|
|
||
|
namespace test {
|
||
|
|
||
|
// ScopedTaskEnvironment allows usage of these APIs within its scope:
|
||
|
// - (Thread|Sequenced)TaskRunnerHandle, on the thread where it lives
|
||
|
// - base/task/post_task.h, on any thread
|
||
|
//
|
||
|
// Tests that need either of these APIs should instantiate a
|
||
|
// ScopedTaskEnvironment.
|
||
|
//
|
||
|
// Tasks posted to the (Thread|Sequenced)TaskRunnerHandle run synchronously when
|
||
|
// RunLoop::Run(UntilIdle) or ScopedTaskEnvironment::RunUntilIdle is called on
|
||
|
// the thread where the ScopedTaskEnvironment lives.
|
||
|
//
|
||
|
// Tasks posted through base/task/post_task.h run on dedicated threads. If
|
||
|
// ExecutionMode is QUEUED, they run when RunUntilIdle() or
|
||
|
// ~ScopedTaskEnvironment is called. If ExecutionMode is ASYNC, they run as they
|
||
|
// are posted.
|
||
|
//
|
||
|
// All methods of ScopedTaskEnvironment must be called from the same thread.
|
||
|
//
|
||
|
// Usage:
|
||
|
//
|
||
|
// class MyTestFixture : public testing::Test {
|
||
|
// public:
|
||
|
// (...)
|
||
|
//
|
||
|
// protected:
|
||
|
// // Must be the first member (or at least before any member that cares
|
||
|
// // about tasks) to be initialized first and destroyed last. protected
|
||
|
// // instead of private visibility will allow controlling the task
|
||
|
// // environment (e.g. clock) once such features are added (see design doc
|
||
|
// // below for details), until then it at least doesn't hurt :).
|
||
|
// base::test::ScopedTaskEnvironment scoped_task_environment_;
|
||
|
//
|
||
|
// // Other members go here (or further below in private section.)
|
||
|
// };
|
||
|
//
|
||
|
// Design and future improvements documented in
|
||
|
// https://docs.google.com/document/d/1QabRo8c7D9LsYY3cEcaPQbOCLo8Tu-6VLykYXyl3Pkk/edit
|
||
|
class ScopedTaskEnvironment {
|
||
|
public:
|
||
|
enum class MainThreadType {
|
||
|
// The main thread doesn't pump system messages.
|
||
|
DEFAULT,
|
||
|
// The main thread doesn't pump system messages and uses a mock clock for
|
||
|
// delayed tasks (controllable via FastForward*() methods).
|
||
|
// TODO(gab): Make this the default |main_thread_type|.
|
||
|
// TODO(gab): Also mock the TaskScheduler's clock simultaneously (this
|
||
|
// currently only mocks the main thread's clock).
|
||
|
MOCK_TIME,
|
||
|
// The main thread pumps UI messages.
|
||
|
UI,
|
||
|
// The main thread pumps asynchronous IO messages and supports the
|
||
|
// FileDescriptorWatcher API on POSIX.
|
||
|
IO,
|
||
|
};
|
||
|
|
||
|
enum class ExecutionMode {
|
||
|
// Tasks are queued and only executed when RunUntilIdle() is explicitly
|
||
|
// called.
|
||
|
QUEUED,
|
||
|
// Tasks run as they are posted. RunUntilIdle() can still be used to block
|
||
|
// until done.
|
||
|
ASYNC,
|
||
|
};
|
||
|
|
||
|
ScopedTaskEnvironment(
|
||
|
MainThreadType main_thread_type = MainThreadType::DEFAULT,
|
||
|
ExecutionMode execution_control_mode = ExecutionMode::ASYNC);
|
||
|
|
||
|
// Waits until no undelayed TaskScheduler tasks remain. Then, unregisters the
|
||
|
// TaskScheduler and the (Thread|Sequenced)TaskRunnerHandle.
|
||
|
~ScopedTaskEnvironment();
|
||
|
|
||
|
// Returns a TaskRunner that schedules tasks on the main thread.
|
||
|
scoped_refptr<base::SingleThreadTaskRunner> GetMainThreadTaskRunner();
|
||
|
|
||
|
// Returns whether the main thread's TaskRunner has pending tasks.
|
||
|
bool MainThreadHasPendingTask() const;
|
||
|
|
||
|
// Runs tasks until both the (Thread|Sequenced)TaskRunnerHandle and the
|
||
|
// TaskScheduler's non-delayed queues are empty.
|
||
|
void RunUntilIdle();
|
||
|
|
||
|
// Only valid for instances with a MOCK_TIME MainThreadType. Fast-forwards
|
||
|
// virtual time by |delta|, causing all tasks on the main thread with a
|
||
|
// remaining delay less than or equal to |delta| to be executed before this
|
||
|
// returns. |delta| must be non-negative.
|
||
|
// TODO(gab): Make this apply to TaskScheduler delayed tasks as well
|
||
|
// (currently only main thread time is mocked).
|
||
|
void FastForwardBy(TimeDelta delta);
|
||
|
|
||
|
// Only valid for instances with a MOCK_TIME MainThreadType.
|
||
|
// Short for FastForwardBy(TimeDelta::Max()).
|
||
|
void FastForwardUntilNoTasksRemain();
|
||
|
|
||
|
// Only valid for instances with a MOCK_TIME MainThreadType. Returns a
|
||
|
// TickClock whose time is updated by FastForward(By|UntilNoTasksRemain).
|
||
|
const TickClock* GetMockTickClock();
|
||
|
std::unique_ptr<TickClock> DeprecatedGetMockTickClock();
|
||
|
|
||
|
// Only valid for instances with a MOCK_TIME MainThreadType.
|
||
|
// Returns the number of pending tasks of the main thread's TaskRunner.
|
||
|
size_t GetPendingMainThreadTaskCount() const;
|
||
|
|
||
|
// Only valid for instances with a MOCK_TIME MainThreadType.
|
||
|
// Returns the delay until the next delayed pending task of the main thread's
|
||
|
// TaskRunner.
|
||
|
TimeDelta NextMainThreadPendingTaskDelay() const;
|
||
|
|
||
|
private:
|
||
|
class TestTaskTracker;
|
||
|
|
||
|
const ExecutionMode execution_control_mode_;
|
||
|
|
||
|
// Exactly one of these will be non-null to provide the task environment on
|
||
|
// the main thread. Users of this class should NOT rely on the presence of a
|
||
|
// MessageLoop beyond (Thread|Sequenced)TaskRunnerHandle and RunLoop as
|
||
|
// the backing implementation of each MainThreadType may change over time.
|
||
|
const std::unique_ptr<MessageLoop> message_loop_;
|
||
|
const scoped_refptr<TestMockTimeTaskRunner> mock_time_task_runner_;
|
||
|
|
||
|
// Non-null in MOCK_TIME, where an explicit SequenceLocalStorageMap needs to
|
||
|
// be provided. TODO(gab): This can be removed once mock time support is added
|
||
|
// to MessageLoop directly.
|
||
|
const std::unique_ptr<internal::SequenceLocalStorageMap> slsm_for_mock_time_;
|
||
|
const std::unique_ptr<
|
||
|
internal::ScopedSetSequenceLocalStorageMapForCurrentThread>
|
||
|
slsm_registration_for_mock_time_;
|
||
|
|
||
|
#if defined(OS_POSIX)
|
||
|
// Enables the FileDescriptorWatcher API iff running a MainThreadType::IO.
|
||
|
const std::unique_ptr<FileDescriptorWatcher> file_descriptor_watcher_;
|
||
|
#endif
|
||
|
|
||
|
const TaskScheduler* task_scheduler_ = nullptr;
|
||
|
|
||
|
// Owned by |task_scheduler_|.
|
||
|
TestTaskTracker* const task_tracker_;
|
||
|
|
||
|
// Ensures destruction of lazy TaskRunners when this is destroyed.
|
||
|
internal::ScopedLazyTaskRunnerListForTesting
|
||
|
scoped_lazy_task_runner_list_for_testing_;
|
||
|
|
||
|
DISALLOW_COPY_AND_ASSIGN(ScopedTaskEnvironment);
|
||
|
};
|
||
|
|
||
|
} // namespace test
|
||
|
} // namespace base
|
||
|
|
||
|
#endif // BASE_TEST_SCOPED_ASYNC_TASK_SCHEDULER_H_
|