Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1593)

Unified Diff: chrome/browser/page_load_metrics/user_input_tracker_unittest.cc

Issue 2540183003: Add UserInputTracker, which keeps track of recent user input events. (Closed)
Patch Set: address comments Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/page_load_metrics/user_input_tracker_unittest.cc
diff --git a/chrome/browser/page_load_metrics/user_input_tracker_unittest.cc b/chrome/browser/page_load_metrics/user_input_tracker_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..5ff1be79f04cf2360808c4f1b07cf6eda003b112
--- /dev/null
+++ b/chrome/browser/page_load_metrics/user_input_tracker_unittest.cc
@@ -0,0 +1,212 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
Charlie Harrison 2016/12/05 19:17:46 Copyright 2016 no (c)
Bryan McQuade 2016/12/06 01:52:25 Ah, sure. I fixed a couple other tests in the same
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/page_load_metrics/user_input_tracker.h"
+
+#include "base/time/time.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/WebInputEvent.h"
+
Charlie Harrison 2016/12/05 19:17:46 Shouldn't these tests be in namespace page_load_me
Bryan McQuade 2016/12/06 01:52:25 I don't think so. Most of our tests don't follow t
Charlie Harrison 2016/12/06 18:43:09 That was because originally the namespace was conf
Bryan McQuade 2016/12/06 20:10:03 Ah, ok, I went ahead and made this change. I took
+namespace {
+
+// UserInputTracker allows events to be at most 2 seconds old. Thus we use
+// 2100ms to make sure the age is greater than 2 seconds.
+const int kTooOldMilliseconds = 2100;
+
+double ToMonotonicallyIncreasingSeconds(base::TimeTicks t) {
+ return t.ToInternalValue() /
Charlie Harrison 2016/12/05 19:17:46 Use (t - base::TimeTicks()).InSecondsF()
Bryan McQuade 2016/12/06 01:52:25 Ah, nice, much better, thanks!
+ static_cast<double>(base::Time::kMicrosecondsPerSecond);
+}
+
+class FakeInputEvent : public blink::WebInputEvent {
+ public:
+ FakeInputEvent() : WebInputEvent(sizeof(FakeInputEvent)) {
+ timeStampSeconds = ToMonotonicallyIncreasingSeconds(base::TimeTicks::Now());
+ type = blink::WebInputEvent::Char;
Charlie Harrison 2016/12/05 19:17:47 Should we vary on this to ensure we aren't recordi
Bryan McQuade 2016/12/06 01:52:25 Added a test.
+ }
+
+ base::TimeTicks GetTimeStamp() {
+ return page_load_metrics::UserInputTracker::GetEventTime(*this);
+ }
+
+ base::TimeTicks GetTimeStampRounded() {
+ return page_load_metrics::UserInputTracker::RoundToRateLimitedOffset(
+ GetTimeStamp());
+ }
+};
+
+} // namespace
+
+class UserInputTrackerTest : public testing::Test {};
+
+TEST_F(UserInputTrackerTest, Basic) {
+ page_load_metrics::UserInputTracker tracker;
+ EXPECT_EQ(base::TimeTicks(),
+ tracker.FindMostRecentUserInputEventBefore(base::TimeTicks()));
+ EXPECT_EQ(base::TimeTicks(),
+ tracker.FindMostRecentUserInputEventBefore(base::TimeTicks::Now()));
+}
+
+TEST_F(UserInputTrackerTest, SingleEvent) {
+ page_load_metrics::UserInputTracker tracker;
+ FakeInputEvent e;
+ tracker.OnInputEvent(e);
+
+ EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
+ e.GetTimeStampRounded()));
+
+ base::TimeTicks after =
+ e.GetTimeStampRounded() + base::TimeDelta::FromMicroseconds(1);
+
+ EXPECT_EQ(e.GetTimeStampRounded(),
+ tracker.FindMostRecentUserInputEventBefore(after));
+
+ EXPECT_TRUE(tracker.FindAndConsumeInputEventsBefore(e.GetTimeStamp()));
+
+ EXPECT_EQ(base::TimeTicks(),
+ tracker.FindMostRecentUserInputEventBefore(after));
+}
+
+TEST_F(UserInputTrackerTest, MultipleEvents) {
+ FakeInputEvent e1;
+ FakeInputEvent e2;
+
+ // Make sure that the two events are monotonically increasing, and that both
+ // are in the past.
+ e1.timeStampSeconds = ToMonotonicallyIncreasingSeconds(
+ e2.GetTimeStamp() - base::TimeDelta::FromMilliseconds(100));
+
+ base::TimeTicks after =
+ e2.GetTimeStampRounded() + base::TimeDelta::FromMicroseconds(1);
+
+ {
+ page_load_metrics::UserInputTracker tracker;
+ tracker.OnInputEvent(e1);
+ tracker.OnInputEvent(e2);
+
+ EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
+ e1.GetTimeStampRounded()));
+ EXPECT_EQ(
+ e1.GetTimeStampRounded(),
+ tracker.FindMostRecentUserInputEventBefore(e2.GetTimeStampRounded()));
+
+ EXPECT_EQ(e2.GetTimeStampRounded(),
+ tracker.FindMostRecentUserInputEventBefore(after));
+
+ EXPECT_TRUE(tracker.FindAndConsumeInputEventsBefore(e1.GetTimeStamp()));
Charlie Harrison 2016/12/05 19:17:46 Why is this always true? Shouldn't e1 == event_tim
Bryan McQuade 2016/12/06 01:52:25 Wow, this is just a straight up test bug, thanks f
+ EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
+ e1.GetTimeStampRounded()));
+ EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
+ e2.GetTimeStampRounded()));
+ EXPECT_EQ(e2.GetTimeStampRounded(),
+ tracker.FindMostRecentUserInputEventBefore(after));
+
+ EXPECT_TRUE(tracker.FindAndConsumeInputEventsBefore(e2.GetTimeStamp()));
+ EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
+ e1.GetTimeStampRounded()));
+ EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
+ e2.GetTimeStampRounded()));
+ EXPECT_EQ(base::TimeTicks(),
+ tracker.FindMostRecentUserInputEventBefore(after));
+ }
+
+ {
+ page_load_metrics::UserInputTracker tracker;
+ tracker.OnInputEvent(e1);
+ tracker.OnInputEvent(e2);
+ EXPECT_EQ(e2.GetTimeStampRounded(),
+ tracker.FindMostRecentUserInputEventBefore(after));
+ EXPECT_TRUE(tracker.FindAndConsumeInputEventsBefore(e2.GetTimeStamp()));
+ EXPECT_EQ(base::TimeTicks(),
+ tracker.FindMostRecentUserInputEventBefore(after));
+ }
+}
+
+TEST_F(UserInputTrackerTest, IgnoreEventsOlderThanConsumed) {
+ FakeInputEvent e1;
+ FakeInputEvent e2;
+
+ // Make sure that the two events are monotonically increasing, and that both
+ // are in the past.
+ e1.timeStampSeconds = ToMonotonicallyIncreasingSeconds(
+ e2.GetTimeStamp() - base::TimeDelta::FromMilliseconds(100));
+
+ base::TimeTicks after =
+ e2.GetTimeStampRounded() + base::TimeDelta::FromMicroseconds(1);
+
+ page_load_metrics::UserInputTracker tracker;
+ tracker.OnInputEvent(e2);
+
+ EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
+ e1.GetTimeStampRounded()));
+ EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
+ e2.GetTimeStampRounded()));
+ EXPECT_EQ(e2.GetTimeStampRounded(),
+ tracker.FindMostRecentUserInputEventBefore(after));
+
+ EXPECT_TRUE(tracker.FindAndConsumeInputEventsBefore(e2.GetTimeStamp()));
+ EXPECT_EQ(base::TimeTicks(),
+ tracker.FindMostRecentUserInputEventBefore(after));
+
+ tracker.OnInputEvent(e1);
+ EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
+ e1.GetTimeStampRounded()));
+ EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
+ e1.GetTimeStampRounded() +
+ base::TimeDelta::FromMicroseconds(1)));
+}
+
+TEST_F(UserInputTrackerTest, ExcludeOldEvents) {
+ page_load_metrics::UserInputTracker tracker;
+ FakeInputEvent e1;
+ FakeInputEvent e2;
+ // make sure e1 is too old to be considered.
+ e1.timeStampSeconds = ToMonotonicallyIncreasingSeconds(
+ e2.GetTimeStamp() -
+ base::TimeDelta::FromMilliseconds(kTooOldMilliseconds));
+
+ tracker.OnInputEvent(e1);
+ tracker.OnInputEvent(e2);
+
+ EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
+ e1.GetTimeStampRounded() +
+ base::TimeDelta::FromMilliseconds(1)));
+ EXPECT_EQ(base::TimeTicks(),
+ tracker.FindMostRecentUserInputEventBefore(
+ e2.GetTimeStampRounded() +
+ base::TimeDelta::FromMilliseconds(kTooOldMilliseconds)));
+ EXPECT_EQ(
+ e2.GetTimeStampRounded(),
+ tracker.FindMostRecentUserInputEventBefore(
+ e2.GetTimeStampRounded() + base::TimeDelta::FromMilliseconds(1)));
Charlie Harrison 2016/12/05 19:17:47 Add test: EXPECT_EQ(base::TimeTicks(), tracker.Fid
Bryan McQuade 2016/12/06 01:52:25 Done
+}
+
+TEST_F(UserInputTrackerTest, RateLimit) {
+ const size_t kTooManyEntries =
+ page_load_metrics::UserInputTracker::kMaxEntries * 5;
+
+ page_load_metrics::UserInputTracker tracker;
+ FakeInputEvent e;
+
+ // UserInputTracker DCHECKs that event timestamps aren't after the current
+ // time, so to be safe, we use a starting timestamp that is twice
+ // kTooManyEntries milliseconds in the past, and then synthesize one event for
+ // each of kTooManyEntries after this start point. This guarantees that all
+ // events are in the past.
+ e.timeStampSeconds = ToMonotonicallyIncreasingSeconds(
+ e.GetTimeStamp() -
+ base::TimeDelta::FromMilliseconds(kTooManyEntries * 2));
+
+ // Insert more than kMaxEntries entries. The rate limiting logic should
+ // prevent more than kMaxEntries entries from actually being inserted. A
+ // DCHECK in OnInputEvent verifies that we don't exceed the expected capacity.
+ for (size_t i = 0; i < kTooManyEntries; ++i) {
+ tracker.OnInputEvent(e);
+ e.timeStampSeconds += base::TimeDelta::FromMilliseconds(1).InSecondsF();
+ }
+
+ // Do a basic sanity check to make sure we can find events in the tracker.
+ EXPECT_NE(base::TimeTicks(),
+ tracker.FindMostRecentUserInputEventBefore(base::TimeTicks::Now()));
+}

Powered by Google App Engine
This is Rietveld 408576698