diff options
Diffstat (limited to 'src/base/sat_counter.test.cc')
-rw-r--r-- | src/base/sat_counter.test.cc | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/src/base/sat_counter.test.cc b/src/base/sat_counter.test.cc index efc79e034..dbdaf0ae6 100644 --- a/src/base/sat_counter.test.cc +++ b/src/base/sat_counter.test.cc @@ -30,6 +30,8 @@ #include <gtest/gtest.h> +#include <utility> + #include "base/sat_counter.hh" /** @@ -78,6 +80,23 @@ TEST(SatCounterTest, InitialValue) } /** + * Test calculating saturation percentile. + */ +TEST(SatCounterTest, SaturationPercentile) +{ + const unsigned bits = 3; + const unsigned max_value = (1 << bits) - 1; + SatCounter counter(bits); + + ASSERT_FALSE(counter.isSaturated()); + for (double value = 0.0; value <= max_value; value++, counter++) { + const double saturation = value / max_value; + ASSERT_DOUBLE_EQ(counter.calcSaturation(), saturation); + } + ASSERT_TRUE(counter.isSaturated()); +} + +/** * Test back and forth against an int. */ TEST(SatCounterTest, IntComparison) @@ -102,6 +121,55 @@ TEST(SatCounterTest, IntComparison) } /** + * Test shift operators. + */ +TEST(SatCounterTest, Shift) +{ + const unsigned bits = 3; + const unsigned max_value = (1 << bits) - 1; + const unsigned initial_value = 1; + SatCounter counter(bits, initial_value); + SatCounter other(bits, initial_value); + // The saturated shift value is just enough to saturate, since greater + // values could generate undefined behavior + SatCounter saturated_counter(bits, bits); + int value = initial_value; + + // Test random shifts + counter <<= 2; + value <<= 2; + ASSERT_EQ(counter, value); + counter >>= 1; + value >>= 1; + ASSERT_EQ(counter, value); + + // Test saturation + counter <<= bits; + ASSERT_EQ(counter, max_value); + + // Test zeroing + counter >>= bits; + ASSERT_EQ(counter, 0); + + // Test saturation against other saturating counter + counter.reset(); + value = initial_value; + counter <<= other; + value <<= other; + ASSERT_EQ(counter, value); + counter <<= saturated_counter; + value = max_value; + ASSERT_EQ(counter, max_value); + + // Test zeroing against other saturating counter + counter >>= other; + value >>= other; + ASSERT_EQ(counter, value); + counter >>= saturated_counter; + ASSERT_EQ(counter, 0); +} + +/** * Test both pre and post operators. */ TEST(SatCounterTest, PrePostOperators) @@ -129,3 +197,108 @@ TEST(SatCounterTest, PrePostOperators) ASSERT_EQ(counter_pre, 0); ASSERT_EQ(counter_post, 0); } + +/** + * Test copy and move for both constructor and assignment. + */ +TEST(SatCounterTest, CopyMove) +{ + const unsigned bits = 3; + const unsigned max_value = (1 << bits) - 1; + const unsigned initial_value = 1; + SatCounter counter(bits, initial_value); + SatCounter deep_copy(1); + SatCounter counter_copy(2); + + // Increase counter value so that we can check if the inner counter is + // being copied + counter++; + + // Copy counter using both the copy constructor and the copy assignment + SatCounter counter_copy_constructor(counter); + deep_copy = counter_copy = counter; + ASSERT_EQ(counter_copy_constructor, initial_value + 1); + ASSERT_EQ(counter_copy, initial_value + 1); + ASSERT_EQ(deep_copy, initial_value + 1); + + // Make sure max value is the same for all of them, and that modifying + // the copies does not modify the original + for (int i = 0; i < 2*max_value; i++) { + counter_copy_constructor++; + counter_copy++; + deep_copy++; + } + ASSERT_EQ(counter, initial_value + 1); + ASSERT_EQ(counter_copy_constructor, max_value); + ASSERT_EQ(counter_copy, max_value); + ASSERT_EQ(deep_copy, max_value); + + // Make sure initial value is the same for all of them + counter_copy_constructor.reset(); + counter_copy.reset(); + deep_copy.reset(); + ASSERT_EQ(counter_copy_constructor, initial_value); + ASSERT_EQ(counter_copy, initial_value); + ASSERT_EQ(deep_copy, initial_value); + + // Now check move + SatCounter counter_move_constructor(std::move(counter)); + ASSERT_EQ(counter, 0); + ASSERT_EQ(counter_move_constructor, initial_value + 1); + + SatCounter counter_move(bits); + counter_move = std::move(counter_move_constructor); + ASSERT_EQ(counter_move_constructor, 0); + ASSERT_EQ(counter_move, initial_value + 1); +} + +/** + * Test add-assignment and subtract assignment. + */ +TEST(SatCounterTest, AddSubAssignment) +{ + const unsigned bits = 3; + const unsigned max_value = (1 << bits) - 1; + SatCounter counter(bits); + SatCounter other(bits, 2); + SatCounter saturated_counter(bits, max_value); + int value = 0; + + // Test add-assignment for a few random values and then saturate + counter += 2; + value += 2; + ASSERT_EQ(counter, value); + counter += 3; + value += 3; + ASSERT_EQ(counter, value); + counter += max_value; + value = max_value; + ASSERT_EQ(counter, value); + + // Test subtract-assignment for a few random values until back to zero + counter -= 2; + value -= 2; + ASSERT_EQ(counter, value); + counter -= 3; + value -= 3; + ASSERT_EQ(counter, value); + counter -= max_value; + value = 0; + ASSERT_EQ(counter, value); + + // Test add-assignment of other saturating counter + counter += other; + value += other; + ASSERT_EQ(counter, value); + counter += saturated_counter; + value = max_value; + ASSERT_EQ(counter, saturated_counter); + + // Test subtract-assignment of other saturating counter + counter -= other; + value -= other; + ASSERT_EQ(counter, value); + counter -= saturated_counter; + ASSERT_EQ(counter, 0); +} + |