sat_counter.test.cc (13962:9c1c64414fb7) sat_counter.test.cc (14210:8f7626532f4d)
1/*
2 * Copyright (c) 2019 Inria
3 * All rights reserved
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Daniel Carvalho
29 */
30
31#include <gtest/gtest.h>
32
33#include <utility>
34
35#include "base/sat_counter.hh"
36
37/**
38 * Test if the maximum value is indeed the maximum value reachable.
39 */
40TEST(SatCounterTest, MaximumValue)
41{
42 const unsigned bits = 3;
43 const unsigned max_value = (1 << bits) - 1;
44 SatCounter counter(bits);
45
46 for (int i = 0; i < 2*max_value; i++) {
47 counter++;
48 }
49
50 ASSERT_EQ(counter, max_value);
51}
52
53/**
54 * Test if the minimum value is indeed the mimimum value reachable.
55 */
56TEST(SatCounterTest, MinimumValue)
57{
58 const unsigned bits = 3;
59 SatCounter counter(bits);
60
61 for (int i = 0; i < 2; i++) {
62 counter--;
63 }
64
65 ASSERT_EQ(counter, 0);
66}
67
68/**
69 * Test initializing the counter with a value, updating it and then resetting.
70 */
71TEST(SatCounterTest, InitialValue)
72{
73 const unsigned bits = 3;
74 const unsigned initial_value = 4;
75 SatCounter counter(bits, initial_value);
76 ASSERT_EQ(counter, initial_value);
77 counter++;
78 counter.reset();
79 ASSERT_EQ(counter, initial_value);
80}
81
82/**
83 * Test calculating saturation percentile.
84 */
85TEST(SatCounterTest, SaturationPercentile)
86{
87 const unsigned bits = 3;
88 const unsigned max_value = (1 << bits) - 1;
89 SatCounter counter(bits);
90
91 ASSERT_FALSE(counter.isSaturated());
92 for (double value = 0.0; value <= max_value; value++, counter++) {
93 const double saturation = value / max_value;
94 ASSERT_DOUBLE_EQ(counter.calcSaturation(), saturation);
95 }
96 ASSERT_TRUE(counter.isSaturated());
97}
98
99/**
1/*
2 * Copyright (c) 2019 Inria
3 * All rights reserved
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Daniel Carvalho
29 */
30
31#include <gtest/gtest.h>
32
33#include <utility>
34
35#include "base/sat_counter.hh"
36
37/**
38 * Test if the maximum value is indeed the maximum value reachable.
39 */
40TEST(SatCounterTest, MaximumValue)
41{
42 const unsigned bits = 3;
43 const unsigned max_value = (1 << bits) - 1;
44 SatCounter counter(bits);
45
46 for (int i = 0; i < 2*max_value; i++) {
47 counter++;
48 }
49
50 ASSERT_EQ(counter, max_value);
51}
52
53/**
54 * Test if the minimum value is indeed the mimimum value reachable.
55 */
56TEST(SatCounterTest, MinimumValue)
57{
58 const unsigned bits = 3;
59 SatCounter counter(bits);
60
61 for (int i = 0; i < 2; i++) {
62 counter--;
63 }
64
65 ASSERT_EQ(counter, 0);
66}
67
68/**
69 * Test initializing the counter with a value, updating it and then resetting.
70 */
71TEST(SatCounterTest, InitialValue)
72{
73 const unsigned bits = 3;
74 const unsigned initial_value = 4;
75 SatCounter counter(bits, initial_value);
76 ASSERT_EQ(counter, initial_value);
77 counter++;
78 counter.reset();
79 ASSERT_EQ(counter, initial_value);
80}
81
82/**
83 * Test calculating saturation percentile.
84 */
85TEST(SatCounterTest, SaturationPercentile)
86{
87 const unsigned bits = 3;
88 const unsigned max_value = (1 << bits) - 1;
89 SatCounter counter(bits);
90
91 ASSERT_FALSE(counter.isSaturated());
92 for (double value = 0.0; value <= max_value; value++, counter++) {
93 const double saturation = value / max_value;
94 ASSERT_DOUBLE_EQ(counter.calcSaturation(), saturation);
95 }
96 ASSERT_TRUE(counter.isSaturated());
97}
98
99/**
100 * Test abrupt saturation.
101 */
102TEST(SatCounterTest, Saturate)
103{
104 const unsigned bits = 3;
105 const unsigned max_value = (1 << bits) - 1;
106 SatCounter counter(bits);
107 counter++;
108 ASSERT_FALSE(counter.isSaturated());
109
110 // Make sure the value added is what was missing to saturate
111 const unsigned diff = counter.saturate();
112 ASSERT_EQ(diff, max_value - 1);
113 ASSERT_TRUE(counter.isSaturated());
114}
115
116/**
100 * Test back and forth against an int.
101 */
102TEST(SatCounterTest, IntComparison)
103{
104 const unsigned bits = 3;
105 SatCounter counter(bits);
106 int value = 0;
107
108 ASSERT_EQ(counter++, value++);
109 ASSERT_EQ(counter++, value++);
110 ASSERT_EQ(counter--, value--);
111 ASSERT_EQ(counter++, value++);
112 ASSERT_EQ(counter++, value++);
113 ASSERT_EQ(counter--, value--);
114 ASSERT_EQ(counter++, value++);
115 ASSERT_EQ(counter--, value--);
116 ASSERT_EQ(counter--, value--);
117 ASSERT_EQ(counter++, value++);
118 ASSERT_EQ(counter--, value--);
119 ASSERT_EQ(counter--, value--);
120 ASSERT_EQ(counter, 0);
121}
122
123/**
124 * Test shift operators.
125 */
126TEST(SatCounterTest, Shift)
127{
128 const unsigned bits = 3;
129 const unsigned max_value = (1 << bits) - 1;
130 const unsigned initial_value = 1;
131 SatCounter counter(bits, initial_value);
132 SatCounter other(bits, initial_value);
133 // The saturated shift value is just enough to saturate, since greater
134 // values could generate undefined behavior
135 SatCounter saturated_counter(bits, bits);
136 int value = initial_value;
137
138 // Test random shifts
139 counter <<= 2;
140 value <<= 2;
141 ASSERT_EQ(counter, value);
142 counter >>= 1;
143 value >>= 1;
144 ASSERT_EQ(counter, value);
145
146 // Test saturation
147 counter <<= bits;
148 ASSERT_EQ(counter, max_value);
149
150 // Test zeroing
151 counter >>= bits;
152 ASSERT_EQ(counter, 0);
153
154 // Test saturation against other saturating counter
155 counter.reset();
156 value = initial_value;
157 counter <<= other;
158 value <<= other;
159 ASSERT_EQ(counter, value);
160 counter <<= saturated_counter;
161 value = max_value;
162 ASSERT_EQ(counter, max_value);
163
164 // Test zeroing against other saturating counter
165 counter >>= other;
166 value >>= other;
167 ASSERT_EQ(counter, value);
168 counter >>= saturated_counter;
169 ASSERT_EQ(counter, 0);
170}
171
172/**
173 * Test both pre and post operators.
174 */
175TEST(SatCounterTest, PrePostOperators)
176{
177 const unsigned bits = 3;
178 const unsigned max_value = (1 << bits) - 1;
179 SatCounter counter_pre(bits);
180 SatCounter counter_post(bits);
181
182 for (int i = 0; i < 2*max_value; i++) {
183 counter_post++;
184 SatCounter value_pre = ++counter_pre;
185 ASSERT_EQ(counter_post, value_pre);
186 }
187
188 ASSERT_EQ(counter_pre, max_value);
189 ASSERT_EQ(counter_post, max_value);
190
191 for (int i = 0; i < 2*max_value; i++) {
192 counter_post--;
193 SatCounter value_pre = --counter_pre;
194 ASSERT_EQ(counter_post, value_pre);
195 }
196
197 ASSERT_EQ(counter_pre, 0);
198 ASSERT_EQ(counter_post, 0);
199}
200
201/**
202 * Test copy and move for both constructor and assignment.
203 */
204TEST(SatCounterTest, CopyMove)
205{
206 const unsigned bits = 3;
207 const unsigned max_value = (1 << bits) - 1;
208 const unsigned initial_value = 1;
209 SatCounter counter(bits, initial_value);
210 SatCounter deep_copy(1);
211 SatCounter counter_copy(2);
212
213 // Increase counter value so that we can check if the inner counter is
214 // being copied
215 counter++;
216
217 // Copy counter using both the copy constructor and the copy assignment
218 SatCounter counter_copy_constructor(counter);
219 deep_copy = counter_copy = counter;
220 ASSERT_EQ(counter_copy_constructor, initial_value + 1);
221 ASSERT_EQ(counter_copy, initial_value + 1);
222 ASSERT_EQ(deep_copy, initial_value + 1);
223
224 // Make sure max value is the same for all of them, and that modifying
225 // the copies does not modify the original
226 for (int i = 0; i < 2*max_value; i++) {
227 counter_copy_constructor++;
228 counter_copy++;
229 deep_copy++;
230 }
231 ASSERT_EQ(counter, initial_value + 1);
232 ASSERT_EQ(counter_copy_constructor, max_value);
233 ASSERT_EQ(counter_copy, max_value);
234 ASSERT_EQ(deep_copy, max_value);
235
236 // Make sure initial value is the same for all of them
237 counter_copy_constructor.reset();
238 counter_copy.reset();
239 deep_copy.reset();
240 ASSERT_EQ(counter_copy_constructor, initial_value);
241 ASSERT_EQ(counter_copy, initial_value);
242 ASSERT_EQ(deep_copy, initial_value);
243
244 // Now check move
245 SatCounter counter_move_constructor(std::move(counter));
246 ASSERT_EQ(counter, 0);
247 ASSERT_EQ(counter_move_constructor, initial_value + 1);
248
249 SatCounter counter_move(bits);
250 counter_move = std::move(counter_move_constructor);
251 ASSERT_EQ(counter_move_constructor, 0);
252 ASSERT_EQ(counter_move, initial_value + 1);
253}
254
255/**
256 * Test add-assignment and subtract assignment.
257 */
258TEST(SatCounterTest, AddSubAssignment)
259{
260 const unsigned bits = 3;
261 const unsigned max_value = (1 << bits) - 1;
262 SatCounter counter(bits);
263 SatCounter other(bits, 2);
264 SatCounter saturated_counter(bits, max_value);
265 int value = 0;
266
267 // Test add-assignment for a few random values and then saturate
268 counter += 2;
269 value += 2;
270 ASSERT_EQ(counter, value);
271 counter += 3;
272 value += 3;
273 ASSERT_EQ(counter, value);
274 counter += max_value;
275 value = max_value;
276 ASSERT_EQ(counter, value);
277
278 // Test subtract-assignment for a few random values until back to zero
279 counter -= 2;
280 value -= 2;
281 ASSERT_EQ(counter, value);
282 counter -= 3;
283 value -= 3;
284 ASSERT_EQ(counter, value);
285 counter -= max_value;
286 value = 0;
287 ASSERT_EQ(counter, value);
288
289 // Test add-assignment of other saturating counter
290 counter += other;
291 value += other;
292 ASSERT_EQ(counter, value);
293 counter += saturated_counter;
294 value = max_value;
295 ASSERT_EQ(counter, saturated_counter);
296
297 // Test subtract-assignment of other saturating counter
298 counter -= other;
299 value -= other;
300 ASSERT_EQ(counter, value);
301 counter -= saturated_counter;
302 ASSERT_EQ(counter, 0);
303}
304
117 * Test back and forth against an int.
118 */
119TEST(SatCounterTest, IntComparison)
120{
121 const unsigned bits = 3;
122 SatCounter counter(bits);
123 int value = 0;
124
125 ASSERT_EQ(counter++, value++);
126 ASSERT_EQ(counter++, value++);
127 ASSERT_EQ(counter--, value--);
128 ASSERT_EQ(counter++, value++);
129 ASSERT_EQ(counter++, value++);
130 ASSERT_EQ(counter--, value--);
131 ASSERT_EQ(counter++, value++);
132 ASSERT_EQ(counter--, value--);
133 ASSERT_EQ(counter--, value--);
134 ASSERT_EQ(counter++, value++);
135 ASSERT_EQ(counter--, value--);
136 ASSERT_EQ(counter--, value--);
137 ASSERT_EQ(counter, 0);
138}
139
140/**
141 * Test shift operators.
142 */
143TEST(SatCounterTest, Shift)
144{
145 const unsigned bits = 3;
146 const unsigned max_value = (1 << bits) - 1;
147 const unsigned initial_value = 1;
148 SatCounter counter(bits, initial_value);
149 SatCounter other(bits, initial_value);
150 // The saturated shift value is just enough to saturate, since greater
151 // values could generate undefined behavior
152 SatCounter saturated_counter(bits, bits);
153 int value = initial_value;
154
155 // Test random shifts
156 counter <<= 2;
157 value <<= 2;
158 ASSERT_EQ(counter, value);
159 counter >>= 1;
160 value >>= 1;
161 ASSERT_EQ(counter, value);
162
163 // Test saturation
164 counter <<= bits;
165 ASSERT_EQ(counter, max_value);
166
167 // Test zeroing
168 counter >>= bits;
169 ASSERT_EQ(counter, 0);
170
171 // Test saturation against other saturating counter
172 counter.reset();
173 value = initial_value;
174 counter <<= other;
175 value <<= other;
176 ASSERT_EQ(counter, value);
177 counter <<= saturated_counter;
178 value = max_value;
179 ASSERT_EQ(counter, max_value);
180
181 // Test zeroing against other saturating counter
182 counter >>= other;
183 value >>= other;
184 ASSERT_EQ(counter, value);
185 counter >>= saturated_counter;
186 ASSERT_EQ(counter, 0);
187}
188
189/**
190 * Test both pre and post operators.
191 */
192TEST(SatCounterTest, PrePostOperators)
193{
194 const unsigned bits = 3;
195 const unsigned max_value = (1 << bits) - 1;
196 SatCounter counter_pre(bits);
197 SatCounter counter_post(bits);
198
199 for (int i = 0; i < 2*max_value; i++) {
200 counter_post++;
201 SatCounter value_pre = ++counter_pre;
202 ASSERT_EQ(counter_post, value_pre);
203 }
204
205 ASSERT_EQ(counter_pre, max_value);
206 ASSERT_EQ(counter_post, max_value);
207
208 for (int i = 0; i < 2*max_value; i++) {
209 counter_post--;
210 SatCounter value_pre = --counter_pre;
211 ASSERT_EQ(counter_post, value_pre);
212 }
213
214 ASSERT_EQ(counter_pre, 0);
215 ASSERT_EQ(counter_post, 0);
216}
217
218/**
219 * Test copy and move for both constructor and assignment.
220 */
221TEST(SatCounterTest, CopyMove)
222{
223 const unsigned bits = 3;
224 const unsigned max_value = (1 << bits) - 1;
225 const unsigned initial_value = 1;
226 SatCounter counter(bits, initial_value);
227 SatCounter deep_copy(1);
228 SatCounter counter_copy(2);
229
230 // Increase counter value so that we can check if the inner counter is
231 // being copied
232 counter++;
233
234 // Copy counter using both the copy constructor and the copy assignment
235 SatCounter counter_copy_constructor(counter);
236 deep_copy = counter_copy = counter;
237 ASSERT_EQ(counter_copy_constructor, initial_value + 1);
238 ASSERT_EQ(counter_copy, initial_value + 1);
239 ASSERT_EQ(deep_copy, initial_value + 1);
240
241 // Make sure max value is the same for all of them, and that modifying
242 // the copies does not modify the original
243 for (int i = 0; i < 2*max_value; i++) {
244 counter_copy_constructor++;
245 counter_copy++;
246 deep_copy++;
247 }
248 ASSERT_EQ(counter, initial_value + 1);
249 ASSERT_EQ(counter_copy_constructor, max_value);
250 ASSERT_EQ(counter_copy, max_value);
251 ASSERT_EQ(deep_copy, max_value);
252
253 // Make sure initial value is the same for all of them
254 counter_copy_constructor.reset();
255 counter_copy.reset();
256 deep_copy.reset();
257 ASSERT_EQ(counter_copy_constructor, initial_value);
258 ASSERT_EQ(counter_copy, initial_value);
259 ASSERT_EQ(deep_copy, initial_value);
260
261 // Now check move
262 SatCounter counter_move_constructor(std::move(counter));
263 ASSERT_EQ(counter, 0);
264 ASSERT_EQ(counter_move_constructor, initial_value + 1);
265
266 SatCounter counter_move(bits);
267 counter_move = std::move(counter_move_constructor);
268 ASSERT_EQ(counter_move_constructor, 0);
269 ASSERT_EQ(counter_move, initial_value + 1);
270}
271
272/**
273 * Test add-assignment and subtract assignment.
274 */
275TEST(SatCounterTest, AddSubAssignment)
276{
277 const unsigned bits = 3;
278 const unsigned max_value = (1 << bits) - 1;
279 SatCounter counter(bits);
280 SatCounter other(bits, 2);
281 SatCounter saturated_counter(bits, max_value);
282 int value = 0;
283
284 // Test add-assignment for a few random values and then saturate
285 counter += 2;
286 value += 2;
287 ASSERT_EQ(counter, value);
288 counter += 3;
289 value += 3;
290 ASSERT_EQ(counter, value);
291 counter += max_value;
292 value = max_value;
293 ASSERT_EQ(counter, value);
294
295 // Test subtract-assignment for a few random values until back to zero
296 counter -= 2;
297 value -= 2;
298 ASSERT_EQ(counter, value);
299 counter -= 3;
300 value -= 3;
301 ASSERT_EQ(counter, value);
302 counter -= max_value;
303 value = 0;
304 ASSERT_EQ(counter, value);
305
306 // Test add-assignment of other saturating counter
307 counter += other;
308 value += other;
309 ASSERT_EQ(counter, value);
310 counter += saturated_counter;
311 value = max_value;
312 ASSERT_EQ(counter, saturated_counter);
313
314 // Test subtract-assignment of other saturating counter
315 counter -= other;
316 value -= other;
317 ASSERT_EQ(counter, value);
318 counter -= saturated_counter;
319 ASSERT_EQ(counter, 0);
320}
321