sat_counter.test.cc revision 13962
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 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 305