]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
test: add DecayCounter test
authorPatrick Donnelly <pdonnell@redhat.com>
Mon, 26 Oct 2020 22:37:24 +0000 (15:37 -0700)
committerVicente Cheng <freeze.bilsted@gmail.com>
Mon, 7 Dec 2020 05:49:24 +0000 (05:49 +0000)
In particular, look at the steady state decay. (i.e. a counter that is
continuously "refilled".)

Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
(cherry picked from commit ce151e3e472da75d707fb12ab8c7c32cb65c9248)

src/test/common/CMakeLists.txt
src/test/common/test_counter.cc [new file with mode: 0644]
src/test/old/testcounter.cc [deleted file]

index e67d9718b2998271263fee2923190b32fd55ed21..0f2452c8b9630aad64392add1f108bbf90234f67 100644 (file)
@@ -27,6 +27,12 @@ add_executable(unittest_lockdep
 add_ceph_unittest(unittest_lockdep)
 target_link_libraries(unittest_lockdep ceph-common)
 
+# unittest_counter
+add_executable(unittest_counter
+  test_counter.cc)
+add_ceph_unittest(unittest_counter)
+target_link_libraries(unittest_counter ceph-common)
+
 # FreeBSD only has shims to support NUMA, no functional code.
 if(LINUX)
 # unittest_numa
diff --git a/src/test/common/test_counter.cc b/src/test/common/test_counter.cc
new file mode 100644 (file)
index 0000000..942d2a7
--- /dev/null
@@ -0,0 +1,40 @@
+#include "common/DecayCounter.h"
+
+#include <gtest/gtest.h>
+
+#include <list>
+#include <cmath>
+
+TEST(DecayCounter, steady)
+{
+  static const double duration = 2.0;
+  static const double max = 2048.0;
+  static const double rate = 3.5;
+
+  DecayCounter d{DecayRate{rate}};
+  d.hit(max);
+  const auto start = DecayCounter::clock::now();
+  double total = 0.0;
+  while (1) {
+    const auto now = DecayCounter::clock::now();
+    auto el = std::chrono::duration<double>(now-start);
+    if (el.count() > duration) {
+      break;
+    }
+
+    double v = d.get();
+    double diff = max-v;
+    if (diff > 0.0) {
+      d.hit(diff);
+      total += diff;
+    }
+  }
+
+  /* Decay function: dN/dt = -λM where λ = ln(0.5)/rate
+   * (where M is the maximum value of the counter, not varying with time.)
+   * Integrating over t: N = -λMt (+c)
+   */
+  double expected = -1*std::log(0.5)/rate*max*duration;
+  std::cerr << "t " << total << " e " << expected << std::endl;
+  ASSERT_LT(std::abs(total-expected)/expected, 0.01);
+}
diff --git a/src/test/old/testcounter.cc b/src/test/old/testcounter.cc
deleted file mode 100644 (file)
index 4e40914..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-
-#include "common/DecayCounter.h"
-
-#include <list>
-
-#include <unistd.h>
-using namespace std;
-
-struct RealCounter {
-public:
-  list<int> hits;
-  
-  void hit(int ms) {
-       hits.push_back(ms);
-  }
-  
-  int get(double hl, int now) {
-       trim(now-hl);
-       return hits.size();
-  }
-
-  void trim(int to) {
-       while (!hits.empty() &&
-                  hits.front() < to) 
-         hits.pop_front();
-  }
-
-};
-
-int main(int argc, char **argv)
-{
-  int target;
-  double hl = atof(argv[1]);
-  cerr << "halflife " << hl << endl;
-
-  DecayCounter dc(hl);
-  RealCounter rc;
-
-  DecayCounter::time now = DecayCounter::clock::now();
-
-  for (int ms=0; ms < 300*1000; ms++) {
-       if (ms % 30000 == 0) {
-         target = 1 + (rand() % 10) * 10;
-         if (ms > 200000) target = 0;
-       }
-
-       if (target &&
-               (rand() % (1000/target) == 0)) {
-         dc.hit();
-         rc.hit(ms);
-       }
-
-       if (ms % 500 == 0) dc.get(now);
-       if (ms % 100 == 0) {
-         //dc.get(now);
-         DecayCounter o = dc;
-         cout << ms << "\t"
-                  << target*hl << "\t"
-                  << rc.get(hl*1000, ms) << "\t"
-                  << o.get(now) << "\t" 
-                  << dc.val << "\t"
-               //                 << dc.delta << "\t"
-                  << o.get_last_vel() << "\t"
-                  << o.get_last() + o.get_last_vel() << "\t"
-                  << endl;
-       }
-
-    usleep(1);
-    now = DecayCounter::clock::now();
-  }
-
-}