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 27using ::testing::_; 28using ::testing::Return; 29 30namespace chromeos_metrics { 31 32namespace { 33const int64_t kStime1MSec = 1400; 34const int64_t kEtime1MSec = 3000; 35const int64_t kDelta1MSec = 1600; 36 37const int64_t kStime2MSec = 4200; 38const int64_t kEtime2MSec = 5000; 39const int64_t kDelta2MSec = 800; 40 41const int64_t kStime3MSec = 6600; 42const int64_t kEtime3MSec = 6800; 43const int64_t kDelta3MSec = 200; 44} // namespace 45 46class TimerTest : public testing::Test { 47 public: 48 TimerTest() : clock_wrapper_mock_(new ClockWrapperMock()) {} 49 50 protected: 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 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 68TEST_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 87TEST_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 98TEST_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 107TEST_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 129TEST_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 143TEST_F(TimerTest, InvalidElapsedTime) { 144 base::TimeDelta elapsed_time; 145 ASSERT_FALSE(timer_.GetElapsedTime(&elapsed_time)); 146} 147 148TEST_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 178TEST_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 207TEST_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 229TEST_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 254TEST_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 284TEST_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 302TEST_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 324TEST_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 368TEST_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 411static const char kMetricName[] = "test-timer"; 412static const int kMinSample = 0; 413static const int kMaxSample = 120 * 1E6; 414static const int kNumBuckets = 50; 415 416class TimerReporterTest : public testing::Test { 417 public: 418 TimerReporterTest() : timer_reporter_(kMetricName, kMinSample, kMaxSample, 419 kNumBuckets), 420 clock_wrapper_mock_(new ClockWrapperMock()) {} 421 422 protected: 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 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 443TEST_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 455TEST_F(TimerReporterTest, InvalidReport) { 456 ASSERT_FALSE(timer_reporter_.ReportMilliseconds()); 457} 458 459} // namespace chromeos_metrics 460 461int main(int argc, char **argv) { 462 testing::InitGoogleTest(&argc, argv); 463 return RUN_ALL_TESTS(); 464} 465