Commit d1317fc3 authored by Alex Clarke's avatar Alex Clarke Committed by Commit Bot

[Reland #3] Use the SequenceManager in ScopedTaskEnvironment

A reland of https://crrev.com/c/1324391

This is necessary because we want content::TestBrowserThreadBundle to
own a BrowserUIThreadScheduler, but that also owns a ScopedTaskEnvironment
and you can't have two SequenceManagers on the same thread.

This patch allows ScopedTaskEnvironment to optionally work with an
externally owned SequenceManager solving the problem.

This implements https://docs.google.com/document/d/1y08C6JQ9Yta3EQXzwIqqIIKHq9500WV6CWFZzZfDx7I/edit?usp=drivesdk,

We now have the ability to mock time on the UI and IO threads.

RE HttpServiceTest change HttpServiceTest.MultipleRequests was failing
mysteriously on fuschia on the bots only (not locally). IO_MOCK_TIME seems
to have fixed this.


TBR=gab@chromium.org,fdoray@chromium.org,wez@chromium.org

Bug: 863341, 891670, 708584
Change-Id: I95444a0a50f8b577c5fae62c12c8423c7e8f21d6
Reviewed-on: https://chromium-review.googlesource.com/c/1361863
Commit-Queue: Alex Clarke <alexclarke@chromium.org>
Reviewed-by: default avatarAlex Clarke <alexclarke@chromium.org>
Reviewed-by: default avatarSami Kyöstilä <skyostil@chromium.org>
Cr-Commit-Position: refs/heads/master@{#615496}
parent f326f2b3
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
#include "base/synchronization/condition_variable.h" #include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "base/task/sequence_manager/sequence_manager_impl.h"
#include "base/task/sequence_manager/time_domain.h"
#include "base/task/task_scheduler/task_scheduler.h" #include "base/task/task_scheduler/task_scheduler.h"
#include "base/task/task_scheduler/task_scheduler_impl.h" #include "base/task/task_scheduler/task_scheduler_impl.h"
#include "base/test/test_mock_time_task_runner.h" #include "base/test/test_mock_time_task_runner.h"
...@@ -36,20 +38,35 @@ namespace { ...@@ -36,20 +38,35 @@ namespace {
LazyInstance<ThreadLocalPointer<ScopedTaskEnvironment::LifetimeObserver>>::Leaky LazyInstance<ThreadLocalPointer<ScopedTaskEnvironment::LifetimeObserver>>::Leaky
environment_lifetime_observer; environment_lifetime_observer;
std::unique_ptr<MessageLoop> CreateMessageLoopForMainThreadType( base::Optional<MessageLoop::Type> GetMessageLoopTypeForMainThreadType(
ScopedTaskEnvironment::MainThreadType main_thread_type) { ScopedTaskEnvironment::MainThreadType main_thread_type) {
switch (main_thread_type) { switch (main_thread_type) {
case ScopedTaskEnvironment::MainThreadType::DEFAULT: case ScopedTaskEnvironment::MainThreadType::DEFAULT:
return std::make_unique<MessageLoop>(MessageLoop::TYPE_DEFAULT);
case ScopedTaskEnvironment::MainThreadType::MOCK_TIME: case ScopedTaskEnvironment::MainThreadType::MOCK_TIME:
return nullptr; return MessageLoop::TYPE_DEFAULT;
case ScopedTaskEnvironment::MainThreadType::UI: case ScopedTaskEnvironment::MainThreadType::UI:
return std::make_unique<MessageLoop>(MessageLoop::TYPE_UI); case ScopedTaskEnvironment::MainThreadType::UI_MOCK_TIME:
return MessageLoop::TYPE_UI;
case ScopedTaskEnvironment::MainThreadType::IO: case ScopedTaskEnvironment::MainThreadType::IO:
return std::make_unique<MessageLoop>(MessageLoop::TYPE_IO); case ScopedTaskEnvironment::MainThreadType::IO_MOCK_TIME:
return MessageLoop::TYPE_IO;
} }
NOTREACHED(); NOTREACHED();
return nullptr; return base::nullopt;
}
std::unique_ptr<sequence_manager::SequenceManager>
CreateSequenceManagerForMainThreadType(
ScopedTaskEnvironment::MainThreadType main_thread_type) {
auto type = GetMessageLoopTypeForMainThreadType(main_thread_type);
if (!type) {
return nullptr;
} else {
auto settings = base::sequence_manager::SequenceManager::Settings{
.message_loop_type = *type};
return sequence_manager::CreateSequenceManagerOnCurrentThreadWithPump(
MessageLoop::CreateMessagePumpForType(*type), std::move(settings));
}
} }
class TickClockBasedClock : public Clock { class TickClockBasedClock : public Clock {
...@@ -71,6 +88,135 @@ class TickClockBasedClock : public Clock { ...@@ -71,6 +88,135 @@ class TickClockBasedClock : public Clock {
} // namespace } // namespace
class ScopedTaskEnvironment::MockTimeDomain
: public sequence_manager::TimeDomain,
public TickClock {
public:
MockTimeDomain() = default;
~MockTimeDomain() override = default;
using TimeDomain::NextScheduledRunTime;
static std::unique_ptr<ScopedTaskEnvironment::MockTimeDomain> Create(
ScopedTaskEnvironment::MainThreadType main_thread_type) {
if (main_thread_type == MainThreadType::MOCK_TIME ||
main_thread_type == MainThreadType::UI_MOCK_TIME ||
main_thread_type == MainThreadType::IO_MOCK_TIME) {
return std::make_unique<ScopedTaskEnvironment::MockTimeDomain>();
}
return nullptr;
}
// sequence_manager::TimeDomain:
sequence_manager::LazyNow CreateLazyNow() const override {
base::AutoLock lock(now_ticks_lock_);
return sequence_manager::LazyNow(now_ticks_);
}
TimeTicks Now() const override {
// This can be called from any thread.
base::AutoLock lock(now_ticks_lock_);
return now_ticks_;
}
Optional<TimeDelta> DelayTillNextTask(
sequence_manager::LazyNow* lazy_now) override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Make sure TimeDomain::NextScheduledRunTime has taken canceled tasks into
// account, ReclaimMemory sweeps canceled delayed tasks.
sequence_manager()->ReclaimMemory();
Optional<TimeTicks> run_time = NextScheduledRunTime();
// Check if we've run out of tasks.
if (!run_time)
return base::nullopt;
// Check if we have a task that should be running now.
if (run_time <= now_ticks_)
return base::TimeDelta();
// The next task is a future delayed task. Since we're using mock time, we
// don't want an actual OS level delayed wake up scheduled, so pretend we
// have no more work. This will result in MaybeFastForwardToNextTask getting
// called which lets us advance |now_ticks_|.
return base::nullopt;
}
// This method is called when the underlying message pump has run out of
// non-delayed work.
bool MaybeFastForwardToNextTask(bool quit_when_idle_requested) override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// If we're being externally controlled by a RunLoop in client code, check
// if the RunLoop is due to quit when idle, if so we don't want to advance
// mock time.
if (stop_when_message_pump_is_idle_ && quit_when_idle_requested)
return false;
// We don't need to call ReclaimMemory here because
// DelayTillNextTask will have dealt with cancelled delayed tasks for us.
Optional<TimeTicks> run_time = NextScheduledRunTime();
if (!run_time) {
// We've run out of tasks, but ScopedTaskEnvironment::FastForwardBy
// requires the virtual time to be consumed.
if (now_ticks_ < allow_advance_until_ && !allow_advance_until_.is_max())
SetTime(allow_advance_until_);
return false;
}
// Don't advance past |allow_advance_until_|.
DCHECK_GT(*run_time, now_ticks_);
TimeTicks time_to_advance_to = std::min(allow_advance_until_, *run_time);
if (time_to_advance_to <= now_ticks_)
return false;
SetTime(time_to_advance_to);
// Make sure a DoWork is scheduled.
return true;
}
const char* GetName() const override { return "MockTimeDomain"; }
// TickClock implementation:
TimeTicks NowTicks() const override { return Now(); }
// Allows time to advance when reaching idle, until
// |now_ticks_ == advance_until|. No-op if |advance_until <= now_ticks_|.
// Doesn't schedule work by itself.
void SetAllowTimeToAutoAdvanceUntil(TimeTicks advance_until) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
allow_advance_until_ = advance_until;
}
void SetStopWhenMessagePumpIsIdle(bool stop_when_message_pump_is_idle) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
stop_when_message_pump_is_idle_ = stop_when_message_pump_is_idle;
}
private:
void SetTime(TimeTicks time) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_LE(time, allow_advance_until_);
base::AutoLock lock(now_ticks_lock_);
now_ticks_ = time;
}
SEQUENCE_CHECKER(sequence_checker_);
// By default we want RunLoop.Run() to advance virtual time due to the API
// contract.
TimeTicks allow_advance_until_ = TimeTicks::Max();
bool stop_when_message_pump_is_idle_ = true;
// Protects |now_ticks_|
mutable Lock now_ticks_lock_;
// Only ever written to from the main sequence.
TimeTicks now_ticks_;
};
class ScopedTaskEnvironment::TestTaskTracker class ScopedTaskEnvironment::TestTaskTracker
: public internal::TaskSchedulerImpl::TaskTrackerImpl { : public internal::TaskSchedulerImpl::TaskTrackerImpl {
public: public:
...@@ -117,33 +263,42 @@ class ScopedTaskEnvironment::TestTaskTracker ...@@ -117,33 +263,42 @@ class ScopedTaskEnvironment::TestTaskTracker
}; };
ScopedTaskEnvironment::ScopedTaskEnvironment( ScopedTaskEnvironment::ScopedTaskEnvironment(
MainThreadType main_thread_type,
ExecutionMode execution_control_mode)
: ScopedTaskEnvironment(
CreateSequenceManagerForMainThreadType(main_thread_type),
nullptr,
main_thread_type,
execution_control_mode) {}
ScopedTaskEnvironment::ScopedTaskEnvironment(
sequence_manager::SequenceManager* sequence_manager,
MainThreadType main_thread_type,
ExecutionMode execution_control_mode)
: ScopedTaskEnvironment(nullptr,
sequence_manager,
main_thread_type,
execution_control_mode) {}
ScopedTaskEnvironment::ScopedTaskEnvironment(
std::unique_ptr<sequence_manager::SequenceManager> owned_sequence_manager,
sequence_manager::SequenceManager* sequence_manager,
MainThreadType main_thread_type, MainThreadType main_thread_type,
ExecutionMode execution_control_mode) ExecutionMode execution_control_mode)
: execution_control_mode_(execution_control_mode), : execution_control_mode_(execution_control_mode),
message_loop_(CreateMessageLoopForMainThreadType(main_thread_type)), mock_time_domain_(MockTimeDomain::Create(main_thread_type)),
mock_time_task_runner_( owned_sequence_manager_(std::move(owned_sequence_manager)),
main_thread_type == MainThreadType::MOCK_TIME sequence_manager_(owned_sequence_manager_.get()
? MakeRefCounted<TestMockTimeTaskRunner>( ? owned_sequence_manager_.get()
TestMockTimeTaskRunner::Type::kBoundToThread) : sequence_manager),
: nullptr), task_queue_(CreateDefaultTaskQueue()),
slsm_for_mock_time_( mock_clock_(mock_time_domain_ ? std::make_unique<TickClockBasedClock>(
main_thread_type == MainThreadType::MOCK_TIME mock_time_domain_.get())
? std::make_unique<internal::SequenceLocalStorageMap>() : nullptr),
: nullptr),
slsm_registration_for_mock_time_(
main_thread_type == MainThreadType::MOCK_TIME
? std::make_unique<
internal::ScopedSetSequenceLocalStorageMapForCurrentThread>(
slsm_for_mock_time_.get())
: nullptr),
mock_clock_(mock_time_task_runner_
? std::make_unique<TickClockBasedClock>(
mock_time_task_runner_->GetMockTickClock())
: nullptr),
#if defined(OS_POSIX) || defined(OS_FUCHSIA) #if defined(OS_POSIX) || defined(OS_FUCHSIA)
file_descriptor_watcher_(main_thread_type == MainThreadType::IO file_descriptor_watcher_(main_thread_type == MainThreadType::IO
? std::make_unique<FileDescriptorWatcher>( ? std::make_unique<FileDescriptorWatcher>(
message_loop_->task_runner()) task_queue_->task_runner())
: nullptr), : nullptr),
#endif // defined(OS_POSIX) || defined(OS_FUCHSIA) #endif // defined(OS_POSIX) || defined(OS_FUCHSIA)
task_tracker_(new TestTaskTracker()) { task_tracker_(new TestTaskTracker()) {
...@@ -154,6 +309,8 @@ ScopedTaskEnvironment::ScopedTaskEnvironment( ...@@ -154,6 +309,8 @@ ScopedTaskEnvironment::ScopedTaskEnvironment(
"someone has explicitly disabled it with " "someone has explicitly disabled it with "
"DisableCheckForLeakedGlobals()."; "DisableCheckForLeakedGlobals().";
sequence_manager_->SetDefaultTaskRunner(task_queue_->task_runner());
// Instantiate a TaskScheduler with 2 threads in each of its 4 pools. Threads // Instantiate a TaskScheduler with 2 threads in each of its 4 pools. Threads
// stay alive even when they don't have work. // stay alive even when they don't have work.
// Each pool uses two threads to prevent deadlocks in unit tests that have a // Each pool uses two threads to prevent deadlocks in unit tests that have a
...@@ -220,6 +377,20 @@ ScopedTaskEnvironment::~ScopedTaskEnvironment() { ...@@ -220,6 +377,20 @@ ScopedTaskEnvironment::~ScopedTaskEnvironment() {
LifetimeObserver* observer = environment_lifetime_observer.Get().Get(); LifetimeObserver* observer = environment_lifetime_observer.Get().Get();
if (observer) if (observer)
observer->OnScopedTaskEnvironmentDestroyed(); observer->OnScopedTaskEnvironmentDestroyed();
task_queue_ = nullptr;
if (mock_time_domain_)
sequence_manager_->UnregisterTimeDomain(mock_time_domain_.get());
}
scoped_refptr<sequence_manager::TaskQueue>
ScopedTaskEnvironment::CreateDefaultTaskQueue() {
if (mock_time_domain_)
sequence_manager_->RegisterTimeDomain(mock_time_domain_.get());
return sequence_manager_->CreateTaskQueue(
sequence_manager::TaskQueue::Spec("scoped_task_environment_default")
.SetTimeDomain(mock_time_domain_.get()));
} }
void ScopedTaskEnvironment::SetLifetimeObserver( void ScopedTaskEnvironment::SetLifetimeObserver(
...@@ -230,20 +401,29 @@ void ScopedTaskEnvironment::SetLifetimeObserver( ...@@ -230,20 +401,29 @@ void ScopedTaskEnvironment::SetLifetimeObserver(
scoped_refptr<base::SingleThreadTaskRunner> scoped_refptr<base::SingleThreadTaskRunner>
ScopedTaskEnvironment::GetMainThreadTaskRunner() { ScopedTaskEnvironment::GetMainThreadTaskRunner() {
if (message_loop_) return task_queue_->task_runner();
return message_loop_->task_runner();
DCHECK(mock_time_task_runner_);
return mock_time_task_runner_;
} }
bool ScopedTaskEnvironment::MainThreadHasPendingTask() const { bool ScopedTaskEnvironment::MainThreadHasPendingTask() const {
if (message_loop_) sequence_manager::internal::SequenceManagerImpl* sequence_manager_impl =
return !message_loop_->IsIdleForTesting(); static_cast<sequence_manager::internal::SequenceManagerImpl*>(
DCHECK(mock_time_task_runner_); sequence_manager_);
return mock_time_task_runner_->HasPendingTask(); // ReclaimMemory sweeps canceled delayed tasks.
sequence_manager_impl->ReclaimMemory();
// Unfortunately this API means different things depending on whether mock
// time is used or not. If MockTime is used then tests want to know if there
// are any delayed or non-delayed tasks, otherwise only non-delayed tasks are
// considered.
if (mock_time_domain_)
return sequence_manager_impl->HasTasks();
return !sequence_manager_impl->IsIdleForTesting();
} }
void ScopedTaskEnvironment::RunUntilIdle() { void ScopedTaskEnvironment::RunUntilIdle() {
// Prevent virtual time from advancing while within this call.
if (mock_time_domain_)
mock_time_domain_->SetAllowTimeToAutoAdvanceUntil(TimeTicks());
// TODO(gab): This can be heavily simplified to essentially: // TODO(gab): This can be heavily simplified to essentially:
// bool HasMainThreadTasks() { // bool HasMainThreadTasks() {
// if (message_loop_) // if (message_loop_)
...@@ -321,31 +501,36 @@ void ScopedTaskEnvironment::RunUntilIdle() { ...@@ -321,31 +501,36 @@ void ScopedTaskEnvironment::RunUntilIdle() {
// parallel execution before returning unless in ExecutionMode::QUEUED. // parallel execution before returning unless in ExecutionMode::QUEUED.
if (execution_control_mode_ != ExecutionMode::QUEUED) if (execution_control_mode_ != ExecutionMode::QUEUED)
task_tracker_->AllowRunTasks(); task_tracker_->AllowRunTasks();
if (mock_time_domain_)
mock_time_domain_->SetAllowTimeToAutoAdvanceUntil(TimeTicks::Max());
} }
void ScopedTaskEnvironment::FastForwardBy(TimeDelta delta) { void ScopedTaskEnvironment::FastForwardBy(TimeDelta delta) {
DCHECK(mock_time_task_runner_); MessageLoopCurrent::ScopedNestableTaskAllower allow;
mock_time_task_runner_->FastForwardBy(delta); DCHECK(mock_time_domain_);
mock_time_domain_->SetStopWhenMessagePumpIsIdle(false);
mock_time_domain_->SetAllowTimeToAutoAdvanceUntil(mock_time_domain_->Now() +
delta);
RunLoop().RunUntilIdle();
mock_time_domain_->SetStopWhenMessagePumpIsIdle(true);
mock_time_domain_->SetAllowTimeToAutoAdvanceUntil(TimeTicks::Max());
} }
void ScopedTaskEnvironment::FastForwardUntilNoTasksRemain() { void ScopedTaskEnvironment::FastForwardUntilNoTasksRemain() {
DCHECK(mock_time_task_runner_); // TimeTicks::operator+(TimeDelta) uses saturated arithmetic so it's safe to
mock_time_task_runner_->FastForwardUntilNoTasksRemain(); // pass in TimeDelta::Max().
FastForwardBy(TimeDelta::Max());
} }
const TickClock* ScopedTaskEnvironment::GetMockTickClock() const { const TickClock* ScopedTaskEnvironment::GetMockTickClock() const {
DCHECK(mock_time_task_runner_); DCHECK(mock_time_domain_);
return mock_time_task_runner_->GetMockTickClock(); return mock_time_domain_.get();
}
std::unique_ptr<TickClock> ScopedTaskEnvironment::DeprecatedGetMockTickClock() {
DCHECK(mock_time_task_runner_);
return mock_time_task_runner_->DeprecatedGetMockTickClock();
} }
base::TimeTicks ScopedTaskEnvironment::NowTicks() const { base::TimeTicks ScopedTaskEnvironment::NowTicks() const {
DCHECK(mock_time_task_runner_); DCHECK(mock_time_domain_);
return mock_time_task_runner_->NowTicks(); return mock_time_domain_->Now();
} }
const Clock* ScopedTaskEnvironment::GetMockClock() const { const Clock* ScopedTaskEnvironment::GetMockClock() const {
...@@ -354,13 +539,19 @@ const Clock* ScopedTaskEnvironment::GetMockClock() const { ...@@ -354,13 +539,19 @@ const Clock* ScopedTaskEnvironment::GetMockClock() const {
} }
size_t ScopedTaskEnvironment::GetPendingMainThreadTaskCount() const { size_t ScopedTaskEnvironment::GetPendingMainThreadTaskCount() const {
DCHECK(mock_time_task_runner_); // ReclaimMemory sweeps canceled delayed tasks.
return mock_time_task_runner_->GetPendingTaskCount(); sequence_manager_->ReclaimMemory();
return sequence_manager_->GetPendingTaskCountForTesting();
} }
TimeDelta ScopedTaskEnvironment::NextMainThreadPendingTaskDelay() const { TimeDelta ScopedTaskEnvironment::NextMainThreadPendingTaskDelay() const {
DCHECK(mock_time_task_runner_); // ReclaimMemory sweeps canceled delayed tasks.
return mock_time_task_runner_->NextPendingTaskDelay(); sequence_manager_->ReclaimMemory();
DCHECK(mock_time_domain_);
Optional<TimeTicks> run_time = mock_time_domain_->NextScheduledRunTime();
if (run_time)
return *run_time - mock_time_domain_->Now();
return TimeDelta::Max();
} }
ScopedTaskEnvironment::TestTaskTracker::TestTaskTracker() ScopedTaskEnvironment::TestTaskTracker::TestTaskTracker()
......
...@@ -9,21 +9,16 @@ ...@@ -9,21 +9,16 @@
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "base/task/lazy_task_runner.h" #include "base/task/lazy_task_runner.h"
#include "base/task/sequence_manager/sequence_manager.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "build/build_config.h" #include "build/build_config.h"
namespace base { namespace base {
namespace internal {
class ScopedSetSequenceLocalStorageMapForCurrentThread;
class SequenceLocalStorageMap;
} // namespace internal
class Clock; class Clock;
class FileDescriptorWatcher; class FileDescriptorWatcher;
class MessageLoop;
class TaskScheduler; class TaskScheduler;
class TestMockTimeTaskRunner;
class TickClock; class TickClock;
namespace test { namespace test {
...@@ -78,9 +73,18 @@ class ScopedTaskEnvironment { ...@@ -78,9 +73,18 @@ class ScopedTaskEnvironment {
MOCK_TIME, MOCK_TIME,
// The main thread pumps UI messages. // The main thread pumps UI messages.
UI, UI,
// The main thread pumps UI messages and uses a mock clock for delayed tasks
// (controllable via FastForward*() methods).
// TODO(gab@): Enable mock time on all threads and make MOCK_TIME
// configurable independent of MainThreadType.
UI_MOCK_TIME,
// The main thread pumps asynchronous IO messages and supports the // The main thread pumps asynchronous IO messages and supports the
// FileDescriptorWatcher API on POSIX. // FileDescriptorWatcher API on POSIX.
IO, IO,
// The main thread pumps IO messages and uses a mock clock for delayed tasks
// (controllable via FastForward*() methods). In addition it supports the
// FileDescriptorWatcher API on POSIX.
IO_MOCK_TIME,
}; };
enum class ExecutionMode { enum class ExecutionMode {
...@@ -96,6 +100,13 @@ class ScopedTaskEnvironment { ...@@ -96,6 +100,13 @@ class ScopedTaskEnvironment {
MainThreadType main_thread_type = MainThreadType::DEFAULT, MainThreadType main_thread_type = MainThreadType::DEFAULT,
ExecutionMode execution_control_mode = ExecutionMode::ASYNC); ExecutionMode execution_control_mode = ExecutionMode::ASYNC);
// Constructs a ScopedTaskEnvironment using a preexisting |sequence_manager|.
// |sequence_manager| must outlive this ScopedTaskEnvironment.
ScopedTaskEnvironment(
sequence_manager::SequenceManager* sequence_manager,
MainThreadType main_thread_type = MainThreadType::DEFAULT,
ExecutionMode execution_control_mode = ExecutionMode::ASYNC);
// Waits until no undelayed TaskScheduler tasks remain. Then, unregisters the // Waits until no undelayed TaskScheduler tasks remain. Then, unregisters the
// TaskScheduler and the (Thread|Sequenced)TaskRunnerHandle. // TaskScheduler and the (Thread|Sequenced)TaskRunnerHandle.
~ScopedTaskEnvironment(); ~ScopedTaskEnvironment();
...@@ -165,24 +176,25 @@ class ScopedTaskEnvironment { ...@@ -165,24 +176,25 @@ class ScopedTaskEnvironment {
TimeDelta NextMainThreadPendingTaskDelay() const; TimeDelta NextMainThreadPendingTaskDelay() const;
private: private:
class MockTimeDomain;
class TestTaskTracker; class TestTaskTracker;
ScopedTaskEnvironment(
std::unique_ptr<sequence_manager::SequenceManager> owned_sequence_manager,
sequence_manager::SequenceManager* sequence_manager,
MainThreadType main_thread_type,
ExecutionMode execution_control_mode);
scoped_refptr<sequence_manager::TaskQueue> CreateDefaultTaskQueue();
const ExecutionMode execution_control_mode_; const ExecutionMode execution_control_mode_;
// Exactly one of these will be non-null to provide the task environment on const std::unique_ptr<MockTimeDomain> mock_time_domain_;
// the main thread. Users of this class should NOT rely on the presence of a const std::unique_ptr<sequence_manager::SequenceManager>
// MessageLoop beyond (Thread|Sequenced)TaskRunnerHandle and RunLoop as owned_sequence_manager_;
// the backing implementation of each MainThreadType may change over time. sequence_manager::SequenceManager* const sequence_manager_;
const std::unique_ptr<MessageLoop> message_loop_;
const scoped_refptr<TestMockTimeTaskRunner> mock_time_task_runner_; scoped_refptr<sequence_manager::TaskQueue> task_queue_;
// 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_;
// Only set for instances with a MOCK_TIME MainThreadType. // Only set for instances with a MOCK_TIME MainThreadType.
const std::unique_ptr<Clock> mock_clock_; const std::unique_ptr<Clock> mock_clock_;
......
...@@ -372,6 +372,10 @@ INSTANTIATE_TEST_CASE_P( ...@@ -372,6 +372,10 @@ INSTANTIATE_TEST_CASE_P(
MainThreadMockTime, MainThreadMockTime,
ScopedTaskEnvironmentTest, ScopedTaskEnvironmentTest,
::testing::Values(ScopedTaskEnvironment::MainThreadType::MOCK_TIME)); ::testing::Values(ScopedTaskEnvironment::MainThreadType::MOCK_TIME));
INSTANTIATE_TEST_CASE_P(
MainThreadUiMockTime,
ScopedTaskEnvironmentTest,
::testing::Values(ScopedTaskEnvironment::MainThreadType::UI_MOCK_TIME));
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
MainThreadUI, MainThreadUI,
ScopedTaskEnvironmentTest, ScopedTaskEnvironmentTest,
...@@ -587,6 +591,10 @@ INSTANTIATE_TEST_CASE_P( ...@@ -587,6 +591,10 @@ INSTANTIATE_TEST_CASE_P(
MainThreadMockTime, MainThreadMockTime,
ScopedTaskEnvironmentMockedTime, ScopedTaskEnvironmentMockedTime,
::testing::Values(ScopedTaskEnvironment::MainThreadType::MOCK_TIME)); ::testing::Values(ScopedTaskEnvironment::MainThreadType::MOCK_TIME));
INSTANTIATE_TEST_CASE_P(
MainThreadUiMockTime,
ScopedTaskEnvironmentMockedTime,
::testing::Values(ScopedTaskEnvironment::MainThreadType::UI_MOCK_TIME));
} // namespace test } // namespace test
} // namespace base } // namespace base
...@@ -35,7 +35,7 @@ class HttpServiceTest : public ::testing::Test { ...@@ -35,7 +35,7 @@ class HttpServiceTest : public ::testing::Test {
public: public:
HttpServiceTest() HttpServiceTest()
: task_environment_( : task_environment_(
base::test::ScopedTaskEnvironment::MainThreadType::IO), base::test::ScopedTaskEnvironment::MainThreadType::IO_MOCK_TIME),
binding_(&http_service_server_) { binding_(&http_service_server_) {
// Initialize the test server. // Initialize the test server.
test_server_.AddDefaultHandlers( test_server_.AddDefaultHandlers(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment