1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
base / profiler / periodic_sampling_scheduler_unittest.cc [blame]
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/profiler/periodic_sampling_scheduler.h"
#include "base/test/bind.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
namespace {
class TestScheduler : public PeriodicSamplingScheduler {
public:
TestScheduler(TimeDelta sampling_duration,
double fraction_of_execution_time_to_sample)
: PeriodicSamplingScheduler(sampling_duration,
fraction_of_execution_time_to_sample,
kStartTime) {
tick_clock_.SetNowTicks(kStartTime);
}
TestScheduler(const TestScheduler&) = delete;
TestScheduler& operator=(const TestScheduler&) = delete;
double RandDouble() const override { return rand_double_value_; }
TimeTicks Now() const override { return tick_clock_.NowTicks(); }
void SetRandDouble(double value) { rand_double_value_ = value; }
SimpleTestTickClock& tick_clock() { return tick_clock_; }
private:
static constexpr TimeTicks kStartTime = TimeTicks();
SimpleTestTickClock tick_clock_;
double rand_double_value_ = 0.0;
};
constexpr TimeTicks TestScheduler::kStartTime;
TEST(PeriodicSamplingSchedulerTest, ScheduleCollections) {
const TimeDelta sampling_duration = Seconds(30);
const double fraction_of_execution_time_to_sample = 0.01;
const TimeDelta expected_period =
sampling_duration / fraction_of_execution_time_to_sample;
TestScheduler scheduler(sampling_duration,
fraction_of_execution_time_to_sample);
// The first collection should be exactly at the start time, since the random
// value is 0.0.
scheduler.SetRandDouble(0.0);
EXPECT_EQ(Seconds(0), scheduler.GetTimeToNextCollection());
// With a random value of 1.0 the second collection should be at the end of
// the second period.
scheduler.SetRandDouble(1.0);
EXPECT_EQ(2 * expected_period - sampling_duration,
scheduler.GetTimeToNextCollection());
// With a random value of 0.25 the second collection should be a quarter into
// the third period exclusive of the sampling duration.
scheduler.SetRandDouble(0.25);
EXPECT_EQ(2 * expected_period + 0.25 * (expected_period - sampling_duration),
scheduler.GetTimeToNextCollection());
}
TEST(PeriodicSamplingSchedulerTest, ScheduleWithJumpInTimeTicks) {
const TimeDelta sampling_duration = Seconds(30);
const double fraction_of_execution_time_to_sample = 0.01;
const TimeDelta expected_period =
sampling_duration / fraction_of_execution_time_to_sample;
TestScheduler scheduler(sampling_duration,
fraction_of_execution_time_to_sample);
// The first collection should be exactly at the start time, since the random
// value is 0.0.
scheduler.SetRandDouble(0.0);
EXPECT_EQ(Seconds(0), scheduler.GetTimeToNextCollection());
// Simulate a non-continuous jump in the current TimeTicks such that the next
// period would start before the current time. In this case the
// period start should be reset to the current time, and the next collection
// chosen within that period.
scheduler.tick_clock().Advance(expected_period + Seconds(1));
scheduler.SetRandDouble(0.5);
EXPECT_EQ(0.5 * (expected_period - sampling_duration),
scheduler.GetTimeToNextCollection());
}
} // namespace
} // namespace base