summaryrefslogtreecommitdiff
path: root/src/base/sat_counter.test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/sat_counter.test.cc')
-rw-r--r--src/base/sat_counter.test.cc173
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);
+}
+