1// Copyright 2014 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 "base/debug/trace_event_synthetic_delay.h"
6
7#include "testing/gtest/include/gtest/gtest.h"
8
9namespace base {
10namespace debug {
11namespace {
12
13const int kTargetDurationMs = 100;
14// Allow some leeway in timings to make it possible to run these tests with a
15// wall clock time source too.
16const int kShortDurationMs = 10;
17
18}  // namespace
19
20class TraceEventSyntheticDelayTest : public testing::Test,
21                                     public TraceEventSyntheticDelayClock {
22 public:
23  TraceEventSyntheticDelayTest() {}
24  virtual ~TraceEventSyntheticDelayTest() {
25    ResetTraceEventSyntheticDelays();
26  }
27
28  // TraceEventSyntheticDelayClock implementation.
29  virtual base::TimeTicks Now() OVERRIDE {
30    AdvanceTime(base::TimeDelta::FromMilliseconds(kShortDurationMs / 10));
31    return now_;
32  }
33
34  TraceEventSyntheticDelay* ConfigureDelay(const char* name) {
35    TraceEventSyntheticDelay* delay = TraceEventSyntheticDelay::Lookup(name);
36    delay->SetClock(this);
37    delay->SetTargetDuration(
38        base::TimeDelta::FromMilliseconds(kTargetDurationMs));
39    return delay;
40  }
41
42  void AdvanceTime(base::TimeDelta delta) { now_ += delta; }
43
44  int TestFunction() {
45    base::TimeTicks start = Now();
46    { TRACE_EVENT_SYNTHETIC_DELAY("test.Delay"); }
47    return (Now() - start).InMilliseconds();
48  }
49
50  int AsyncTestFunctionBegin() {
51    base::TimeTicks start = Now();
52    { TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("test.AsyncDelay"); }
53    return (Now() - start).InMilliseconds();
54  }
55
56  int AsyncTestFunctionEnd() {
57    base::TimeTicks start = Now();
58    { TRACE_EVENT_SYNTHETIC_DELAY_END("test.AsyncDelay"); }
59    return (Now() - start).InMilliseconds();
60  }
61
62 private:
63  base::TimeTicks now_;
64
65  DISALLOW_COPY_AND_ASSIGN(TraceEventSyntheticDelayTest);
66};
67
68TEST_F(TraceEventSyntheticDelayTest, StaticDelay) {
69  TraceEventSyntheticDelay* delay = ConfigureDelay("test.Delay");
70  delay->SetMode(TraceEventSyntheticDelay::STATIC);
71  EXPECT_GE(TestFunction(), kTargetDurationMs);
72}
73
74TEST_F(TraceEventSyntheticDelayTest, OneShotDelay) {
75  TraceEventSyntheticDelay* delay = ConfigureDelay("test.Delay");
76  delay->SetMode(TraceEventSyntheticDelay::ONE_SHOT);
77  EXPECT_GE(TestFunction(), kTargetDurationMs);
78  EXPECT_LT(TestFunction(), kShortDurationMs);
79
80  delay->SetTargetDuration(
81      base::TimeDelta::FromMilliseconds(kTargetDurationMs));
82  EXPECT_GE(TestFunction(), kTargetDurationMs);
83}
84
85TEST_F(TraceEventSyntheticDelayTest, AlternatingDelay) {
86  TraceEventSyntheticDelay* delay = ConfigureDelay("test.Delay");
87  delay->SetMode(TraceEventSyntheticDelay::ALTERNATING);
88  EXPECT_GE(TestFunction(), kTargetDurationMs);
89  EXPECT_LT(TestFunction(), kShortDurationMs);
90  EXPECT_GE(TestFunction(), kTargetDurationMs);
91  EXPECT_LT(TestFunction(), kShortDurationMs);
92}
93
94TEST_F(TraceEventSyntheticDelayTest, AsyncDelay) {
95  ConfigureDelay("test.AsyncDelay");
96  EXPECT_LT(AsyncTestFunctionBegin(), kShortDurationMs);
97  EXPECT_GE(AsyncTestFunctionEnd(), kTargetDurationMs / 2);
98}
99
100TEST_F(TraceEventSyntheticDelayTest, AsyncDelayExceeded) {
101  ConfigureDelay("test.AsyncDelay");
102  EXPECT_LT(AsyncTestFunctionBegin(), kShortDurationMs);
103  AdvanceTime(base::TimeDelta::FromMilliseconds(kTargetDurationMs));
104  EXPECT_LT(AsyncTestFunctionEnd(), kShortDurationMs);
105}
106
107TEST_F(TraceEventSyntheticDelayTest, AsyncDelayNoActivation) {
108  ConfigureDelay("test.AsyncDelay");
109  EXPECT_LT(AsyncTestFunctionEnd(), kShortDurationMs);
110}
111
112TEST_F(TraceEventSyntheticDelayTest, AsyncDelayNested) {
113  ConfigureDelay("test.AsyncDelay");
114  EXPECT_LT(AsyncTestFunctionBegin(), kShortDurationMs);
115  EXPECT_LT(AsyncTestFunctionBegin(), kShortDurationMs);
116  EXPECT_LT(AsyncTestFunctionEnd(), kShortDurationMs);
117  EXPECT_GE(AsyncTestFunctionEnd(), kTargetDurationMs / 2);
118}
119
120TEST_F(TraceEventSyntheticDelayTest, AsyncDelayUnbalanced) {
121  ConfigureDelay("test.AsyncDelay");
122  EXPECT_LT(AsyncTestFunctionBegin(), kShortDurationMs);
123  EXPECT_GE(AsyncTestFunctionEnd(), kTargetDurationMs / 2);
124  EXPECT_LT(AsyncTestFunctionEnd(), kShortDurationMs);
125
126  EXPECT_LT(AsyncTestFunctionBegin(), kShortDurationMs);
127  EXPECT_GE(AsyncTestFunctionEnd(), kTargetDurationMs / 2);
128}
129
130TEST_F(TraceEventSyntheticDelayTest, ResetDelays) {
131  ConfigureDelay("test.Delay");
132  ResetTraceEventSyntheticDelays();
133  EXPECT_LT(TestFunction(), kShortDurationMs);
134}
135
136TEST_F(TraceEventSyntheticDelayTest, BeginParallel) {
137  TraceEventSyntheticDelay* delay = ConfigureDelay("test.AsyncDelay");
138  base::TimeTicks end_times[2];
139  base::TimeTicks start_time = Now();
140
141  delay->BeginParallel(&end_times[0]);
142  EXPECT_FALSE(end_times[0].is_null());
143
144  delay->BeginParallel(&end_times[1]);
145  EXPECT_FALSE(end_times[1].is_null());
146
147  delay->EndParallel(end_times[0]);
148  EXPECT_GE((Now() - start_time).InMilliseconds(), kTargetDurationMs);
149
150  start_time = Now();
151  delay->EndParallel(end_times[1]);
152  EXPECT_LT((Now() - start_time).InMilliseconds(), kShortDurationMs);
153}
154
155}  // namespace debug
156}  // namespace base
157