From ce151e3e472da75d707fb12ab8c7c32cb65c9248 Mon Sep 17 00:00:00 2001 From: Patrick Donnelly Date: Mon, 26 Oct 2020 15:37:24 -0700 Subject: [PATCH] test: add DecayCounter test In particular, look at the steady state decay. (i.e. a counter that is continuously "refilled".) Signed-off-by: Patrick Donnelly --- src/test/common/CMakeLists.txt | 6 +++ src/test/common/test_counter.cc | 40 ++++++++++++++++++ src/test/old/testcounter.cc | 73 --------------------------------- 3 files changed, 46 insertions(+), 73 deletions(-) create mode 100644 src/test/common/test_counter.cc delete mode 100644 src/test/old/testcounter.cc diff --git a/src/test/common/CMakeLists.txt b/src/test/common/CMakeLists.txt index 4bf46a00873d0..9338e3af10e74 100644 --- a/src/test/common/CMakeLists.txt +++ b/src/test/common/CMakeLists.txt @@ -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 index 0000000000000..942d2a7e530c0 --- /dev/null +++ b/src/test/common/test_counter.cc @@ -0,0 +1,40 @@ +#include "common/DecayCounter.h" + +#include + +#include +#include + +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(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 index 4e40914f453fe..0000000000000 --- a/src/test/old/testcounter.cc +++ /dev/null @@ -1,73 +0,0 @@ - -#include "common/DecayCounter.h" - -#include - -#include -using namespace std; - -struct RealCounter { -public: - list 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(); - } - -} -- 2.39.5