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: 26 TraceEventSyntheticDelayTest() {} 27 ~TraceEventSyntheticDelayTest() override { ResetTraceEventSyntheticDelays(); } 28 29 // TraceEventSyntheticDelayClock implementation. 30 base::TimeTicks Now() override { 31 AdvanceTime(base::TimeDelta::FromMilliseconds(kShortDurationMs / 10)); 32 return now_; 33 } 34 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 43 void AdvanceTime(base::TimeDelta delta) { now_ += delta; } 44 45 int64_t TestFunction() { 46 base::TimeTicks start = Now(); 47 { TRACE_EVENT_SYNTHETIC_DELAY("test.Delay"); } 48 return (Now() - start).InMilliseconds(); 49 } 50 51 int64_t AsyncTestFunctionBegin() { 52 base::TimeTicks start = Now(); 53 { TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("test.AsyncDelay"); } 54 return (Now() - start).InMilliseconds(); 55 } 56 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 69 TEST_F(TraceEventSyntheticDelayTest, StaticDelay) { 70 TraceEventSyntheticDelay* delay = ConfigureDelay("test.Delay"); 71 delay->SetMode(TraceEventSyntheticDelay::STATIC); 72 EXPECT_GE(TestFunction(), kTargetDurationMs); 73 } 74 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 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 95 TEST_F(TraceEventSyntheticDelayTest, AsyncDelay) { 96 ConfigureDelay("test.AsyncDelay"); 97 EXPECT_LT(AsyncTestFunctionBegin(), kShortDurationMs); 98 EXPECT_GE(AsyncTestFunctionEnd(), kTargetDurationMs / 2); 99 } 100 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 108 TEST_F(TraceEventSyntheticDelayTest, AsyncDelayNoActivation) { 109 ConfigureDelay("test.AsyncDelay"); 110 EXPECT_LT(AsyncTestFunctionEnd(), kShortDurationMs); 111 } 112 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 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 131 TEST_F(TraceEventSyntheticDelayTest, ResetDelays) { 132 ConfigureDelay("test.Delay"); 133 ResetTraceEventSyntheticDelays(); 134 EXPECT_LT(TestFunction(), kShortDurationMs); 135 } 136 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