1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <stdint.h>
18 
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 #include <memory>
22 
23 #include "metrics/metrics_library_mock.h"
24 #include "metrics/timer.h"
25 #include "metrics/timer_mock.h"
26 
27 using ::testing::_;
28 using ::testing::Return;
29 
30 namespace chromeos_metrics {
31 
32 namespace {
33 const int64_t kStime1MSec = 1400;
34 const int64_t kEtime1MSec = 3000;
35 const int64_t kDelta1MSec = 1600;
36 
37 const int64_t kStime2MSec = 4200;
38 const int64_t kEtime2MSec = 5000;
39 const int64_t kDelta2MSec = 800;
40 
41 const int64_t kStime3MSec = 6600;
42 const int64_t kEtime3MSec = 6800;
43 const int64_t kDelta3MSec = 200;
44 }  // namespace
45 
46 class TimerTest : public testing::Test {
47  public:
TimerTest()48   TimerTest() : clock_wrapper_mock_(new ClockWrapperMock()) {}
49 
50  protected:
SetUp()51   virtual void SetUp() {
52     EXPECT_EQ(Timer::kTimerStopped, timer_.timer_state_);
53     stime += base::TimeDelta::FromMilliseconds(kStime1MSec);
54     etime += base::TimeDelta::FromMilliseconds(kEtime1MSec);
55     stime2 += base::TimeDelta::FromMilliseconds(kStime2MSec);
56     etime2 += base::TimeDelta::FromMilliseconds(kEtime2MSec);
57     stime3 += base::TimeDelta::FromMilliseconds(kStime3MSec);
58     etime3 += base::TimeDelta::FromMilliseconds(kEtime3MSec);
59   }
60 
TearDown()61   virtual void TearDown() {}
62 
63   Timer timer_;
64   std::unique_ptr<ClockWrapperMock> clock_wrapper_mock_;
65   base::TimeTicks stime, etime, stime2, etime2, stime3, etime3;
66 };
67 
TEST_F(TimerTest,StartStop)68 TEST_F(TimerTest, StartStop) {
69   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
70       .WillOnce(Return(stime))
71       .WillOnce(Return(etime));
72   timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
73   ASSERT_TRUE(timer_.Start());
74   ASSERT_TRUE(timer_.start_time_ == stime);
75   ASSERT_TRUE(timer_.HasStarted());
76   ASSERT_TRUE(timer_.Stop());
77   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(), kDelta1MSec);
78 
79   base::TimeDelta elapsed_time;
80   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
81   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
82             elapsed_time.InMilliseconds());
83 
84   ASSERT_FALSE(timer_.HasStarted());
85 }
86 
TEST_F(TimerTest,ReStart)87 TEST_F(TimerTest, ReStart) {
88   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
89       .WillOnce(Return(stime))
90       .WillOnce(Return(etime));
91   timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
92   timer_.Start();
93   base::TimeTicks buffer = timer_.start_time_;
94   timer_.Start();
95   ASSERT_FALSE(timer_.start_time_ == buffer);
96 }
97 
TEST_F(TimerTest,Reset)98 TEST_F(TimerTest, Reset) {
99   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
100       .WillOnce(Return(stime));
101   timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
102   timer_.Start();
103   ASSERT_TRUE(timer_.Reset());
104   ASSERT_FALSE(timer_.HasStarted());
105 }
106 
TEST_F(TimerTest,SeparatedTimers)107 TEST_F(TimerTest, SeparatedTimers) {
108   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
109       .WillOnce(Return(stime))
110       .WillOnce(Return(etime))
111       .WillOnce(Return(stime2))
112       .WillOnce(Return(etime2));
113   timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
114   ASSERT_TRUE(timer_.Start());
115   ASSERT_TRUE(timer_.Stop());
116   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(), kDelta1MSec);
117   ASSERT_TRUE(timer_.Start());
118   ASSERT_TRUE(timer_.start_time_ == stime2);
119   ASSERT_TRUE(timer_.Stop());
120   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(), kDelta2MSec);
121   ASSERT_FALSE(timer_.HasStarted());
122 
123   base::TimeDelta elapsed_time;
124   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
125   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
126             elapsed_time.InMilliseconds());
127 }
128 
TEST_F(TimerTest,InvalidStop)129 TEST_F(TimerTest, InvalidStop) {
130   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
131       .WillOnce(Return(stime))
132       .WillOnce(Return(etime));
133   timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
134   ASSERT_FALSE(timer_.Stop());
135   // Now we try it again, but after a valid start/stop.
136   timer_.Start();
137   timer_.Stop();
138   base::TimeDelta elapsed_time = timer_.elapsed_time_;
139   ASSERT_FALSE(timer_.Stop());
140   ASSERT_TRUE(elapsed_time == timer_.elapsed_time_);
141 }
142 
TEST_F(TimerTest,InvalidElapsedTime)143 TEST_F(TimerTest, InvalidElapsedTime) {
144   base::TimeDelta elapsed_time;
145   ASSERT_FALSE(timer_.GetElapsedTime(&elapsed_time));
146 }
147 
TEST_F(TimerTest,PauseStartStopResume)148 TEST_F(TimerTest, PauseStartStopResume) {
149   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
150       .WillOnce(Return(stime))
151       .WillOnce(Return(stime2))
152       .WillOnce(Return(etime2))
153       .WillOnce(Return(stime3))
154       .WillOnce(Return(etime3));
155   timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
156   ASSERT_TRUE(timer_.Pause());  // Starts timer paused.
157   ASSERT_TRUE(timer_.start_time_ == stime);
158   ASSERT_TRUE(timer_.HasStarted());
159 
160   ASSERT_TRUE(timer_.Start());  // Restarts timer.
161   ASSERT_TRUE(timer_.start_time_ == stime2);
162   ASSERT_TRUE(timer_.HasStarted());
163 
164   ASSERT_TRUE(timer_.Stop());
165   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(), kDelta2MSec);
166   ASSERT_FALSE(timer_.HasStarted());
167   base::TimeDelta elapsed_time;
168   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
169   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
170             elapsed_time.InMilliseconds());
171 
172   ASSERT_TRUE(timer_.Resume());
173   ASSERT_TRUE(timer_.HasStarted());
174   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
175   ASSERT_EQ(kDelta3MSec, elapsed_time.InMilliseconds());
176 }
177 
TEST_F(TimerTest,ResumeStartStopPause)178 TEST_F(TimerTest, ResumeStartStopPause) {
179   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
180       .WillOnce(Return(stime))
181       .WillOnce(Return(stime2))
182       .WillOnce(Return(etime2))
183       .WillOnce(Return(stime3));
184   timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
185   ASSERT_TRUE(timer_.Resume());
186   ASSERT_TRUE(timer_.start_time_ == stime);
187   ASSERT_TRUE(timer_.HasStarted());
188 
189   ASSERT_TRUE(timer_.Start());
190   ASSERT_TRUE(timer_.start_time_ == stime2);
191   ASSERT_TRUE(timer_.HasStarted());
192 
193   ASSERT_TRUE(timer_.Stop());
194   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(), kDelta2MSec);
195   ASSERT_FALSE(timer_.HasStarted());
196   base::TimeDelta elapsed_time;
197   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
198   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
199             elapsed_time.InMilliseconds());
200 
201   ASSERT_TRUE(timer_.Pause());
202   ASSERT_TRUE(timer_.HasStarted());
203   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
204   ASSERT_EQ(0, elapsed_time.InMilliseconds());
205 }
206 
TEST_F(TimerTest,StartResumeStop)207 TEST_F(TimerTest, StartResumeStop) {
208   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
209       .WillOnce(Return(stime))
210       .WillOnce(Return(etime));
211   timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
212   ASSERT_TRUE(timer_.Start());
213   ASSERT_TRUE(timer_.start_time_ == stime);
214   ASSERT_TRUE(timer_.HasStarted());
215 
216   ASSERT_FALSE(timer_.Resume());
217   ASSERT_TRUE(timer_.start_time_ == stime);
218   ASSERT_TRUE(timer_.HasStarted());
219 
220   ASSERT_TRUE(timer_.Stop());
221   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(), kDelta1MSec);
222   ASSERT_FALSE(timer_.HasStarted());
223   base::TimeDelta elapsed_time;
224   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
225   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
226             elapsed_time.InMilliseconds());
227 }
228 
TEST_F(TimerTest,StartPauseStop)229 TEST_F(TimerTest, StartPauseStop) {
230   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
231       .WillOnce(Return(stime))
232       .WillOnce(Return(etime));
233   timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
234   ASSERT_TRUE(timer_.Start());
235   ASSERT_TRUE(timer_.start_time_ == stime);
236   ASSERT_TRUE(timer_.HasStarted());
237 
238   ASSERT_TRUE(timer_.Pause());
239   ASSERT_TRUE(timer_.HasStarted());
240   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(), kDelta1MSec);
241   base::TimeDelta elapsed_time;
242   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
243   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
244             elapsed_time.InMilliseconds());
245 
246   ASSERT_TRUE(timer_.Stop());
247   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(), kDelta1MSec);
248   ASSERT_FALSE(timer_.HasStarted());
249   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
250   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
251             elapsed_time.InMilliseconds());
252 }
253 
TEST_F(TimerTest,StartPauseResumeStop)254 TEST_F(TimerTest, StartPauseResumeStop) {
255   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
256       .WillOnce(Return(stime))
257       .WillOnce(Return(etime))
258       .WillOnce(Return(stime2))
259       .WillOnce(Return(etime2));
260   timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
261   ASSERT_TRUE(timer_.Start());
262   ASSERT_TRUE(timer_.start_time_ == stime);
263   ASSERT_TRUE(timer_.HasStarted());
264 
265   ASSERT_TRUE(timer_.Pause());
266   ASSERT_TRUE(timer_.HasStarted());
267   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(), kDelta1MSec);
268   base::TimeDelta elapsed_time;
269   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
270   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
271             elapsed_time.InMilliseconds());
272 
273   ASSERT_TRUE(timer_.Resume());
274   ASSERT_TRUE(timer_.HasStarted());
275 
276   ASSERT_TRUE(timer_.Stop());
277   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(), kDelta1MSec + kDelta2MSec);
278   ASSERT_FALSE(timer_.HasStarted());
279   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
280   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
281             elapsed_time.InMilliseconds());
282 }
283 
TEST_F(TimerTest,PauseStop)284 TEST_F(TimerTest, PauseStop) {
285   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
286       .WillOnce(Return(stime));
287   timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
288   ASSERT_TRUE(timer_.Pause());
289   ASSERT_TRUE(timer_.start_time_ == stime);
290   ASSERT_TRUE(timer_.HasStarted());
291   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(), 0);
292 
293   ASSERT_TRUE(timer_.Stop());
294   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(), 0);
295   ASSERT_FALSE(timer_.HasStarted());
296   base::TimeDelta elapsed_time;
297   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
298   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
299             elapsed_time.InMilliseconds());
300 }
301 
TEST_F(TimerTest,PauseResumeStop)302 TEST_F(TimerTest, PauseResumeStop) {
303   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
304       .WillOnce(Return(stime))
305       .WillOnce(Return(stime2))
306       .WillOnce(Return(etime2));
307   timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
308   ASSERT_TRUE(timer_.Pause());
309   ASSERT_TRUE(timer_.start_time_ == stime);
310   ASSERT_TRUE(timer_.HasStarted());
311 
312   ASSERT_TRUE(timer_.Resume());
313   ASSERT_TRUE(timer_.HasStarted());
314 
315   ASSERT_TRUE(timer_.Stop());
316   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(), kDelta2MSec);
317   ASSERT_FALSE(timer_.HasStarted());
318   base::TimeDelta elapsed_time;
319   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
320   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
321             elapsed_time.InMilliseconds());
322 }
323 
TEST_F(TimerTest,StartPauseResumePauseStop)324 TEST_F(TimerTest, StartPauseResumePauseStop) {
325   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
326       .WillOnce(Return(stime))
327       .WillOnce(Return(etime))
328       .WillOnce(Return(stime2))
329       .WillOnce(Return(stime3))
330       .WillOnce(Return(etime3));
331   timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
332   ASSERT_TRUE(timer_.Start());
333   ASSERT_TRUE(timer_.start_time_ == stime);
334   ASSERT_TRUE(timer_.HasStarted());
335 
336   ASSERT_TRUE(timer_.Pause());
337   ASSERT_TRUE(timer_.HasStarted());
338   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(), kDelta1MSec);
339   base::TimeDelta elapsed_time;
340   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
341   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
342             elapsed_time.InMilliseconds());
343 
344   ASSERT_TRUE(timer_.Resume());
345   ASSERT_TRUE(timer_.HasStarted());
346   // Make sure GetElapsedTime works while we're running.
347   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
348   ASSERT_EQ(kDelta1MSec + kStime3MSec - kStime2MSec,
349             elapsed_time.InMilliseconds());
350 
351   ASSERT_TRUE(timer_.Pause());
352   ASSERT_TRUE(timer_.HasStarted());
353   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
354             kDelta1MSec + kEtime3MSec - kStime2MSec);
355   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
356   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
357             elapsed_time.InMilliseconds());
358 
359   ASSERT_TRUE(timer_.Stop());
360   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
361             kDelta1MSec + kEtime3MSec - kStime2MSec);
362   ASSERT_FALSE(timer_.HasStarted());
363   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
364   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
365             elapsed_time.InMilliseconds());
366 }
367 
TEST_F(TimerTest,StartPauseResumePauseResumeStop)368 TEST_F(TimerTest, StartPauseResumePauseResumeStop) {
369   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
370       .WillOnce(Return(stime))
371       .WillOnce(Return(etime))
372       .WillOnce(Return(stime2))
373       .WillOnce(Return(etime2))
374       .WillOnce(Return(stime3))
375       .WillOnce(Return(etime3));
376   timer_.clock_wrapper_.reset(clock_wrapper_mock_.release());
377   ASSERT_TRUE(timer_.Start());
378   ASSERT_TRUE(timer_.start_time_ == stime);
379   ASSERT_TRUE(timer_.HasStarted());
380 
381   ASSERT_TRUE(timer_.Pause());
382   ASSERT_TRUE(timer_.HasStarted());
383   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(), kDelta1MSec);
384   base::TimeDelta elapsed_time;
385   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
386   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
387             elapsed_time.InMilliseconds());
388 
389   ASSERT_TRUE(timer_.Resume());
390   ASSERT_TRUE(timer_.HasStarted());
391 
392   ASSERT_TRUE(timer_.Pause());
393   ASSERT_TRUE(timer_.HasStarted());
394   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(), kDelta1MSec + kDelta2MSec);
395   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
396   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
397             elapsed_time.InMilliseconds());
398 
399   ASSERT_TRUE(timer_.Resume());
400   ASSERT_TRUE(timer_.HasStarted());
401 
402   ASSERT_TRUE(timer_.Stop());
403   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
404             kDelta1MSec + kDelta2MSec + kDelta3MSec);
405   ASSERT_FALSE(timer_.HasStarted());
406   ASSERT_TRUE(timer_.GetElapsedTime(&elapsed_time));
407   ASSERT_EQ(timer_.elapsed_time_.InMilliseconds(),
408             elapsed_time.InMilliseconds());
409 }
410 
411 static const char kMetricName[] = "test-timer";
412 static const int kMinSample = 0;
413 static const int kMaxSample = 120 * 1E6;
414 static const int kNumBuckets = 50;
415 
416 class TimerReporterTest : public testing::Test {
417  public:
TimerReporterTest()418   TimerReporterTest() : timer_reporter_(kMetricName, kMinSample, kMaxSample,
419                                         kNumBuckets),
420                         clock_wrapper_mock_(new ClockWrapperMock()) {}
421 
422  protected:
SetUp()423   virtual void SetUp() {
424     timer_reporter_.set_metrics_lib(&lib_);
425     EXPECT_EQ(timer_reporter_.histogram_name_, kMetricName);
426     EXPECT_EQ(timer_reporter_.min_, kMinSample);
427     EXPECT_EQ(timer_reporter_.max_, kMaxSample);
428     EXPECT_EQ(timer_reporter_.num_buckets_, kNumBuckets);
429     stime += base::TimeDelta::FromMilliseconds(kStime1MSec);
430     etime += base::TimeDelta::FromMilliseconds(kEtime1MSec);
431   }
432 
TearDown()433   virtual void TearDown() {
434     timer_reporter_.set_metrics_lib(nullptr);
435   }
436 
437   TimerReporter timer_reporter_;
438   MetricsLibraryMock lib_;
439   std::unique_ptr<ClockWrapperMock> clock_wrapper_mock_;
440   base::TimeTicks stime, etime;
441 };
442 
TEST_F(TimerReporterTest,StartStopReport)443 TEST_F(TimerReporterTest, StartStopReport) {
444   EXPECT_CALL(*clock_wrapper_mock_, GetCurrentTime())
445       .WillOnce(Return(stime))
446       .WillOnce(Return(etime));
447   timer_reporter_.clock_wrapper_.reset(clock_wrapper_mock_.release());
448   EXPECT_CALL(lib_, SendToUMA(kMetricName, kDelta1MSec, kMinSample, kMaxSample,
449                               kNumBuckets)).WillOnce(Return(true));
450   ASSERT_TRUE(timer_reporter_.Start());
451   ASSERT_TRUE(timer_reporter_.Stop());
452   ASSERT_TRUE(timer_reporter_.ReportMilliseconds());
453 }
454 
TEST_F(TimerReporterTest,InvalidReport)455 TEST_F(TimerReporterTest, InvalidReport) {
456   ASSERT_FALSE(timer_reporter_.ReportMilliseconds());
457 }
458 
459 }  // namespace chromeos_metrics
460 
main(int argc,char ** argv)461 int main(int argc, char **argv) {
462   testing::InitGoogleTest(&argc, argv);
463   return RUN_ALL_TESTS();
464 }
465