Commit e3486063 authored by Sebastien Marchand's avatar Sebastien Marchand Committed by Commit Bot

Expose a TickClock on ScopedTaskEnvironment

Bug: 806265
Change-Id: I4820b88096de01aa134715ebbe6cb1556d91b4ec
Reviewed-on: https://chromium-review.googlesource.com/888094Reviewed-by: default avatarGabriel Charette <gab@chromium.org>
Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Commit-Queue: Sébastien Marchand <sebmarchand@chromium.org>
Cr-Commit-Position: refs/heads/master@{#534072}
parent a7892a1d
...@@ -232,6 +232,11 @@ void ScopedTaskEnvironment::FastForwardUntilNoTasksRemain() { ...@@ -232,6 +232,11 @@ void ScopedTaskEnvironment::FastForwardUntilNoTasksRemain() {
mock_time_task_runner_->FastForwardUntilNoTasksRemain(); mock_time_task_runner_->FastForwardUntilNoTasksRemain();
} }
std::unique_ptr<TickClock> ScopedTaskEnvironment::GetMockTickClock() {
DCHECK(mock_time_task_runner_);
return mock_time_task_runner_->GetMockTickClock();
}
ScopedTaskEnvironment::TestTaskTracker::TestTaskTracker() ScopedTaskEnvironment::TestTaskTracker::TestTaskTracker()
: internal::TaskSchedulerImpl::TaskTrackerImpl("ScopedTaskEnvironment"), : internal::TaskSchedulerImpl::TaskTrackerImpl("ScopedTaskEnvironment"),
can_run_tasks_cv_(&lock_), can_run_tasks_cv_(&lock_),
......
...@@ -15,6 +15,7 @@ namespace base { ...@@ -15,6 +15,7 @@ namespace base {
class MessageLoop; class MessageLoop;
class TaskScheduler; class TaskScheduler;
class TestMockTimeTaskRunner; class TestMockTimeTaskRunner;
class TickClock;
namespace test { namespace test {
...@@ -108,6 +109,10 @@ class ScopedTaskEnvironment { ...@@ -108,6 +109,10 @@ class ScopedTaskEnvironment {
// Short for FastForwardBy(TimeDelta::Max()). // Short for FastForwardBy(TimeDelta::Max()).
void FastForwardUntilNoTasksRemain(); void FastForwardUntilNoTasksRemain();
// Returns a TickClock whose time is updated by
// FastForward(By|UntilNoTasksRemain).
std::unique_ptr<TickClock> GetMockTickClock();
private: private:
class TestTaskTracker; class TestTaskTracker;
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "base/test/scoped_task_environment.h" #include "base/test/scoped_task_environment.h"
#include <memory>
#include "base/atomicops.h" #include "base/atomicops.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/synchronization/atomic_flag.h" #include "base/synchronization/atomic_flag.h"
...@@ -12,6 +14,7 @@ ...@@ -12,6 +14,7 @@
#include "base/test/test_timeouts.h" #include "base/test/test_timeouts.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "base/time/tick_clock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace base { namespace base {
...@@ -143,6 +146,7 @@ TEST_P(ScopedTaskEnvironmentTest, DelayedTasks) { ...@@ -143,6 +146,7 @@ TEST_P(ScopedTaskEnvironmentTest, DelayedTasks) {
subtle::Atomic32 counter = 0; subtle::Atomic32 counter = 0;
constexpr base::TimeDelta kShortTaskDelay = TimeDelta::FromDays(1);
// Should run only in MOCK_TIME environment when time is fast-forwarded. // Should run only in MOCK_TIME environment when time is fast-forwarded.
ThreadTaskRunnerHandle::Get()->PostDelayedTask( ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, FROM_HERE,
...@@ -151,7 +155,7 @@ TEST_P(ScopedTaskEnvironmentTest, DelayedTasks) { ...@@ -151,7 +155,7 @@ TEST_P(ScopedTaskEnvironmentTest, DelayedTasks) {
subtle::NoBarrier_AtomicIncrement(counter, 4); subtle::NoBarrier_AtomicIncrement(counter, 4);
}, },
Unretained(&counter)), Unretained(&counter)),
TimeDelta::FromDays(1)); kShortTaskDelay);
// TODO(gab): This currently doesn't run because the TaskScheduler's clock // TODO(gab): This currently doesn't run because the TaskScheduler's clock
// isn't mocked but it should be. // isn't mocked but it should be.
PostDelayedTask(FROM_HERE, PostDelayedTask(FROM_HERE,
...@@ -160,8 +164,9 @@ TEST_P(ScopedTaskEnvironmentTest, DelayedTasks) { ...@@ -160,8 +164,9 @@ TEST_P(ScopedTaskEnvironmentTest, DelayedTasks) {
subtle::NoBarrier_AtomicIncrement(counter, 128); subtle::NoBarrier_AtomicIncrement(counter, 128);
}, },
Unretained(&counter)), Unretained(&counter)),
TimeDelta::FromDays(1)); kShortTaskDelay);
constexpr base::TimeDelta kLongTaskDelay = TimeDelta::FromDays(7);
// Same as first task, longer delays to exercise // Same as first task, longer delays to exercise
// FastForwardUntilNoTasksRemain(). // FastForwardUntilNoTasksRemain().
ThreadTaskRunnerHandle::Get()->PostDelayedTask( ThreadTaskRunnerHandle::Get()->PostDelayedTask(
...@@ -179,7 +184,7 @@ TEST_P(ScopedTaskEnvironmentTest, DelayedTasks) { ...@@ -179,7 +184,7 @@ TEST_P(ScopedTaskEnvironmentTest, DelayedTasks) {
subtle::NoBarrier_AtomicIncrement(counter, 16); subtle::NoBarrier_AtomicIncrement(counter, 16);
}, },
Unretained(&counter)), Unretained(&counter)),
TimeDelta::FromDays(7)); kLongTaskDelay);
ThreadTaskRunnerHandle::Get()->PostTask( ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, Bind( FROM_HERE, Bind(
...@@ -205,10 +210,15 @@ TEST_P(ScopedTaskEnvironmentTest, DelayedTasks) { ...@@ -205,10 +210,15 @@ TEST_P(ScopedTaskEnvironmentTest, DelayedTasks) {
EXPECT_EQ(expected_value, counter); EXPECT_EQ(expected_value, counter);
if (GetParam() == ScopedTaskEnvironment::MainThreadType::MOCK_TIME) { if (GetParam() == ScopedTaskEnvironment::MainThreadType::MOCK_TIME) {
scoped_task_environment.FastForwardBy(TimeDelta::FromSeconds(1)); // Delay inferior to the delay of the first posted task.
constexpr base::TimeDelta kInferiorTaskDelay = TimeDelta::FromSeconds(1);
static_assert(kInferiorTaskDelay < kShortTaskDelay,
"|kInferiorTaskDelay| should be "
"set to a value inferior to the first posted task's delay.");
scoped_task_environment.FastForwardBy(kInferiorTaskDelay);
EXPECT_EQ(expected_value, counter); EXPECT_EQ(expected_value, counter);
scoped_task_environment.FastForwardBy(TimeDelta::FromDays(1)); scoped_task_environment.FastForwardBy(kShortTaskDelay - kInferiorTaskDelay);
expected_value += 4; expected_value += 4;
EXPECT_EQ(expected_value, counter); EXPECT_EQ(expected_value, counter);
...@@ -219,6 +229,42 @@ TEST_P(ScopedTaskEnvironmentTest, DelayedTasks) { ...@@ -219,6 +229,42 @@ TEST_P(ScopedTaskEnvironmentTest, DelayedTasks) {
} }
} }
// Verify that the TickClock returned by
// |ScopedTaskEnvironment::GetMockTickClock| gets updated when the
// FastForward(By|UntilNoTasksRemain) functions are called.
TEST_F(ScopedTaskEnvironmentTest, FastForwardAdvanceTickClock) {
// Use a QUEUED execution-mode environment, so that no tasks are actually
// executed until RunUntilIdle()/FastForwardBy() are invoked.
ScopedTaskEnvironment scoped_task_environment(
ScopedTaskEnvironment::MainThreadType::MOCK_TIME,
ScopedTaskEnvironment::ExecutionMode::QUEUED);
constexpr base::TimeDelta kShortTaskDelay = TimeDelta::FromDays(1);
ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, base::BindOnce(&base::DoNothing), kShortTaskDelay);
constexpr base::TimeDelta kLongTaskDelay = TimeDelta::FromDays(7);
ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, base::BindOnce(&base::DoNothing), kLongTaskDelay);
std::unique_ptr<base::TickClock> tick_clock =
scoped_task_environment.GetMockTickClock();
base::TimeTicks tick_clock_ref = tick_clock->NowTicks();
// Make sure that |FastForwardBy| advances the clock.
scoped_task_environment.FastForwardBy(kShortTaskDelay);
EXPECT_EQ(kShortTaskDelay, tick_clock->NowTicks() - tick_clock_ref);
// Make sure that |FastForwardUntilNoTasksRemain| advances the clock.
scoped_task_environment.FastForwardUntilNoTasksRemain();
EXPECT_EQ(kLongTaskDelay, tick_clock->NowTicks() - tick_clock_ref);
// Fast-forwarding to a time at which there's no tasks should also advance the
// clock.
scoped_task_environment.FastForwardBy(kLongTaskDelay);
EXPECT_EQ(kLongTaskDelay * 2, tick_clock->NowTicks() - tick_clock_ref);
}
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
MainThreadDefault, MainThreadDefault,
ScopedTaskEnvironmentTest, ScopedTaskEnvironmentTest,
......
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