15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/debug/trace_event_synthetic_delay.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace base {
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace debug {
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kTargetDurationMs = 100;
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Allow some leeway in timings to make it possible to run these tests with a
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// wall clock time source too.
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kShortDurationMs = 10;
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class TraceEventSyntheticDelayTest : public testing::Test,
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     public TraceEventSyntheticDelayClock {
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TraceEventSyntheticDelayTest() {}
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~TraceEventSyntheticDelayTest() {
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ResetTraceEventSyntheticDelays();
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TraceEventSyntheticDelayClock implementation.
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual base::TimeTicks Now() OVERRIDE {
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AdvanceTime(base::TimeDelta::FromMilliseconds(kShortDurationMs / 10));
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return now_;
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TraceEventSyntheticDelay* ConfigureDelay(const char* name) {
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    TraceEventSyntheticDelay* delay = TraceEventSyntheticDelay::Lookup(name);
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delay->SetClock(this);
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delay->SetTargetDuration(
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::TimeDelta::FromMilliseconds(kTargetDurationMs));
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return delay;
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void AdvanceTime(base::TimeDelta delta) { now_ += delta; }
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int TestFunction() {
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::TimeTicks start = Now();
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    { TRACE_EVENT_SYNTHETIC_DELAY("test.Delay"); }
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return (Now() - start).InMilliseconds();
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int AsyncTestFunctionBegin() {
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::TimeTicks start = Now();
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    { TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("test.AsyncDelay"); }
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return (Now() - start).InMilliseconds();
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int AsyncTestFunctionEnd() {
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::TimeTicks start = Now();
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    { TRACE_EVENT_SYNTHETIC_DELAY_END("test.AsyncDelay"); }
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return (Now() - start).InMilliseconds();
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::TimeTicks now_;
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TraceEventSyntheticDelayTest);
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(TraceEventSyntheticDelayTest, StaticDelay) {
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TraceEventSyntheticDelay* delay = ConfigureDelay("test.Delay");
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delay->SetMode(TraceEventSyntheticDelay::STATIC);
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GE(TestFunction(), kTargetDurationMs);
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(TraceEventSyntheticDelayTest, OneShotDelay) {
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TraceEventSyntheticDelay* delay = ConfigureDelay("test.Delay");
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delay->SetMode(TraceEventSyntheticDelay::ONE_SHOT);
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GE(TestFunction(), kTargetDurationMs);
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LT(TestFunction(), kShortDurationMs);
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delay->SetTargetDuration(
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kTargetDurationMs));
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GE(TestFunction(), kTargetDurationMs);
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(TraceEventSyntheticDelayTest, AlternatingDelay) {
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TraceEventSyntheticDelay* delay = ConfigureDelay("test.Delay");
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delay->SetMode(TraceEventSyntheticDelay::ALTERNATING);
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GE(TestFunction(), kTargetDurationMs);
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LT(TestFunction(), kShortDurationMs);
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GE(TestFunction(), kTargetDurationMs);
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LT(TestFunction(), kShortDurationMs);
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(TraceEventSyntheticDelayTest, AsyncDelay) {
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ConfigureDelay("test.AsyncDelay");
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LT(AsyncTestFunctionBegin(), kShortDurationMs);
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GE(AsyncTestFunctionEnd(), kTargetDurationMs / 2);
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(TraceEventSyntheticDelayTest, AsyncDelayExceeded) {
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ConfigureDelay("test.AsyncDelay");
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LT(AsyncTestFunctionBegin(), kShortDurationMs);
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AdvanceTime(base::TimeDelta::FromMilliseconds(kTargetDurationMs));
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LT(AsyncTestFunctionEnd(), kShortDurationMs);
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(TraceEventSyntheticDelayTest, AsyncDelayNoActivation) {
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ConfigureDelay("test.AsyncDelay");
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LT(AsyncTestFunctionEnd(), kShortDurationMs);
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(TraceEventSyntheticDelayTest, AsyncDelayNested) {
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ConfigureDelay("test.AsyncDelay");
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LT(AsyncTestFunctionBegin(), kShortDurationMs);
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LT(AsyncTestFunctionBegin(), kShortDurationMs);
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LT(AsyncTestFunctionEnd(), kShortDurationMs);
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GE(AsyncTestFunctionEnd(), kTargetDurationMs / 2);
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(TraceEventSyntheticDelayTest, AsyncDelayUnbalanced) {
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ConfigureDelay("test.AsyncDelay");
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LT(AsyncTestFunctionBegin(), kShortDurationMs);
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GE(AsyncTestFunctionEnd(), kTargetDurationMs / 2);
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LT(AsyncTestFunctionEnd(), kShortDurationMs);
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LT(AsyncTestFunctionBegin(), kShortDurationMs);
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GE(AsyncTestFunctionEnd(), kTargetDurationMs / 2);
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(TraceEventSyntheticDelayTest, ResetDelays) {
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ConfigureDelay("test.Delay");
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ResetTraceEventSyntheticDelays();
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LT(TestFunction(), kShortDurationMs);
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(TraceEventSyntheticDelayTest, BeginParallel) {
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TraceEventSyntheticDelay* delay = ConfigureDelay("test.AsyncDelay");
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::TimeTicks end_times[2];
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::TimeTicks start_time = Now();
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delay->BeginParallel(&end_times[0]);
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(end_times[0].is_null());
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delay->BeginParallel(&end_times[1]);
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(end_times[1].is_null());
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delay->EndParallel(end_times[0]);
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GE((Now() - start_time).InMilliseconds(), kTargetDurationMs);
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  start_time = Now();
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delay->EndParallel(end_times[1]);
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LT((Now() - start_time).InMilliseconds(), kShortDurationMs);
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace debug
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace base
157