1 // Copyright 2019 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "absl/base/internal/periodic_sampler.h"
16
17 #include <thread> // NOLINT(build/c++11)
18
19 #include "gmock/gmock.h"
20 #include "gtest/gtest.h"
21 #include "absl/base/attributes.h"
22 #include "absl/base/macros.h"
23
24 namespace absl {
25 ABSL_NAMESPACE_BEGIN
26 namespace base_internal {
27 namespace {
28
29 using testing::Eq;
30 using testing::Return;
31 using testing::StrictMock;
32
33 class MockPeriodicSampler : public PeriodicSamplerBase {
34 public:
35 virtual ~MockPeriodicSampler() = default;
36
37 MOCK_METHOD(int, period, (), (const, noexcept));
38 MOCK_METHOD(int64_t, GetExponentialBiased, (int), (noexcept));
39 };
40
TEST(PeriodicSamplerBaseTest,Sample)41 TEST(PeriodicSamplerBaseTest, Sample) {
42 StrictMock<MockPeriodicSampler> sampler;
43
44 EXPECT_CALL(sampler, period()).Times(3).WillRepeatedly(Return(16));
45 EXPECT_CALL(sampler, GetExponentialBiased(16))
46 .WillOnce(Return(2))
47 .WillOnce(Return(3))
48 .WillOnce(Return(4));
49
50 EXPECT_FALSE(sampler.Sample());
51 EXPECT_TRUE(sampler.Sample());
52
53 EXPECT_FALSE(sampler.Sample());
54 EXPECT_FALSE(sampler.Sample());
55 EXPECT_TRUE(sampler.Sample());
56
57 EXPECT_FALSE(sampler.Sample());
58 EXPECT_FALSE(sampler.Sample());
59 EXPECT_FALSE(sampler.Sample());
60 }
61
TEST(PeriodicSamplerBaseTest,ImmediatelySample)62 TEST(PeriodicSamplerBaseTest, ImmediatelySample) {
63 StrictMock<MockPeriodicSampler> sampler;
64
65 EXPECT_CALL(sampler, period()).Times(2).WillRepeatedly(Return(16));
66 EXPECT_CALL(sampler, GetExponentialBiased(16))
67 .WillOnce(Return(1))
68 .WillOnce(Return(2))
69 .WillOnce(Return(3));
70
71 EXPECT_TRUE(sampler.Sample());
72
73 EXPECT_FALSE(sampler.Sample());
74 EXPECT_TRUE(sampler.Sample());
75
76 EXPECT_FALSE(sampler.Sample());
77 EXPECT_FALSE(sampler.Sample());
78 }
79
TEST(PeriodicSamplerBaseTest,Disabled)80 TEST(PeriodicSamplerBaseTest, Disabled) {
81 StrictMock<MockPeriodicSampler> sampler;
82
83 EXPECT_CALL(sampler, period()).Times(3).WillRepeatedly(Return(0));
84
85 EXPECT_FALSE(sampler.Sample());
86 EXPECT_FALSE(sampler.Sample());
87 EXPECT_FALSE(sampler.Sample());
88 }
89
TEST(PeriodicSamplerBaseTest,AlwaysOn)90 TEST(PeriodicSamplerBaseTest, AlwaysOn) {
91 StrictMock<MockPeriodicSampler> sampler;
92
93 EXPECT_CALL(sampler, period()).Times(3).WillRepeatedly(Return(1));
94
95 EXPECT_TRUE(sampler.Sample());
96 EXPECT_TRUE(sampler.Sample());
97 EXPECT_TRUE(sampler.Sample());
98 }
99
TEST(PeriodicSamplerBaseTest,Disable)100 TEST(PeriodicSamplerBaseTest, Disable) {
101 StrictMock<MockPeriodicSampler> sampler;
102
103 EXPECT_CALL(sampler, period()).WillOnce(Return(16));
104 EXPECT_CALL(sampler, GetExponentialBiased(16)).WillOnce(Return(3));
105 EXPECT_FALSE(sampler.Sample());
106 EXPECT_FALSE(sampler.Sample());
107
108 EXPECT_CALL(sampler, period()).Times(2).WillRepeatedly(Return(0));
109
110 EXPECT_FALSE(sampler.Sample());
111 EXPECT_FALSE(sampler.Sample());
112 }
113
TEST(PeriodicSamplerBaseTest,Enable)114 TEST(PeriodicSamplerBaseTest, Enable) {
115 StrictMock<MockPeriodicSampler> sampler;
116
117 EXPECT_CALL(sampler, period()).WillOnce(Return(0));
118 EXPECT_FALSE(sampler.Sample());
119
120 EXPECT_CALL(sampler, period()).Times(2).WillRepeatedly(Return(16));
121 EXPECT_CALL(sampler, GetExponentialBiased(16))
122 .Times(2)
123 .WillRepeatedly(Return(3));
124
125 EXPECT_FALSE(sampler.Sample());
126 EXPECT_FALSE(sampler.Sample());
127 EXPECT_TRUE(sampler.Sample());
128
129 EXPECT_FALSE(sampler.Sample());
130 EXPECT_FALSE(sampler.Sample());
131 }
132
TEST(PeriodicSamplerTest,ConstructConstInit)133 TEST(PeriodicSamplerTest, ConstructConstInit) {
134 struct Tag {};
135 ABSL_CONST_INIT static PeriodicSampler<Tag> sampler;
136 (void)sampler;
137 }
138
TEST(PeriodicSamplerTest,DefaultPeriod0)139 TEST(PeriodicSamplerTest, DefaultPeriod0) {
140 struct Tag {};
141 PeriodicSampler<Tag> sampler;
142 EXPECT_THAT(sampler.period(), Eq(0));
143 }
144
TEST(PeriodicSamplerTest,DefaultPeriod)145 TEST(PeriodicSamplerTest, DefaultPeriod) {
146 struct Tag {};
147 PeriodicSampler<Tag, 100> sampler;
148 EXPECT_THAT(sampler.period(), Eq(100));
149 }
150
TEST(PeriodicSamplerTest,SetGlobalPeriod)151 TEST(PeriodicSamplerTest, SetGlobalPeriod) {
152 struct Tag1 {};
153 struct Tag2 {};
154 PeriodicSampler<Tag1, 25> sampler1;
155 PeriodicSampler<Tag2, 50> sampler2;
156
157 EXPECT_THAT(sampler1.period(), Eq(25));
158 EXPECT_THAT(sampler2.period(), Eq(50));
159
160 std::thread thread([] {
161 PeriodicSampler<Tag1, 25> sampler1;
162 PeriodicSampler<Tag2, 50> sampler2;
163 EXPECT_THAT(sampler1.period(), Eq(25));
164 EXPECT_THAT(sampler2.period(), Eq(50));
165 sampler1.SetGlobalPeriod(10);
166 sampler2.SetGlobalPeriod(20);
167 });
168 thread.join();
169
170 EXPECT_THAT(sampler1.period(), Eq(10));
171 EXPECT_THAT(sampler2.period(), Eq(20));
172 }
173
174 } // namespace
175 } // namespace base_internal
176 ABSL_NAMESPACE_END
177 } // namespace absl
178