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