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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/page_load_metrics/user_input_tracker.h"
6
7 #include "base/time/time.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "third_party/WebKit/public/platform/WebInputEvent.h"
10
11 namespace {
12
13 // UserInputTracker allows events to be at most 2 seconds old. Thus we use
14 // 2100ms to make sure the age is greater than 2 seconds.
15 const int kTooOldMilliseconds = 2100;
16
17 double ToMonotonicallyIncreasingSeconds(base::TimeTicks t) {
18 return (t - base::TimeTicks()).InSecondsF();
19 }
20
21 class FakeInputEvent : public blink::WebInputEvent {
22 public:
23 FakeInputEvent() : WebInputEvent(sizeof(FakeInputEvent)) {
24 timeStampSeconds = ToMonotonicallyIncreasingSeconds(base::TimeTicks::Now());
25 type = blink::WebInputEvent::Char;
26 }
27
28 base::TimeTicks GetTimeStamp() {
29 return page_load_metrics::UserInputTracker::GetEventTime(*this);
30 }
31
32 base::TimeTicks GetTimeStampRounded() {
33 return page_load_metrics::UserInputTracker::RoundToRateLimitedOffset(
34 GetTimeStamp());
35 }
36 };
37
38 } // namespace
39
40 class UserInputTrackerTest : public testing::Test {};
41
42 TEST_F(UserInputTrackerTest, Basic) {
43 page_load_metrics::UserInputTracker tracker;
44 EXPECT_EQ(base::TimeTicks(),
45 tracker.FindMostRecentUserInputEventBefore(base::TimeTicks()));
46 EXPECT_EQ(base::TimeTicks(),
47 tracker.FindMostRecentUserInputEventBefore(base::TimeTicks::Now()));
48 }
49
50 TEST_F(UserInputTrackerTest, SingleEvent) {
51 page_load_metrics::UserInputTracker tracker;
52 FakeInputEvent e;
53 tracker.OnInputEvent(e);
54
55 EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
56 e.GetTimeStampRounded()));
57
58 base::TimeTicks after =
59 e.GetTimeStampRounded() + base::TimeDelta::FromMicroseconds(1);
60
61 EXPECT_EQ(e.GetTimeStampRounded(),
62 tracker.FindMostRecentUserInputEventBefore(after));
63
64 EXPECT_TRUE(tracker.FindAndConsumeInputEventsBefore(e.GetTimeStamp()));
65
66 EXPECT_EQ(base::TimeTicks(),
67 tracker.FindMostRecentUserInputEventBefore(after));
68 }
69
70 TEST_F(UserInputTrackerTest, MultipleEvents) {
71 FakeInputEvent e1;
72 FakeInputEvent e2;
73
74 // Make sure that the two events are monotonically increasing, and that both
75 // are in the past.
76 e1.timeStampSeconds = ToMonotonicallyIncreasingSeconds(
77 e2.GetTimeStamp() - base::TimeDelta::FromMilliseconds(100));
78
79 base::TimeTicks after =
80 e2.GetTimeStampRounded() + base::TimeDelta::FromMicroseconds(1);
81
82 {
83 page_load_metrics::UserInputTracker tracker;
84 tracker.OnInputEvent(e1);
85 tracker.OnInputEvent(e2);
86
87 EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
88 e1.GetTimeStampRounded()));
89 EXPECT_EQ(
90 e1.GetTimeStampRounded(),
91 tracker.FindMostRecentUserInputEventBefore(e2.GetTimeStampRounded()));
92
93 EXPECT_EQ(e2.GetTimeStampRounded(),
94 tracker.FindMostRecentUserInputEventBefore(after));
95
96 EXPECT_FALSE(
97 tracker.FindAndConsumeInputEventsBefore(e1.GetTimeStampRounded()));
98 EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
99 e1.GetTimeStampRounded()));
100 EXPECT_EQ(
101 e1.GetTimeStampRounded(),
102 tracker.FindMostRecentUserInputEventBefore(e2.GetTimeStampRounded()));
103 EXPECT_EQ(e2.GetTimeStampRounded(),
104 tracker.FindMostRecentUserInputEventBefore(after));
105
106 EXPECT_TRUE(tracker.FindAndConsumeInputEventsBefore(e2.GetTimeStamp()));
107 EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
108 e1.GetTimeStampRounded()));
109 EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
110 e2.GetTimeStampRounded()));
111 EXPECT_EQ(base::TimeTicks(),
112 tracker.FindMostRecentUserInputEventBefore(after));
113 }
114
115 {
116 page_load_metrics::UserInputTracker tracker;
117 tracker.OnInputEvent(e1);
118 tracker.OnInputEvent(e2);
119 EXPECT_EQ(e2.GetTimeStampRounded(),
120 tracker.FindMostRecentUserInputEventBefore(after));
121 EXPECT_TRUE(tracker.FindAndConsumeInputEventsBefore(e2.GetTimeStamp()));
122 EXPECT_EQ(base::TimeTicks(),
123 tracker.FindMostRecentUserInputEventBefore(after));
124 }
125 }
126
127 TEST_F(UserInputTrackerTest, IgnoreEventsOlderThanConsumed) {
128 FakeInputEvent e1;
129 FakeInputEvent e2;
130
131 // Make sure that the two events are monotonically increasing, and that both
132 // are in the past.
133 e1.timeStampSeconds = ToMonotonicallyIncreasingSeconds(
134 e2.GetTimeStamp() - base::TimeDelta::FromMilliseconds(100));
135
136 base::TimeTicks after =
137 e2.GetTimeStampRounded() + base::TimeDelta::FromMicroseconds(1);
138
139 page_load_metrics::UserInputTracker tracker;
140 tracker.OnInputEvent(e2);
141
142 EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
143 e1.GetTimeStampRounded()));
144 EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
145 e2.GetTimeStampRounded()));
146 EXPECT_EQ(e2.GetTimeStampRounded(),
147 tracker.FindMostRecentUserInputEventBefore(after));
148
149 EXPECT_TRUE(tracker.FindAndConsumeInputEventsBefore(e2.GetTimeStamp()));
150 EXPECT_EQ(base::TimeTicks(),
151 tracker.FindMostRecentUserInputEventBefore(after));
152
153 tracker.OnInputEvent(e1);
154 EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
155 e1.GetTimeStampRounded()));
156 EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
157 e1.GetTimeStampRounded() +
158 base::TimeDelta::FromMicroseconds(1)));
159 }
160
161 TEST_F(UserInputTrackerTest, ExcludeOldEvents) {
162 page_load_metrics::UserInputTracker tracker;
163 FakeInputEvent e1;
164 FakeInputEvent e2;
165 // make sure e1 is too old to be considered.
166 e1.timeStampSeconds = ToMonotonicallyIncreasingSeconds(
167 e2.GetTimeStamp() -
168 base::TimeDelta::FromMilliseconds(kTooOldMilliseconds));
169
170 tracker.OnInputEvent(e1);
171 tracker.OnInputEvent(e2);
172
173 EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
174 e1.GetTimeStampRounded() +
175 base::TimeDelta::FromMilliseconds(1)));
176 EXPECT_EQ(base::TimeTicks(),
177 tracker.FindMostRecentUserInputEventBefore(
178 e2.GetTimeStampRounded() +
179 base::TimeDelta::FromMilliseconds(kTooOldMilliseconds)));
180 EXPECT_EQ(
181 e2.GetTimeStampRounded(),
182 tracker.FindMostRecentUserInputEventBefore(
183 e2.GetTimeStampRounded() + base::TimeDelta::FromMilliseconds(1)));
184
185 EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
186 e2.GetTimeStampRounded()));
187 }
188
189 TEST_F(UserInputTrackerTest, RateLimit) {
190 const size_t kTooManyEntries =
191 page_load_metrics::UserInputTracker::kMaxTrackedEvents * 5;
192
193 page_load_metrics::UserInputTracker tracker;
194 FakeInputEvent e;
195
196 // UserInputTracker DCHECKs that event timestamps aren't after the current
197 // time, so to be safe, we use a starting timestamp that is twice
198 // kTooManyEntries milliseconds in the past, and then synthesize one event for
199 // each of kTooManyEntries after this start point. This guarantees that all
200 // events are in the past.
201 e.timeStampSeconds = ToMonotonicallyIncreasingSeconds(
202 e.GetTimeStamp() -
203 base::TimeDelta::FromMilliseconds(kTooManyEntries * 2));
204
205 // Insert more than kMaxEntries entries. The rate limiting logic should
206 // prevent more than kMaxEntries entries from actually being inserted. A
207 // DCHECK in OnInputEvent verifies that we don't exceed the expected capacity.
208 for (size_t i = 0; i < kTooManyEntries; ++i) {
209 tracker.OnInputEvent(e);
210 e.timeStampSeconds += base::TimeDelta::FromMilliseconds(1).InSecondsF();
211 }
212
213 // Do a basic sanity check to make sure we can find events in the tracker.
214 EXPECT_NE(base::TimeTicks(),
215 tracker.FindMostRecentUserInputEventBefore(base::TimeTicks::Now()));
216 }
217
218 TEST_F(UserInputTrackerTest, IgnoredEventType) {
219 page_load_metrics::UserInputTracker tracker;
220 FakeInputEvent e;
221 e.type = blink::WebInputEvent::MouseMove;
222 tracker.OnInputEvent(e);
223 EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
224 e.GetTimeStampRounded() +
225 base::TimeDelta::FromMilliseconds(1)));
226 }
227
228 TEST_F(UserInputTrackerTest, IgnoreRepeatEvents) {
229 page_load_metrics::UserInputTracker tracker;
230 FakeInputEvent e;
231 e.modifiers |= blink::WebInputEvent::IsAutoRepeat;
232 tracker.OnInputEvent(e);
233 EXPECT_EQ(base::TimeTicks(), tracker.FindMostRecentUserInputEventBefore(
234 e.GetTimeStampRounded() +
235 base::TimeDelta::FromMilliseconds(1)));
236 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698