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