Commit 9985a686 authored by Sergio Villar Senin's avatar Sergio Villar Senin Committed by Commit Bot

OnionSoup: Replace WTF::ScopedMockClock by TestMockTimeTaskRunner

As part of removing wtf/time.h we are replacing almost all the usages of
WTF::ScopedMockClock by base::'s TestMockTimeTaskRunner. The remaining
migrations, web_view_test.cc and window_performance_test.cc, will be
done in a followup CL as they require additional changes.

The migrations are all pretty similar. A Clock/TickClock object is added to the
class that is being tested. That class will be internally used to retrieve the
current time/timeticks instead of directly using base/time functions. Production
code will use the DefaultClock/DefaultTickClock which are mostly wrappers to
base::Time::Now() and base::TimeTicks::Now() so there is no change in behaviour
(apart from an extra indirection). Using a clock class has the benefit of
allowing tests to overwrite, by using Set{Clock|TickClock}ForTesting(), that
clock with a mock one they can handle with no changes in the production code.

Note that setting a mock clock sometimes requires additional changes like
recomputing some timestamps that were calculated at object's creation time using
the default (real time) clock.

Last but not least, by using TestMockTimeTaskRunner we are avoiding all the
complications that overwritting the global time functions brings, like the lack
of protection of those global pointers or the inherent disparities of using a
mock and a real clock at the same time.

Bug: 919383
Change-Id: I4f1882643ae817cf68a05f2583a9756f4deff554
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1518518
Commit-Queue: Sergio Villar <svillar@igalia.com>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarJeremy Roman <jbroman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#660347}
parent 2a3edd0b
...@@ -13,6 +13,7 @@ include_rules = [ ...@@ -13,6 +13,7 @@ include_rules = [
"+base/strings/stringprintf.h", "+base/strings/stringprintf.h",
"+base/synchronization/waitable_event.h", "+base/synchronization/waitable_event.h",
"+base/task/sequence_manager/task_time_observer.h", "+base/task/sequence_manager/task_time_observer.h",
"+base/time",
"+base/unguessable_token.h", "+base/unguessable_token.h",
"+build/mac", "+build/mac",
"+build/win", "+build/win",
...@@ -87,6 +88,7 @@ specific_include_rules = { ...@@ -87,6 +88,7 @@ specific_include_rules = {
# Additional allowed includes for tests. # Additional allowed includes for tests.
".*_test(_.*)?\.(cc|h)" : [ ".*_test(_.*)?\.(cc|h)" : [
"+base/message_loop/message_loop.h", "+base/message_loop/message_loop.h",
"+base/test/test_mock_time_task_runner.h",
# Test harness may use cc directly instead of going through WebViewImpl etc. # Test harness may use cc directly instead of going through WebViewImpl etc.
"+cc", "+cc",
"+components/ukm/test_ukm_recorder.h", "+components/ukm/test_ukm_recorder.h",
......
...@@ -3,12 +3,14 @@ ...@@ -3,12 +3,14 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "third_party/blink/renderer/core/display_lock/display_lock_budget.h" #include "third_party/blink/renderer/core/display_lock/display_lock_budget.h"
#include "base/time/default_tick_clock.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_context.h" #include "third_party/blink/renderer/core/display_lock/display_lock_context.h"
namespace blink { namespace blink {
DisplayLockBudget::DisplayLockBudget(DisplayLockContext* context) DisplayLockBudget::DisplayLockBudget(DisplayLockContext* context)
: context_(context) {} : clock_(base::DefaultTickClock::GetInstance()), context_(context) {}
bool DisplayLockBudget::MarkAncestorsDirtyForPhaseIfNeeded(Phase phase) { bool DisplayLockBudget::MarkAncestorsDirtyForPhaseIfNeeded(Phase phase) {
switch (phase) { switch (phase) {
......
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/heap/member.h" #include "third_party/blink/renderer/platform/heap/member.h"
namespace base {
class TickClock;
}
namespace blink { namespace blink {
class DisplayLockContext; class DisplayLockContext;
...@@ -39,6 +43,10 @@ class CORE_EXPORT DisplayLockBudget { ...@@ -39,6 +43,10 @@ class CORE_EXPORT DisplayLockBudget {
// true indicating that another frame is needed. // true indicating that another frame is needed.
virtual bool NeedsLifecycleUpdates() const = 0; virtual bool NeedsLifecycleUpdates() const = 0;
// The caller is the owner of the |clock|. The |clock| must outlive the
// DisplayLockBudget.
void SetTickClockForTesting(const base::TickClock* clock) { clock_ = clock; }
protected: protected:
// Marks the ancestor chain dirty for the given phase if it's needed. Returns // Marks the ancestor chain dirty for the given phase if it's needed. Returns
// true if the ancestors were marked dirty and false otherwise. // true if the ancestors were marked dirty and false otherwise.
...@@ -47,6 +55,8 @@ class CORE_EXPORT DisplayLockBudget { ...@@ -47,6 +55,8 @@ class CORE_EXPORT DisplayLockBudget {
// Returns true if there is likely to be work for the given phase. // Returns true if there is likely to be work for the given phase.
bool IsElementDirtyForPhase(Phase) const; bool IsElementDirtyForPhase(Phase) const;
const base::TickClock* clock_;
private: private:
// This is a backpointer to the context, which should always outlive this // This is a backpointer to the context, which should always outlive this
// budget, so it's untraced. // budget, so it's untraced.
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "third_party/blink/renderer/core/display_lock/display_lock_budget.h" #include "third_party/blink/renderer/core/display_lock/display_lock_budget.h"
#include "base/test/test_mock_time_task_runner.h"
#include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/script_function.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_context.h" #include "third_party/blink/renderer/core/display_lock/display_lock_context.h"
...@@ -12,7 +14,6 @@ ...@@ -12,7 +14,6 @@
#include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/testing/wtf/scoped_mock_clock.h"
namespace blink { namespace blink {
...@@ -22,6 +23,7 @@ class DisplayLockBudgetTest : public RenderingTest { ...@@ -22,6 +23,7 @@ class DisplayLockBudgetTest : public RenderingTest {
RenderingTest::SetUp(); RenderingTest::SetUp();
features_backup_.emplace(); features_backup_.emplace();
RuntimeEnabledFeatures::SetDisplayLockingEnabled(true); RuntimeEnabledFeatures::SetDisplayLockingEnabled(true);
test_task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
} }
void TearDown() override { void TearDown() override {
...@@ -46,6 +48,9 @@ class DisplayLockBudgetTest : public RenderingTest { ...@@ -46,6 +48,9 @@ class DisplayLockBudgetTest : public RenderingTest {
context->update_budget_ = std::move(budget); context->update_budget_ = std::move(budget);
} }
protected:
scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_;
private: private:
base::Optional<RuntimeEnabledFeatures::Backup> features_backup_; base::Optional<RuntimeEnabledFeatures::Backup> features_backup_;
}; };
...@@ -295,8 +300,7 @@ TEST_F(DisplayLockBudgetTest, YieldingBudget) { ...@@ -295,8 +300,7 @@ TEST_F(DisplayLockBudgetTest, YieldingBudget) {
ASSERT_TRUE(element->GetDisplayLockContext()); ASSERT_TRUE(element->GetDisplayLockContext());
YieldingDisplayLockBudget budget(element->GetDisplayLockContext()); YieldingDisplayLockBudget budget(element->GetDisplayLockContext());
budget.SetTickClockForTesting(test_task_runner_->GetMockTickClock());
WTF::ScopedMockClock clock;
// When acquiring, we need to update the layout with the locked size, so we // When acquiring, we need to update the layout with the locked size, so we
// need an update. // need an update.
...@@ -314,13 +318,16 @@ TEST_F(DisplayLockBudgetTest, YieldingBudget) { ...@@ -314,13 +318,16 @@ TEST_F(DisplayLockBudgetTest, YieldingBudget) {
EXPECT_TRUE(budget.NeedsLifecycleUpdates()); EXPECT_TRUE(budget.NeedsLifecycleUpdates());
// Advancing the clock a bit will make us still want to the phases. // Advancing the clock a bit will make us still want to the phases.
clock.Advance(TimeDelta::FromMillisecondsD(GetBudgetMs(budget) / 2)); test_task_runner_->FastForwardBy(
TimeDelta::FromMillisecondsD(GetBudgetMs(budget) / 2));
EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle)); EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle));
EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout)); EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout));
EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint)); EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint));
// However, once we're out of budget, we will only do the next phase. // However, once we're out of budget, we will only do the next phase.
clock.Advance(TimeDelta::FromMillisecondsD(GetBudgetMs(budget))); test_task_runner_->FastForwardBy(
TimeDelta::FromMillisecondsD(GetBudgetMs(budget)));
EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle)); EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle));
EXPECT_FALSE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout)); EXPECT_FALSE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout));
EXPECT_FALSE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint)); EXPECT_FALSE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint));
...@@ -340,7 +347,8 @@ TEST_F(DisplayLockBudgetTest, YieldingBudget) { ...@@ -340,7 +347,8 @@ TEST_F(DisplayLockBudgetTest, YieldingBudget) {
// Now that we're out of budget, phases performed previously should remain // Now that we're out of budget, phases performed previously should remain
// true. // true.
clock.Advance(TimeDelta::FromMillisecondsD(GetBudgetMs(budget) * 2)); test_task_runner_->FastForwardBy(
TimeDelta::FromMillisecondsD(GetBudgetMs(budget) * 2));
EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle)); EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle));
EXPECT_FALSE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout)); EXPECT_FALSE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout));
EXPECT_FALSE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint)); EXPECT_FALSE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint));
...@@ -354,7 +362,8 @@ TEST_F(DisplayLockBudgetTest, YieldingBudget) { ...@@ -354,7 +362,8 @@ TEST_F(DisplayLockBudgetTest, YieldingBudget) {
EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle)); EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle));
EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout)); EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout));
EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint)); EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint));
clock.Advance(TimeDelta::FromMillisecondsD(GetBudgetMs(budget) * 2)); test_task_runner_->FastForwardBy(
TimeDelta::FromMillisecondsD(GetBudgetMs(budget) * 2));
EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle)); EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle));
EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout)); EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout));
EXPECT_FALSE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint)); EXPECT_FALSE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint));
...@@ -368,7 +377,7 @@ TEST_F(DisplayLockBudgetTest, YieldingBudget) { ...@@ -368,7 +377,7 @@ TEST_F(DisplayLockBudgetTest, YieldingBudget) {
EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle)); EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle));
EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout)); EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout));
EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint)); EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint));
clock.Advance(TimeDelta::FromMillisecondsD(10000)); test_task_runner_->FastForwardBy(TimeDelta::FromMillisecondsD(10000));
} }
} }
...@@ -400,6 +409,7 @@ TEST_F(DisplayLockBudgetTest, YieldingBudgetMarksNextPhase) { ...@@ -400,6 +409,7 @@ TEST_F(DisplayLockBudgetTest, YieldingBudgetMarksNextPhase) {
new YieldingDisplayLockBudget(element->GetDisplayLockContext())); new YieldingDisplayLockBudget(element->GetDisplayLockContext()));
; ;
auto* budget = budget_owned.get(); auto* budget = budget_owned.get();
budget->SetTickClockForTesting(test_task_runner_->GetMockTickClock());
{ {
auto* script_state = ToScriptStateForMainWorld(GetDocument().GetFrame()); auto* script_state = ToScriptStateForMainWorld(GetDocument().GetFrame());
ScriptState::Scope scope(script_state); ScriptState::Scope scope(script_state);
...@@ -407,8 +417,6 @@ TEST_F(DisplayLockBudgetTest, YieldingBudgetMarksNextPhase) { ...@@ -407,8 +417,6 @@ TEST_F(DisplayLockBudgetTest, YieldingBudgetMarksNextPhase) {
ResetBudget(std::move(budget_owned), element->GetDisplayLockContext()); ResetBudget(std::move(budget_owned), element->GetDisplayLockContext());
} }
WTF::ScopedMockClock clock;
// When acquiring, we need to update the layout with the locked size, so we // When acquiring, we need to update the layout with the locked size, so we
// need an update. // need an update.
EXPECT_TRUE(budget->NeedsLifecycleUpdates()); EXPECT_TRUE(budget->NeedsLifecycleUpdates());
...@@ -429,7 +437,8 @@ TEST_F(DisplayLockBudgetTest, YieldingBudgetMarksNextPhase) { ...@@ -429,7 +437,8 @@ TEST_F(DisplayLockBudgetTest, YieldingBudgetMarksNextPhase) {
EXPECT_TRUE(parent->NeedsStyleRecalc() || parent->ChildNeedsStyleRecalc()); EXPECT_TRUE(parent->NeedsStyleRecalc() || parent->ChildNeedsStyleRecalc());
EXPECT_TRUE(element->NeedsStyleRecalc() || element->ChildNeedsStyleRecalc()); EXPECT_TRUE(element->NeedsStyleRecalc() || element->ChildNeedsStyleRecalc());
clock.Advance(TimeDelta::FromMillisecondsD(GetBudgetMs(*budget) * 2)); test_task_runner_->FastForwardBy(
TimeDelta::FromMillisecondsD(GetBudgetMs(*budget) * 2));
EXPECT_TRUE(budget->ShouldPerformPhase(DisplayLockBudget::Phase::kStyle)); EXPECT_TRUE(budget->ShouldPerformPhase(DisplayLockBudget::Phase::kStyle));
EXPECT_FALSE(budget->ShouldPerformPhase(DisplayLockBudget::Phase::kLayout)); EXPECT_FALSE(budget->ShouldPerformPhase(DisplayLockBudget::Phase::kLayout));
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/display_lock/yielding_display_lock_budget.h" #include "third_party/blink/renderer/core/display_lock/yielding_display_lock_budget.h"
#include "base/time/tick_clock.h"
#include "third_party/blink/renderer/platform/wtf/time.h" #include "third_party/blink/renderer/platform/wtf/time.h"
#include <algorithm> #include <algorithm>
...@@ -24,7 +25,7 @@ bool YieldingDisplayLockBudget::ShouldPerformPhase(Phase phase) const { ...@@ -24,7 +25,7 @@ bool YieldingDisplayLockBudget::ShouldPerformPhase(Phase phase) const {
return true; return true;
// Otherwise, we can still do work while we're not past the deadline. // Otherwise, we can still do work while we're not past the deadline.
return CurrentTimeTicks() < deadline_; return clock_->NowTicks() < deadline_;
} }
void YieldingDisplayLockBudget::DidPerformPhase(Phase phase) { void YieldingDisplayLockBudget::DidPerformPhase(Phase phase) {
...@@ -42,7 +43,7 @@ void YieldingDisplayLockBudget::DidPerformPhase(Phase phase) { ...@@ -42,7 +43,7 @@ void YieldingDisplayLockBudget::DidPerformPhase(Phase phase) {
void YieldingDisplayLockBudget::WillStartLifecycleUpdate() { void YieldingDisplayLockBudget::WillStartLifecycleUpdate() {
++lifecycle_count_; ++lifecycle_count_;
deadline_ = deadline_ =
CurrentTimeTicks() + TimeDelta::FromMillisecondsD(GetCurrentBudgetMs()); clock_->NowTicks() + TimeDelta::FromMillisecondsD(GetCurrentBudgetMs());
// Figure out the next phase we would run. If we had completed a phase before, // Figure out the next phase we would run. If we had completed a phase before,
// then we should try to complete the next one, otherwise we'll start with the // then we should try to complete the next one, otherwise we'll start with the
......
...@@ -4,18 +4,20 @@ ...@@ -4,18 +4,20 @@
#include "third_party/blink/renderer/core/dom/idle_deadline.h" #include "third_party/blink/renderer/core/dom/idle_deadline.h"
#include "base/time/default_tick_clock.h"
#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/core/timing/performance.h" #include "third_party/blink/renderer/core/timing/performance.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink { namespace blink {
IdleDeadline::IdleDeadline(TimeTicks deadline, CallbackType callback_type) IdleDeadline::IdleDeadline(TimeTicks deadline, CallbackType callback_type)
: deadline_(deadline), callback_type_(callback_type) {} : deadline_(deadline),
callback_type_(callback_type),
clock_(base::DefaultTickClock::GetInstance()) {}
double IdleDeadline::timeRemaining() const { double IdleDeadline::timeRemaining() const {
TimeDelta time_remaining = deadline_ - CurrentTimeTicks(); TimeDelta time_remaining = deadline_ - clock_->NowTicks();
if (time_remaining < TimeDelta() || if (time_remaining < TimeDelta() ||
ThreadScheduler::Current()->ShouldYieldForHighPriorityWork()) { ThreadScheduler::Current()->ShouldYieldForHighPriorityWork()) {
return 0; return 0;
......
...@@ -10,6 +10,10 @@ ...@@ -10,6 +10,10 @@
#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/time.h" #include "third_party/blink/renderer/platform/wtf/time.h"
namespace base {
class TickClock;
}
namespace blink { namespace blink {
class CORE_EXPORT IdleDeadline : public ScriptWrappable { class CORE_EXPORT IdleDeadline : public ScriptWrappable {
...@@ -32,9 +36,14 @@ class CORE_EXPORT IdleDeadline : public ScriptWrappable { ...@@ -32,9 +36,14 @@ class CORE_EXPORT IdleDeadline : public ScriptWrappable {
return callback_type_ == CallbackType::kCalledByTimeout; return callback_type_ == CallbackType::kCalledByTimeout;
} }
// The caller is the owner of the |clock|. The |clock| must outlive the
// IdleDeadline.
void SetTickClockForTesting(const base::TickClock* clock) { clock_ = clock; }
private: private:
TimeTicks deadline_; TimeTicks deadline_;
CallbackType callback_type_; CallbackType callback_type_;
const base::TickClock* clock_;
}; };
} // namespace blink } // namespace blink
......
...@@ -5,12 +5,11 @@ ...@@ -5,12 +5,11 @@
#include "third_party/blink/renderer/core/dom/idle_deadline.h" #include "third_party/blink/renderer/core/dom/idle_deadline.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "base/test/test_mock_time_task_runner.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/testing/scoped_scheduler_overrider.h" #include "third_party/blink/renderer/platform/testing/scoped_scheduler_overrider.h"
#include "third_party/blink/renderer/platform/testing/wtf/scoped_mock_clock.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink { namespace blink {
namespace { namespace {
...@@ -74,16 +73,20 @@ class MockIdleDeadlineScheduler final : public ThreadScheduler { ...@@ -74,16 +73,20 @@ class MockIdleDeadlineScheduler final : public ThreadScheduler {
class IdleDeadlineTest : public testing::Test { class IdleDeadlineTest : public testing::Test {
public: public:
void SetUp() override { clock_.Advance(TimeDelta::FromSeconds(1)); } void SetUp() override {
test_task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
}
private: protected:
WTF::ScopedMockClock clock_; scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_;
}; };
TEST_F(IdleDeadlineTest, DeadlineInFuture) { TEST_F(IdleDeadlineTest, DeadlineInFuture) {
auto* deadline = MakeGarbageCollected<IdleDeadline>( auto* deadline = MakeGarbageCollected<IdleDeadline>(
TimeTicks() + TimeDelta::FromSecondsD(1.25), TimeTicks() + TimeDelta::FromSecondsD(1.25),
IdleDeadline::CallbackType::kCalledWhenIdle); IdleDeadline::CallbackType::kCalledWhenIdle);
deadline->SetTickClockForTesting(test_task_runner_->GetMockTickClock());
test_task_runner_->FastForwardBy(TimeDelta::FromSeconds(1));
// Note: the deadline is computed with reduced resolution. // Note: the deadline is computed with reduced resolution.
EXPECT_FLOAT_EQ(250.0, deadline->timeRemaining()); EXPECT_FLOAT_EQ(250.0, deadline->timeRemaining());
} }
...@@ -92,6 +95,8 @@ TEST_F(IdleDeadlineTest, DeadlineInPast) { ...@@ -92,6 +95,8 @@ TEST_F(IdleDeadlineTest, DeadlineInPast) {
auto* deadline = MakeGarbageCollected<IdleDeadline>( auto* deadline = MakeGarbageCollected<IdleDeadline>(
TimeTicks() + TimeDelta::FromSecondsD(0.75), TimeTicks() + TimeDelta::FromSecondsD(0.75),
IdleDeadline::CallbackType::kCalledWhenIdle); IdleDeadline::CallbackType::kCalledWhenIdle);
deadline->SetTickClockForTesting(test_task_runner_->GetMockTickClock());
test_task_runner_->FastForwardBy(TimeDelta::FromSeconds(1));
EXPECT_FLOAT_EQ(0, deadline->timeRemaining()); EXPECT_FLOAT_EQ(0, deadline->timeRemaining());
} }
...@@ -102,6 +107,8 @@ TEST_F(IdleDeadlineTest, YieldForHighPriorityWork) { ...@@ -102,6 +107,8 @@ TEST_F(IdleDeadlineTest, YieldForHighPriorityWork) {
auto* deadline = MakeGarbageCollected<IdleDeadline>( auto* deadline = MakeGarbageCollected<IdleDeadline>(
TimeTicks() + TimeDelta::FromSecondsD(1.25), TimeTicks() + TimeDelta::FromSecondsD(1.25),
IdleDeadline::CallbackType::kCalledWhenIdle); IdleDeadline::CallbackType::kCalledWhenIdle);
deadline->SetTickClockForTesting(test_task_runner_->GetMockTickClock());
test_task_runner_->FastForwardBy(TimeDelta::FromSeconds(1));
EXPECT_FLOAT_EQ(0, deadline->timeRemaining()); EXPECT_FLOAT_EQ(0, deadline->timeRemaining());
} }
......
...@@ -4,12 +4,12 @@ ...@@ -4,12 +4,12 @@
#include "third_party/blink/renderer/core/dom/user_gesture_indicator.h" #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h"
#include "base/time/default_clock.h"
#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/platform/histogram.h" #include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink { namespace blink {
...@@ -21,7 +21,8 @@ const double kUserGestureOutOfProcessTimeout = 10.0; ...@@ -21,7 +21,8 @@ const double kUserGestureOutOfProcessTimeout = 10.0;
UserGestureToken::UserGestureToken(Status status) UserGestureToken::UserGestureToken(Status status)
: consumable_gestures_(0), : consumable_gestures_(0),
timestamp_(WTF::CurrentTime()), clock_(base::DefaultClock::GetInstance()),
timestamp_(clock_->Now().ToDoubleT()),
timeout_policy_(kDefault), timeout_policy_(kDefault),
was_forwarded_cross_process_(false) { was_forwarded_cross_process_(false) {
if (status == kNewGesture || !UserGestureIndicator::CurrentTokenThreadSafe()) if (status == kNewGesture || !UserGestureIndicator::CurrentTokenThreadSafe())
...@@ -52,7 +53,7 @@ void UserGestureToken::SetTimeoutPolicy(TimeoutPolicy policy) { ...@@ -52,7 +53,7 @@ void UserGestureToken::SetTimeoutPolicy(TimeoutPolicy policy) {
} }
void UserGestureToken::ResetTimestamp() { void UserGestureToken::ResetTimestamp() {
timestamp_ = WTF::CurrentTime(); timestamp_ = clock_->Now().ToDoubleT();
} }
bool UserGestureToken::HasTimedOut() const { bool UserGestureToken::HasTimedOut() const {
...@@ -61,7 +62,7 @@ bool UserGestureToken::HasTimedOut() const { ...@@ -61,7 +62,7 @@ bool UserGestureToken::HasTimedOut() const {
double timeout = timeout_policy_ == kOutOfProcess double timeout = timeout_policy_ == kOutOfProcess
? kUserGestureOutOfProcessTimeout ? kUserGestureOutOfProcessTimeout
: kUserGestureTimeout; : kUserGestureTimeout;
return WTF::CurrentTime() - timestamp_ > timeout; return clock_->Now().ToDoubleT() - timestamp_ > timeout;
} }
bool UserGestureToken::WasForwardedCrossProcess() const { bool UserGestureToken::WasForwardedCrossProcess() const {
......
...@@ -10,6 +10,10 @@ ...@@ -10,6 +10,10 @@
#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/wtf/ref_counted.h" #include "third_party/blink/renderer/platform/wtf/ref_counted.h"
namespace base {
class Clock;
}
namespace blink { namespace blink {
// A UserGestureToken represents the current state of a user gesture. It can be // A UserGestureToken represents the current state of a user gesture. It can be
...@@ -32,6 +36,9 @@ class CORE_EXPORT UserGestureToken : public RefCounted<UserGestureToken> { ...@@ -32,6 +36,9 @@ class CORE_EXPORT UserGestureToken : public RefCounted<UserGestureToken> {
// need to investigate the usecase closely. // need to investigate the usecase closely.
bool HasGestures() const; bool HasGestures() const;
void SetClockForTesting(const base::Clock* clock) { clock_ = clock; }
void ResetTimestampForTesting() { ResetTimestamp(); }
private: private:
UserGestureToken(Status); UserGestureToken(Status);
...@@ -44,6 +51,7 @@ class CORE_EXPORT UserGestureToken : public RefCounted<UserGestureToken> { ...@@ -44,6 +51,7 @@ class CORE_EXPORT UserGestureToken : public RefCounted<UserGestureToken> {
void SetWasForwardedCrossProcess(); void SetWasForwardedCrossProcess();
size_t consumable_gestures_; size_t consumable_gestures_;
const base::Clock* clock_;
double timestamp_; double timestamp_;
TimeoutPolicy timeout_policy_; TimeoutPolicy timeout_policy_;
bool was_forwarded_cross_process_; bool was_forwarded_cross_process_;
......
...@@ -4,10 +4,9 @@ ...@@ -4,10 +4,9 @@
#include "third_party/blink/renderer/core/dom/user_gesture_indicator.h" #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h"
#include "base/test/test_mock_time_task_runner.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/platform/testing/wtf/scoped_mock_clock.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink { namespace blink {
...@@ -112,17 +111,20 @@ TEST(UserGestureIndicatorTest, MultipleGesturesWithTheSameToken) { ...@@ -112,17 +111,20 @@ TEST(UserGestureIndicatorTest, MultipleGesturesWithTheSameToken) {
} }
TEST(UserGestureIndicatorTest, Timeouts) { TEST(UserGestureIndicatorTest, Timeouts) {
WTF::ScopedMockClock clock; auto test_task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
{ {
// Token times out after 1 second. // Token times out after 1 second.
std::unique_ptr<UserGestureIndicator> user_gesture_scope = std::unique_ptr<UserGestureIndicator> user_gesture_scope =
LocalFrame::NotifyUserActivation(nullptr); LocalFrame::NotifyUserActivation(nullptr);
scoped_refptr<UserGestureToken> token = user_gesture_scope->CurrentToken(); scoped_refptr<UserGestureToken> token = user_gesture_scope->CurrentToken();
token->SetClockForTesting(test_task_runner->GetMockClock());
// Timestamp is initialized to Now() in constructor using the default clock,
// reset it so it gets the Now() of the mock clock.
token->ResetTimestampForTesting();
EXPECT_TRUE(token->HasGestures()); EXPECT_TRUE(token->HasGestures());
clock.Advance(TimeDelta::FromSecondsD(0.75)); test_task_runner->FastForwardBy(TimeDelta::FromSecondsD(0.75));
EXPECT_TRUE(token->HasGestures()); EXPECT_TRUE(token->HasGestures());
clock.Advance(TimeDelta::FromSecondsD(0.75)); test_task_runner->FastForwardBy(TimeDelta::FromSecondsD(0.75));
EXPECT_FALSE(token->HasGestures()); EXPECT_FALSE(token->HasGestures());
} }
...@@ -134,16 +136,20 @@ TEST(UserGestureIndicatorTest, Timeouts) { ...@@ -134,16 +136,20 @@ TEST(UserGestureIndicatorTest, Timeouts) {
std::unique_ptr<UserGestureIndicator> user_gesture_scope = std::unique_ptr<UserGestureIndicator> user_gesture_scope =
LocalFrame::NotifyUserActivation(nullptr); LocalFrame::NotifyUserActivation(nullptr);
token = user_gesture_scope->CurrentToken(); token = user_gesture_scope->CurrentToken();
token->SetClockForTesting(test_task_runner->GetMockClock());
// Timestamp is initialized to Now() in constructor using the default
// clock, reset it so it gets the Now() of the mock clock.
token->ResetTimestampForTesting();
EXPECT_TRUE(token->HasGestures()); EXPECT_TRUE(token->HasGestures());
clock.Advance(TimeDelta::FromSecondsD(0.75)); test_task_runner->FastForwardBy(TimeDelta::FromSecondsD(0.75));
EXPECT_TRUE(token->HasGestures()); EXPECT_TRUE(token->HasGestures());
} }
{ {
UserGestureIndicator user_gesture_scope(token.get()); UserGestureIndicator user_gesture_scope(token.get());
clock.Advance(TimeDelta::FromSecondsD(0.75)); test_task_runner->FastForwardBy(TimeDelta::FromSecondsD(0.75));
EXPECT_TRUE(token->HasGestures()); EXPECT_TRUE(token->HasGestures());
clock.Advance(TimeDelta::FromSecondsD(0.75)); test_task_runner->FastForwardBy(TimeDelta::FromSecondsD(0.75));
EXPECT_FALSE(token->HasGestures()); EXPECT_FALSE(token->HasGestures());
} }
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/format_macros.h" #include "base/format_macros.h"
#include "base/rand_util.h" #include "base/rand_util.h"
#include "base/time/default_tick_clock.h"
#include "services/metrics/public/cpp/ukm_builders.h" #include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h" #include "services/metrics/public/cpp/ukm_recorder.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
...@@ -15,15 +16,18 @@ namespace blink { ...@@ -15,15 +16,18 @@ namespace blink {
LocalFrameUkmAggregator::ScopedUkmHierarchicalTimer::ScopedUkmHierarchicalTimer( LocalFrameUkmAggregator::ScopedUkmHierarchicalTimer::ScopedUkmHierarchicalTimer(
scoped_refptr<LocalFrameUkmAggregator> aggregator, scoped_refptr<LocalFrameUkmAggregator> aggregator,
size_t metric_index) size_t metric_index,
const base::TickClock* clock)
: aggregator_(aggregator), : aggregator_(aggregator),
metric_index_(metric_index), metric_index_(metric_index),
start_time_(CurrentTimeTicks()) {} clock_(clock),
start_time_(clock_->NowTicks()) {}
LocalFrameUkmAggregator::ScopedUkmHierarchicalTimer::ScopedUkmHierarchicalTimer( LocalFrameUkmAggregator::ScopedUkmHierarchicalTimer::ScopedUkmHierarchicalTimer(
ScopedUkmHierarchicalTimer&& other) ScopedUkmHierarchicalTimer&& other)
: aggregator_(other.aggregator_), : aggregator_(other.aggregator_),
metric_index_(other.metric_index_), metric_index_(other.metric_index_),
clock_(other.clock_),
start_time_(other.start_time_) { start_time_(other.start_time_) {
other.aggregator_ = nullptr; other.aggregator_ = nullptr;
} }
...@@ -31,7 +35,7 @@ LocalFrameUkmAggregator::ScopedUkmHierarchicalTimer::ScopedUkmHierarchicalTimer( ...@@ -31,7 +35,7 @@ LocalFrameUkmAggregator::ScopedUkmHierarchicalTimer::ScopedUkmHierarchicalTimer(
LocalFrameUkmAggregator::ScopedUkmHierarchicalTimer:: LocalFrameUkmAggregator::ScopedUkmHierarchicalTimer::
~ScopedUkmHierarchicalTimer() { ~ScopedUkmHierarchicalTimer() {
if (aggregator_ && base::TimeTicks::IsHighResolution()) { if (aggregator_ && base::TimeTicks::IsHighResolution()) {
aggregator_->RecordSample(metric_index_, start_time_, CurrentTimeTicks()); aggregator_->RecordSample(metric_index_, start_time_, clock_->NowTicks());
} }
} }
...@@ -39,6 +43,7 @@ LocalFrameUkmAggregator::LocalFrameUkmAggregator(int64_t source_id, ...@@ -39,6 +43,7 @@ LocalFrameUkmAggregator::LocalFrameUkmAggregator(int64_t source_id,
ukm::UkmRecorder* recorder) ukm::UkmRecorder* recorder)
: source_id_(source_id), : source_id_(source_id),
recorder_(recorder), recorder_(recorder),
clock_(base::DefaultTickClock::GetInstance()),
event_name_("Blink.UpdateTime") { event_name_("Blink.UpdateTime") {
// Record average and worst case for the primary metric. // Record average and worst case for the primary metric.
primary_metric_.reset(); primary_metric_.reset();
...@@ -111,7 +116,7 @@ LocalFrameUkmAggregator::LocalFrameUkmAggregator(int64_t source_id, ...@@ -111,7 +116,7 @@ LocalFrameUkmAggregator::LocalFrameUkmAggregator(int64_t source_id,
LocalFrameUkmAggregator::ScopedUkmHierarchicalTimer LocalFrameUkmAggregator::ScopedUkmHierarchicalTimer
LocalFrameUkmAggregator::GetScopedTimer(size_t metric_index) { LocalFrameUkmAggregator::GetScopedTimer(size_t metric_index) {
return ScopedUkmHierarchicalTimer(this, metric_index); return ScopedUkmHierarchicalTimer(this, metric_index, clock_);
} }
void LocalFrameUkmAggregator::BeginMainFrame() { void LocalFrameUkmAggregator::BeginMainFrame() {
...@@ -119,6 +124,11 @@ void LocalFrameUkmAggregator::BeginMainFrame() { ...@@ -119,6 +124,11 @@ void LocalFrameUkmAggregator::BeginMainFrame() {
in_main_frame_update_ = true; in_main_frame_update_ = true;
} }
void LocalFrameUkmAggregator::SetTickClockForTesting(
const base::TickClock* clock) {
clock_ = clock;
}
void LocalFrameUkmAggregator::RecordSample(size_t metric_index, void LocalFrameUkmAggregator::RecordSample(size_t metric_index,
TimeTicks start, TimeTicks start,
TimeTicks end) { TimeTicks end) {
......
...@@ -11,6 +11,10 @@ ...@@ -11,6 +11,10 @@
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/time.h" #include "third_party/blink/renderer/platform/wtf/time.h"
namespace base {
class TickClock;
}
namespace ukm { namespace ukm {
class UkmRecorder; class UkmRecorder;
} }
...@@ -194,10 +198,12 @@ class CORE_EXPORT LocalFrameUkmAggregator ...@@ -194,10 +198,12 @@ class CORE_EXPORT LocalFrameUkmAggregator
friend class LocalFrameUkmAggregator; friend class LocalFrameUkmAggregator;
ScopedUkmHierarchicalTimer(scoped_refptr<LocalFrameUkmAggregator>, ScopedUkmHierarchicalTimer(scoped_refptr<LocalFrameUkmAggregator>,
size_t metric_index); size_t metric_index,
const base::TickClock* clock);
scoped_refptr<LocalFrameUkmAggregator> aggregator_; scoped_refptr<LocalFrameUkmAggregator> aggregator_;
const size_t metric_index_; const size_t metric_index_;
const base::TickClock* clock_;
const TimeTicks start_time_; const TimeTicks start_time_;
DISALLOW_COPY_AND_ASSIGN(ScopedUkmHierarchicalTimer); DISALLOW_COPY_AND_ASSIGN(ScopedUkmHierarchicalTimer);
...@@ -226,6 +232,10 @@ class CORE_EXPORT LocalFrameUkmAggregator ...@@ -226,6 +232,10 @@ class CORE_EXPORT LocalFrameUkmAggregator
bool InMainFrame() { return in_main_frame_update_; } bool InMainFrame() { return in_main_frame_update_; }
// The caller is the owner of the |clock|. The |clock| must outlive the
// LocalFrameUkmAggregator.
void SetTickClockForTesting(const base::TickClock* clock);
private: private:
struct AbsoluteMetricRecord { struct AbsoluteMetricRecord {
std::unique_ptr<CustomCountHistogram> uma_counter; std::unique_ptr<CustomCountHistogram> uma_counter;
...@@ -261,6 +271,7 @@ class CORE_EXPORT LocalFrameUkmAggregator ...@@ -261,6 +271,7 @@ class CORE_EXPORT LocalFrameUkmAggregator
// UKM system data // UKM system data
const int64_t source_id_; const int64_t source_id_;
ukm::UkmRecorder* const recorder_; ukm::UkmRecorder* const recorder_;
const base::TickClock* clock_;
// Event and metric data // Event and metric data
const String event_name_; const String event_name_;
......
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
#include "third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h" #include "third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h"
#include "base/test/test_mock_time_task_runner.h"
#include "components/ukm/test_ukm_recorder.h" #include "components/ukm/test_ukm_recorder.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/testing/wtf/scoped_mock_clock.h"
namespace blink { namespace blink {
...@@ -16,14 +16,14 @@ class LocalFrameUkmAggregatorTest : public testing::Test { ...@@ -16,14 +16,14 @@ class LocalFrameUkmAggregatorTest : public testing::Test {
~LocalFrameUkmAggregatorTest() override = default; ~LocalFrameUkmAggregatorTest() override = default;
void SetUp() override { void SetUp() override {
clock_.emplace(); test_task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
aggregator_ = base::MakeRefCounted<LocalFrameUkmAggregator>( aggregator_ = base::MakeRefCounted<LocalFrameUkmAggregator>(
ukm::UkmRecorder::GetNewSourceID(), &recorder_); ukm::UkmRecorder::GetNewSourceID(), &recorder_);
aggregator_->SetTickClockForTesting(test_task_runner_->GetMockTickClock());
} }
void TearDown() override { void TearDown() override {
aggregator_.reset(); aggregator_.reset();
clock_.reset();
} }
LocalFrameUkmAggregator& aggregator() { LocalFrameUkmAggregator& aggregator() {
...@@ -35,8 +35,6 @@ class LocalFrameUkmAggregatorTest : public testing::Test { ...@@ -35,8 +35,6 @@ class LocalFrameUkmAggregatorTest : public testing::Test {
void ResetAggregator() { aggregator_.reset(); } void ResetAggregator() { aggregator_.reset(); }
WTF::ScopedMockClock& clock() { return *clock_; }
std::string GetPrimaryMetricName() { std::string GetPrimaryMetricName() {
return std::string( return std::string(
LocalFrameUkmAggregator::primary_metric_name().Utf8().data()); LocalFrameUkmAggregator::primary_metric_name().Utf8().data());
...@@ -58,9 +56,10 @@ class LocalFrameUkmAggregatorTest : public testing::Test { ...@@ -58,9 +56,10 @@ class LocalFrameUkmAggregatorTest : public testing::Test {
aggregator().FramesToNextEventForTest(delta); aggregator().FramesToNextEventForTest(delta);
} }
base::TimeTicks Now() { base::TimeTicks Now() { return test_task_runner_->NowTicks(); }
return base::TimeTicks() + base::TimeDelta::FromSecondsD(clock_->Now());
} protected:
scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_;
void VerifyEntries(unsigned expected_num_entries, void VerifyEntries(unsigned expected_num_entries,
unsigned expected_primary_metric, unsigned expected_primary_metric,
...@@ -93,7 +92,6 @@ class LocalFrameUkmAggregatorTest : public testing::Test { ...@@ -93,7 +92,6 @@ class LocalFrameUkmAggregatorTest : public testing::Test {
} }
private: private:
base::Optional<WTF::ScopedMockClock> clock_;
scoped_refptr<LocalFrameUkmAggregator> aggregator_; scoped_refptr<LocalFrameUkmAggregator> aggregator_;
ukm::TestUkmRecorder recorder_; ukm::TestUkmRecorder recorder_;
}; };
...@@ -106,7 +104,7 @@ TEST_F(LocalFrameUkmAggregatorTest, EmptyEventsNotRecorded) { ...@@ -106,7 +104,7 @@ TEST_F(LocalFrameUkmAggregatorTest, EmptyEventsNotRecorded) {
return; return;
// There is no BeginMainFrame, so no metrics get recorded. // There is no BeginMainFrame, so no metrics get recorded.
clock().Advance(TimeDelta::FromSeconds(10)); test_task_runner_->FastForwardBy(TimeDelta::FromSeconds(10));
ResetAggregator(); ResetAggregator();
EXPECT_EQ(recorder().sources_count(), 0u); EXPECT_EQ(recorder().sources_count(), 0u);
...@@ -129,7 +127,8 @@ TEST_F(LocalFrameUkmAggregatorTest, FirstFrameIsRecorded) { ...@@ -129,7 +127,8 @@ TEST_F(LocalFrameUkmAggregatorTest, FirstFrameIsRecorded) {
for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) { for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) {
auto timer = auto timer =
aggregator().GetScopedTimer(i % LocalFrameUkmAggregator::kCount); aggregator().GetScopedTimer(i % LocalFrameUkmAggregator::kCount);
clock().Advance(TimeDelta::FromMilliseconds(millisecond_for_step)); test_task_runner_->FastForwardBy(
TimeDelta::FromMilliseconds(millisecond_for_step));
} }
aggregator().RecordEndOfFrameMetrics(start_time, Now()); aggregator().RecordEndOfFrameMetrics(start_time, Now());
...@@ -171,9 +170,11 @@ TEST_F(LocalFrameUkmAggregatorTest, EventsRecordedAtIntervals) { ...@@ -171,9 +170,11 @@ TEST_F(LocalFrameUkmAggregatorTest, EventsRecordedAtIntervals) {
aggregator().BeginMainFrame(); aggregator().BeginMainFrame();
for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) { for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) {
auto timer = aggregator().GetScopedTimer(i); auto timer = aggregator().GetScopedTimer(i);
clock().Advance(TimeDelta::FromMilliseconds(millisecond_per_step)); test_task_runner_->FastForwardBy(
TimeDelta::FromMilliseconds(millisecond_per_step));
} }
clock().Advance(TimeDelta::FromMilliseconds(millisecond_per_step)); test_task_runner_->FastForwardBy(
TimeDelta::FromMilliseconds(millisecond_per_step));
aggregator().RecordEndOfFrameMetrics(start_time, Now()); aggregator().RecordEndOfFrameMetrics(start_time, Now());
// We should have a sample after the very first step, regardless of the // We should have a sample after the very first step, regardless of the
...@@ -188,9 +189,11 @@ TEST_F(LocalFrameUkmAggregatorTest, EventsRecordedAtIntervals) { ...@@ -188,9 +189,11 @@ TEST_F(LocalFrameUkmAggregatorTest, EventsRecordedAtIntervals) {
aggregator().BeginMainFrame(); aggregator().BeginMainFrame();
for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) { for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) {
auto timer = aggregator().GetScopedTimer(i); auto timer = aggregator().GetScopedTimer(i);
clock().Advance(TimeDelta::FromMilliseconds(millisecond_per_step)); test_task_runner_->FastForwardBy(
TimeDelta::FromMilliseconds(millisecond_per_step));
} }
clock().Advance(TimeDelta::FromMilliseconds(millisecond_per_step)); test_task_runner_->FastForwardBy(
TimeDelta::FromMilliseconds(millisecond_per_step));
aggregator().RecordEndOfFrameMetrics(start_time, Now()); aggregator().RecordEndOfFrameMetrics(start_time, Now());
VerifyEntries(1u, millisecond_per_frame, millisecond_per_step, VerifyEntries(1u, millisecond_per_frame, millisecond_per_step,
...@@ -203,9 +206,11 @@ TEST_F(LocalFrameUkmAggregatorTest, EventsRecordedAtIntervals) { ...@@ -203,9 +206,11 @@ TEST_F(LocalFrameUkmAggregatorTest, EventsRecordedAtIntervals) {
aggregator().BeginMainFrame(); aggregator().BeginMainFrame();
for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) { for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) {
auto timer = aggregator().GetScopedTimer(i); auto timer = aggregator().GetScopedTimer(i);
clock().Advance(TimeDelta::FromMilliseconds(millisecond_per_step)); test_task_runner_->FastForwardBy(
TimeDelta::FromMilliseconds(millisecond_per_step));
} }
clock().Advance(TimeDelta::FromMilliseconds(millisecond_per_step)); test_task_runner_->FastForwardBy(
TimeDelta::FromMilliseconds(millisecond_per_step));
aggregator().RecordEndOfFrameMetrics(start_time, Now()); aggregator().RecordEndOfFrameMetrics(start_time, Now());
VerifyEntries(2u, millisecond_per_frame, millisecond_per_step, VerifyEntries(2u, millisecond_per_frame, millisecond_per_step,
...@@ -216,9 +221,11 @@ TEST_F(LocalFrameUkmAggregatorTest, EventsRecordedAtIntervals) { ...@@ -216,9 +221,11 @@ TEST_F(LocalFrameUkmAggregatorTest, EventsRecordedAtIntervals) {
aggregator().BeginMainFrame(); aggregator().BeginMainFrame();
for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) { for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) {
auto timer = aggregator().GetScopedTimer(i); auto timer = aggregator().GetScopedTimer(i);
clock().Advance(TimeDelta::FromMilliseconds(millisecond_per_step)); test_task_runner_->FastForwardBy(
TimeDelta::FromMilliseconds(millisecond_per_step));
} }
clock().Advance(TimeDelta::FromMilliseconds(millisecond_per_step)); test_task_runner_->FastForwardBy(
TimeDelta::FromMilliseconds(millisecond_per_step));
aggregator().RecordEndOfFrameMetrics(start_time, Now()); aggregator().RecordEndOfFrameMetrics(start_time, Now());
// Should be no more samples. // Should be no more samples.
...@@ -230,9 +237,11 @@ TEST_F(LocalFrameUkmAggregatorTest, EventsRecordedAtIntervals) { ...@@ -230,9 +237,11 @@ TEST_F(LocalFrameUkmAggregatorTest, EventsRecordedAtIntervals) {
aggregator().BeginMainFrame(); aggregator().BeginMainFrame();
for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) { for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) {
auto timer = aggregator().GetScopedTimer(i); auto timer = aggregator().GetScopedTimer(i);
clock().Advance(TimeDelta::FromMilliseconds(millisecond_per_step)); test_task_runner_->FastForwardBy(
TimeDelta::FromMilliseconds(millisecond_per_step));
} }
clock().Advance(TimeDelta::FromMilliseconds(millisecond_per_step)); test_task_runner_->FastForwardBy(
TimeDelta::FromMilliseconds(millisecond_per_step));
aggregator().RecordEndOfFrameMetrics(start_time, Now()); aggregator().RecordEndOfFrameMetrics(start_time, Now());
// We should have 3 more events, once for the prior interval and 2 for the // We should have 3 more events, once for the prior interval and 2 for the
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/paint/image_paint_timing_detector.h" #include "third_party/blink/renderer/core/paint/image_paint_timing_detector.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/test/test_mock_time_task_runner.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h" #include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
#include "third_party/blink/public/web/web_performance.h" #include "third_party/blink/public/web/web_performance.h"
...@@ -23,7 +24,6 @@ ...@@ -23,7 +24,6 @@
#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/wtf/scoped_mock_clock.h"
#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkSurface.h"
...@@ -38,6 +38,7 @@ class ImagePaintTimingDetectorTest ...@@ -38,6 +38,7 @@ class ImagePaintTimingDetectorTest
ImagePaintTimingDetectorTest() ImagePaintTimingDetectorTest()
: RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()), : RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()),
ScopedFirstContentfulPaintPlusPlusForTest(true), ScopedFirstContentfulPaintPlusPlusForTest(true),
test_task_runner_(base::MakeRefCounted<base::TestMockTimeTaskRunner>()),
base_url_("http://www.test.com/") {} base_url_("http://www.test.com/") {}
~ImagePaintTimingDetectorTest() override { ~ImagePaintTimingDetectorTest() override {
...@@ -131,8 +132,16 @@ class ImagePaintTimingDetectorTest ...@@ -131,8 +132,16 @@ class ImagePaintTimingDetectorTest
return GetPaintTimingDetector().largest_image_paint_time_; return GetPaintTimingDetector().largest_image_paint_time_;
} }
static constexpr TimeDelta kQuantumOfTime =
base::TimeDelta::FromMilliseconds(10);
void SimulatePassOfTime() {
test_task_runner_->FastForwardBy(kQuantumOfTime);
}
void UpdateAllLifecyclePhasesAndInvokeCallbackIfAny() { void UpdateAllLifecyclePhasesAndInvokeCallbackIfAny() {
UpdateAllLifecyclePhasesForTest(); UpdateAllLifecyclePhasesForTest();
SimulatePassOfTime();
if (!callback_queue_.empty()) if (!callback_queue_.empty())
InvokeCallback(); InvokeCallback();
} }
...@@ -140,7 +149,8 @@ class ImagePaintTimingDetectorTest ...@@ -140,7 +149,8 @@ class ImagePaintTimingDetectorTest
void InvokeCallback() { void InvokeCallback() {
DCHECK_GT(callback_queue_.size(), 0UL); DCHECK_GT(callback_queue_.size(), 0UL);
std::move(callback_queue_.front()) std::move(callback_queue_.front())
.Run(WebWidgetClient::SwapResult::kDidSwap, CurrentTimeTicks()); .Run(WebWidgetClient::SwapResult::kDidSwap,
test_task_runner_->NowTicks());
callback_queue_.pop(); callback_queue_.pop();
} }
...@@ -177,6 +187,8 @@ class ImagePaintTimingDetectorTest ...@@ -177,6 +187,8 @@ class ImagePaintTimingDetectorTest
void SimulateScroll() { GetPaintTimingDetector().NotifyScroll(kUserScroll); } void SimulateScroll() { GetPaintTimingDetector().NotifyScroll(kUserScroll); }
scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_;
private: private:
void FakeNotifySwapTime(WebWidgetClient::ReportTimeCallback callback) { void FakeNotifySwapTime(WebWidgetClient::ReportTimeCallback callback) {
callback_queue_.push(std::move(callback)); callback_queue_.push(std::move(callback));
...@@ -197,6 +209,8 @@ class ImagePaintTimingDetectorTest ...@@ -197,6 +209,8 @@ class ImagePaintTimingDetectorTest
std::string base_url_; std::string base_url_;
}; };
constexpr TimeDelta ImagePaintTimingDetectorTest::kQuantumOfTime;
TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_NoImage) { TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_NoImage) {
SetBodyInnerHTML(R"HTML( SetBodyInnerHTML(R"HTML(
<div></div> <div></div>
...@@ -452,7 +466,6 @@ TEST_F(ImagePaintTimingDetectorTest, ...@@ -452,7 +466,6 @@ TEST_F(ImagePaintTimingDetectorTest,
TEST_F(ImagePaintTimingDetectorTest, TEST_F(ImagePaintTimingDetectorTest,
LargestImagePaint_ReattachedNodeUseFirstPaint) { LargestImagePaint_ReattachedNodeUseFirstPaint) {
WTF::ScopedMockClock clock;
SetBodyInnerHTML(R"HTML( SetBodyInnerHTML(R"HTML(
<div id="parent"> <div id="parent">
</div> </div>
...@@ -461,26 +474,32 @@ TEST_F(ImagePaintTimingDetectorTest, ...@@ -461,26 +474,32 @@ TEST_F(ImagePaintTimingDetectorTest,
image->setAttribute("id", "target"); image->setAttribute("id", "target");
GetDocument().getElementById("parent")->AppendChild(image); GetDocument().getElementById("parent")->AppendChild(image);
SetImageAndPaint("target", 5, 5); SetImageAndPaint("target", 5, 5);
clock.Advance(TimeDelta::FromSecondsD(1)); test_task_runner_->FastForwardBy(TimeDelta::FromSecondsD(1));
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny(); UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
ImageRecord* record; ImageRecord* record;
record = FindLargestPaintCandidate(); record = FindLargestPaintCandidate();
EXPECT_TRUE(record); EXPECT_TRUE(record);
EXPECT_EQ(record->paint_time, base::TimeTicks() + TimeDelta::FromSecondsD(1)); // UpdateAllLifecyclePhasesAndInvokeCallbackIfAny() moves time forward
// kQuantumOfTime so we should take that into account.
EXPECT_EQ(record->paint_time,
base::TimeTicks() + TimeDelta::FromSecondsD(1) + kQuantumOfTime);
GetDocument().getElementById("parent")->RemoveChild(image); GetDocument().getElementById("parent")->RemoveChild(image);
clock.Advance(TimeDelta::FromSecondsD(1)); test_task_runner_->FastForwardBy(TimeDelta::FromSecondsD(1));
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny(); UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
record = FindLargestPaintCandidate(); record = FindLargestPaintCandidate();
EXPECT_FALSE(record); EXPECT_FALSE(record);
GetDocument().getElementById("parent")->AppendChild(image); GetDocument().getElementById("parent")->AppendChild(image);
SetImageAndPaint("target", 5, 5); SetImageAndPaint("target", 5, 5);
clock.Advance(TimeDelta::FromSecondsD(1)); test_task_runner_->FastForwardBy(TimeDelta::FromSecondsD(1));
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny(); UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
record = FindLargestPaintCandidate(); record = FindLargestPaintCandidate();
EXPECT_TRUE(record); EXPECT_TRUE(record);
EXPECT_EQ(record->paint_time, base::TimeTicks() + TimeDelta::FromSecondsD(1)); // UpdateAllLifecyclePhasesAndInvokeCallbackIfAny() moves time forward
// kQuantumOfTime so we should take that into account.
EXPECT_EQ(record->paint_time,
base::TimeTicks() + TimeDelta::FromSecondsD(1) + kQuantumOfTime);
} }
// This is to prove that a swap time is assigned only to nodes of the frame who // This is to prove that a swap time is assigned only to nodes of the frame who
...@@ -496,8 +515,10 @@ TEST_F(ImagePaintTimingDetectorTest, MatchSwapTimeToNodesOfDifferentFrames) { ...@@ -496,8 +515,10 @@ TEST_F(ImagePaintTimingDetectorTest, MatchSwapTimeToNodesOfDifferentFrames) {
SetImageAndPaint("larger", 9, 9); SetImageAndPaint("larger", 9, 9);
UpdateAllLifecyclePhasesForTest(); UpdateAllLifecyclePhasesForTest();
SimulatePassOfTime();
SetImageAndPaint("smaller", 5, 5); SetImageAndPaint("smaller", 5, 5);
UpdateAllLifecyclePhasesForTest(); UpdateAllLifecyclePhasesForTest();
SimulatePassOfTime();
InvokeCallback(); InvokeCallback();
// record1 is the larger. // record1 is the larger.
ImageRecord* record1 = FindLargestPaintCandidate(); ImageRecord* record1 = FindLargestPaintCandidate();
...@@ -505,6 +526,7 @@ TEST_F(ImagePaintTimingDetectorTest, MatchSwapTimeToNodesOfDifferentFrames) { ...@@ -505,6 +526,7 @@ TEST_F(ImagePaintTimingDetectorTest, MatchSwapTimeToNodesOfDifferentFrames) {
GetDocument().getElementById("parent")->RemoveChild( GetDocument().getElementById("parent")->RemoveChild(
GetDocument().getElementById("larger")); GetDocument().getElementById("larger"));
UpdateAllLifecyclePhasesForTest(); UpdateAllLifecyclePhasesForTest();
SimulatePassOfTime();
InvokeCallback(); InvokeCallback();
// record2 is the smaller. // record2 is the smaller.
ImageRecord* record2 = FindLargestPaintCandidate(); ImageRecord* record2 = FindLargestPaintCandidate();
...@@ -513,7 +535,7 @@ TEST_F(ImagePaintTimingDetectorTest, MatchSwapTimeToNodesOfDifferentFrames) { ...@@ -513,7 +535,7 @@ TEST_F(ImagePaintTimingDetectorTest, MatchSwapTimeToNodesOfDifferentFrames) {
TEST_F(ImagePaintTimingDetectorTest, TEST_F(ImagePaintTimingDetectorTest,
LargestImagePaint_UpdateResultWhenLargestChanged) { LargestImagePaint_UpdateResultWhenLargestChanged) {
TimeTicks time1 = CurrentTimeTicks(); TimeTicks time1 = test_task_runner_->NowTicks();
SetBodyInnerHTML(R"HTML( SetBodyInnerHTML(R"HTML(
<div id="parent"> <div id="parent">
<img id="target1"></img> <img id="target1"></img>
...@@ -522,14 +544,14 @@ TEST_F(ImagePaintTimingDetectorTest, ...@@ -522,14 +544,14 @@ TEST_F(ImagePaintTimingDetectorTest,
)HTML"); )HTML");
SetImageAndPaint("target1", 5, 5); SetImageAndPaint("target1", 5, 5);
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny(); UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
TimeTicks time2 = CurrentTimeTicks(); TimeTicks time2 = test_task_runner_->NowTicks();
TimeTicks result1 = LargestPaintStoredResult(); TimeTicks result1 = LargestPaintStoredResult();
EXPECT_GE(result1, time1); EXPECT_GE(result1, time1);
EXPECT_GE(time2, result1); EXPECT_GE(time2, result1);
SetImageAndPaint("target2", 10, 10); SetImageAndPaint("target2", 10, 10);
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny(); UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
TimeTicks time3 = CurrentTimeTicks(); TimeTicks time3 = test_task_runner_->NowTicks();
TimeTicks result2 = LargestPaintStoredResult(); TimeTicks result2 = LargestPaintStoredResult();
EXPECT_GE(result2, time2); EXPECT_GE(result2, time2);
EXPECT_GE(time3, result2); EXPECT_GE(time3, result2);
...@@ -545,9 +567,11 @@ TEST_F(ImagePaintTimingDetectorTest, OneSwapPromiseForOneFrame) { ...@@ -545,9 +567,11 @@ TEST_F(ImagePaintTimingDetectorTest, OneSwapPromiseForOneFrame) {
)HTML"); )HTML");
SetImageAndPaint("1", 5, 5); SetImageAndPaint("1", 5, 5);
UpdateAllLifecyclePhasesForTest(); UpdateAllLifecyclePhasesForTest();
SimulatePassOfTime();
SetImageAndPaint("2", 9, 9); SetImageAndPaint("2", 9, 9);
UpdateAllLifecyclePhasesForTest(); UpdateAllLifecyclePhasesForTest();
SimulatePassOfTime();
// This callback only assigns a time to the 5x5 image. // This callback only assigns a time to the 5x5 image.
InvokeCallback(); InvokeCallback();
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <stdint.h> #include <stdint.h>
#include "base/metrics/histogram_base.h" #include "base/metrics/histogram_base.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/time/default_tick_clock.h"
#include "base/time/tick_clock.h" #include "base/time/tick_clock.h"
#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/allocator.h"
...@@ -70,37 +71,42 @@ class PLATFORM_EXPORT LinearHistogram : public CustomCountHistogram { ...@@ -70,37 +71,42 @@ class PLATFORM_EXPORT LinearHistogram : public CustomCountHistogram {
int32_t bucket_count); int32_t bucket_count);
}; };
class PLATFORM_EXPORT ScopedUsHistogramTimer { template <typename Derived>
USING_FAST_MALLOC(ScopedUsHistogramTimer); class ScopedUsHistogramTimerBase {
USING_FAST_MALLOC(ScopedUsHistogramTimerBase);
public: public:
explicit ScopedUsHistogramTimer(CustomCountHistogram& counter) explicit ScopedUsHistogramTimerBase(CustomCountHistogram& counter)
: start_time_(CurrentTimeTicks()), counter_(counter) {} : ScopedUsHistogramTimerBase(counter,
base::DefaultTickClock::GetInstance()) {}
~ScopedUsHistogramTimer() { ScopedUsHistogramTimerBase(CustomCountHistogram& counter,
counter_.CountMicroseconds(CurrentTimeTicks() - start_time_); const base::TickClock* clock)
: clock_(*clock), start_time_(clock_.NowTicks()), counter_(counter) {}
~ScopedUsHistogramTimerBase() {
if (Derived::ShouldRecord())
counter_.CountMicroseconds(clock_.NowTicks() - start_time_);
} }
private: private:
const base::TickClock& clock_;
TimeTicks start_time_; TimeTicks start_time_;
CustomCountHistogram& counter_; CustomCountHistogram& counter_;
}; };
class PLATFORM_EXPORT ScopedHighResUsHistogramTimer { class ScopedUsHistogramTimer
USING_FAST_MALLOC(ScopedUsHistogramTimer); : public ScopedUsHistogramTimerBase<ScopedUsHistogramTimer> {
public: public:
explicit ScopedHighResUsHistogramTimer(CustomCountHistogram& counter) using ScopedUsHistogramTimerBase::ScopedUsHistogramTimerBase;
: start_time_(CurrentTimeTicks()), counter_(counter) {} static bool ShouldRecord() { return true; }
};
~ScopedHighResUsHistogramTimer() {
if (TimeTicks::IsHighResolution())
counter_.CountMicroseconds(CurrentTimeTicks() - start_time_);
}
private: class ScopedHighResUsHistogramTimer
TimeTicks start_time_; : public ScopedUsHistogramTimerBase<ScopedHighResUsHistogramTimer> {
CustomCountHistogram& counter_; public:
using ScopedUsHistogramTimerBase::ScopedUsHistogramTimerBase;
static bool ShouldRecord() { return TimeTicks::IsHighResolution(); }
}; };
#define SCOPED_BLINK_UMA_HISTOGRAM_TIMER_IMPL(name, allow_cross_thread) \ #define SCOPED_BLINK_UMA_HISTOGRAM_TIMER_IMPL(name, allow_cross_thread) \
......
...@@ -5,9 +5,8 @@ ...@@ -5,9 +5,8 @@
#include "third_party/blink/renderer/platform/histogram.h" #include "third_party/blink/renderer/platform/histogram.h"
#include "base/metrics/histogram_samples.h" #include "base/metrics/histogram_samples.h"
#include "base/test/test_mock_time_task_runner.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/testing/wtf/scoped_mock_clock.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink { namespace blink {
...@@ -22,25 +21,35 @@ class TestCustomCountHistogram : public CustomCountHistogram { ...@@ -22,25 +21,35 @@ class TestCustomCountHistogram : public CustomCountHistogram {
base::HistogramBase* Histogram() { return histogram_; } base::HistogramBase* Histogram() { return histogram_; }
}; };
TEST(ScopedUsHistogramTimerTest, Basic) { class ScopedUsHistogramTimerTest : public testing::Test {
public:
void SetUp() override {
test_task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
}
protected:
scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_;
};
TEST_F(ScopedUsHistogramTimerTest, Basic) {
TestCustomCountHistogram scoped_us_counter("ScopedUsHistogramTimerTest.Basic", TestCustomCountHistogram scoped_us_counter("ScopedUsHistogramTimerTest.Basic",
0, 10000000, 50); 0, 10000000, 50);
{ {
WTF::ScopedMockClock clock; ScopedUsHistogramTimer timer(scoped_us_counter,
ScopedUsHistogramTimer timer(scoped_us_counter); test_task_runner_->GetMockTickClock());
clock.Advance(TimeDelta::FromMilliseconds(500)); test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(500));
} }
// 500ms == 500000us // 500ms == 500000us
EXPECT_EQ(500000, scoped_us_counter.Histogram()->SnapshotSamples()->sum()); EXPECT_EQ(500000, scoped_us_counter.Histogram()->SnapshotSamples()->sum());
} }
TEST(ScopedHighResUsHistogramTimerTest, Basic) { TEST_F(ScopedUsHistogramTimerTest, BasicHighRes) {
TestCustomCountHistogram scoped_us_counter( TestCustomCountHistogram scoped_us_counter(
"ScopedHighResUsHistogramTimerTest.Basic", 0, 10000000, 50); "ScopedHighResUsHistogramTimerTest.Basic", 0, 10000000, 50);
{ {
WTF::ScopedMockClock clock; ScopedHighResUsHistogramTimer timer(scoped_us_counter,
ScopedHighResUsHistogramTimer timer(scoped_us_counter); test_task_runner_->GetMockTickClock());
clock.Advance(TimeDelta::FromMilliseconds(500)); test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(500));
} }
int64_t expected = TimeTicks::IsHighResolution() ? 500000 : 0; int64_t expected = TimeTicks::IsHighResolution() ? 500000 : 0;
EXPECT_EQ(expected, scoped_us_counter.Histogram()->SnapshotSamples()->sum()); EXPECT_EQ(expected, scoped_us_counter.Histogram()->SnapshotSamples()->sum());
......
...@@ -198,6 +198,12 @@ _CONFIG = [ ...@@ -198,6 +198,12 @@ _CONFIG = [
# For MessageLoop::TaskObserver. # For MessageLoop::TaskObserver.
'base::PendingTask', 'base::PendingTask',
# Time
'base::Clock',
'base::DefaultClock',
'base::DefaultTickClock',
'base::TickClock',
# cc painting types. # cc painting types.
'cc::PaintCanvas', 'cc::PaintCanvas',
'cc::PaintFlags', 'cc::PaintFlags',
......
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