From 10fa0aaa796f772bd3b8ae0ec4cb4337f563caa1 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 6 Apr 2024 23:21:10 +0200 Subject: [PATCH] Scheduler-test: design problems impeding clean test-setup Encountering ''just some design problems related to the test setup,'' which however turn out hard to overcome. Seems that, in my eagerness to create a succinct and clear presentation of the test, I went into danger territory, overstretching the abilities of the C++ language. After working with a set of tools created step by step over an extended span of time, ''for me'' the machinations of this setup seem to be reduced to flipping a toggle here and there, and I want to focus these active parts while laying out this test. ''This would require'' to create a system of nested scopes, while getting more and more specific gradually, and moving to the individual case at question; notably any clarification and definition within those inner focused contexts would have to be picked up and linked in dynamically. Yet the C++ language only allows to be ''either'' open and flexible towards the actual types, or ''alternatively'' to select dynamically within a fixed set of (virtual) methods, which then must be determined from the beginning. It is not possible to tweak and adjust base definitions after the fact, and it is not possible to fill in constant definitions dynamically with late binding to some specific implementation type provided only at current scope. Seems that I am running against that brick wall over and over again, piling up complexities driven by an desire for succinctness and clarity. Now attempting to resolve this quite frustrating situation... - fix the actual type of the TestChainLoad by a typedef in test context - avoid the definitions (and thus the danger of shadowing) and use one `testSetup()` method to place all local adjustments. --- tests/vault/gear/scheduler-stress-test.cpp | 36 ++++++++++++----- tests/vault/gear/stress-test-rig.hpp | 43 +++++++++----------- tests/vault/gear/test-chain-load.hpp | 8 ++++ wiki/thinkPad.ichthyo.mm | 47 ++++++++++++++++++++++ 4 files changed, 100 insertions(+), 34 deletions(-) diff --git a/tests/vault/gear/scheduler-stress-test.cpp b/tests/vault/gear/scheduler-stress-test.cpp index c0c1fa677..48c6af04a 100644 --- a/tests/vault/gear/scheduler-stress-test.cpp +++ b/tests/vault/gear/scheduler-stress-test.cpp @@ -329,6 +329,7 @@ namespace test { } // should ideally spend most of the time at highest concurrency levels + using StressRig = StressTestRig<16>; /** @test determine the breaking point towards scheduler overload * - use the integrated StressRig @@ -356,11 +357,18 @@ namespace test { struct Setup : StressRig { - usec LOAD_BASE = 500us; uint CONCURRENCY = 4; bool showRuns = true; - auto testLoad() { return TestChainLoad<>{64}.configureShape_chain_loadBursts(); } + auto testLoad() + { return TestLoad{64}.configureShape_chain_loadBursts(); } + + auto testSetup (TestLoad& testLoad) + { + return StressRig::testSetup(testLoad) + .withLoadTimeBase(500us); + } + }; auto [stress,delta,time] = StressRig::with() @@ -391,19 +399,23 @@ namespace test { struct Setup : StressRig { - usec LOAD_BASE = 500us; uint CONCURRENCY = 4; using Param = size_t; using Table = bench::DataTable; - auto - testLoad(Param nodes) + auto testLoad(Param nodes) { - TestChainLoad testLoad{nodes}; + TestLoad testLoad{nodes}; return testLoad.configure_isolated_nodes(); } + auto testSetup (TestLoad& testLoad) + { + return StressRig::testSetup(testLoad) + .withLoadTimeBase(500us); + } + void collectResult(Table& data, Param param, double millis, bench::IncidenceStat const& stat) { @@ -469,11 +481,10 @@ SHOW_EXPR(loadMicros) //SHOW_EXPR(runTime) //SHOW_EXPR(expected) //SHOW_EXPR(refTime) + using StressRig = StressTestRig<8>; struct Setup : StressRig { - usec LOAD_BASE = 500us; - usec BASE_EXPENSE = 200us; double UPPER_STRESS = 12; // double FAIL_LIMIT = 1.0; //0.7; @@ -486,13 +497,20 @@ SHOW_EXPR(loadMicros) auto testLoad() { - TestChainLoad<8> testLoad{256}; + TestLoad testLoad{256}; testLoad.seedingRule(testLoad.rule().probability(0.6).minVal(2)) .pruningRule(testLoad.rule().probability(0.44)) .weightRule(testLoad.value(1)) .setSeed(55); return testLoad; } + + auto testSetup (TestLoad& testLoad) + { + return StressRig::testSetup(testLoad) + .withBaseExpense(200us) + .withLoadTimeBase(500us); + } }; auto [stress,delta,time] = StressRig::with() .perform(); diff --git a/tests/vault/gear/stress-test-rig.hpp b/tests/vault/gear/stress-test-rig.hpp index 7587650fe..599205692 100644 --- a/tests/vault/gear/stress-test-rig.hpp +++ b/tests/vault/gear/stress-test-rig.hpp @@ -143,11 +143,15 @@ namespace test { /** configurable template framework for running Scheduler Stress tests */ - class StressRig + template + class StressTestRig : util::NonCopyable { - public: + using TestLoad = TestChainLoad; + using TestSetup = typename TestLoad::ScheduleCtx; + + /***********************************************************************//** * Entrance Point: build a stress test measurement setup using a dedicated * \a TOOL class, takes the configuration \a CONF as template parameter @@ -165,13 +169,6 @@ namespace test { /* ======= default configuration (inherited) ======= */ - using usec = std::chrono::microseconds; - - usec LOAD_BASE = 500us; - usec LEVEL_STEP = 200us; - usec BASE_EXPENSE = 0us; - bool SCHED_NOTIFY = true; - bool SCHED_DEPENDS = false; uint CONCURRENCY = work::Config::getDefaultComputationCapacity(); bool INSTRUMENTATION = true; double EPSILON = 0.01; ///< error bound to abort binary search @@ -198,20 +195,16 @@ namespace test { auto testLoad(size_t nodes =64) { - return TestChainLoad<>{nodes}; + return TestLoad{nodes}; } - /** (optional) extension point: base configuration of the test ScheduleCtx */ - template + /** (optional) extension point: base configuration of the test ScheduleCtx + * @warning the actual setup \a CONF is layered, beware of shadowing. */ auto - testSetup (TL& testLoad) + testSetup (TestLoad& testLoad) { return testLoad.setupSchedule(scheduler) - .withLoadTimeBase(LOAD_BASE) - .withLevelDuration(LEVEL_STEP) - .withBaseExpense (BASE_EXPENSE) - .withSchedNotify (SCHED_NOTIFY) - .withSchedDepends(SCHED_DEPENDS) + .withLevelDuration(200us) .withJobDeadline(100ms) .withUpfrontPlanning(); } @@ -244,8 +237,8 @@ namespace test { class BreakingPoint : public CONF { - using TestLoad = decltype(declval().testLoad()); - using TestSetup = decltype(declval().testSetup (declval())); + using TestLoad = typename CONF::TestLoad; + using TestSetup = typename TestLoad::ScheduleCtx; struct Res { @@ -383,11 +376,11 @@ namespace test { } void - showRef(TestLoad& testLoad) + showRef(TestSetup& testSetup) { if (CONF::showRef) cout << fmtResVal_ % "refTime" - % (testLoad.calcRuntimeReference(CONF::LOAD_BASE) /1000) + % (testSetup.calcRuntimeReference() /1000) % "ms" << endl; } @@ -417,7 +410,7 @@ namespace test { Res res = conductBinarySearch (move(performEvaluation), observations); showRes (res); - showRef (testLoad); + showRef (testSetup); return make_tuple (res.stressFac, res.avgDelta, res.avgTime); } }; @@ -465,8 +458,8 @@ namespace test { using Table = typename CONF::Table; using Param = typename CONF::Param; - using TestLoad = decltype(declval().testLoad(Param())); - using TestSetup = decltype(declval().testSetup (declval())); + using TestLoad = typename CONF::TestLoad; + using TestSetup = typename TestLoad::ScheduleCtx; void diff --git a/tests/vault/gear/test-chain-load.hpp b/tests/vault/gear/test-chain-load.hpp index 68a621cf3..1406b1d17 100644 --- a/tests/vault/gear/test-chain-load.hpp +++ b/tests/vault/gear/test-chain-load.hpp @@ -1865,6 +1865,14 @@ namespace test { : lib::IncidenceCount::Statistic{}; } + double + calcRuntimeReference() + { + microseconds timeBase = compuLoad_->timeBase; + size_t sizeBase = compuLoad_->useAllocation? compuLoad_->sizeBase : 0; + return chainLoad_.calcRuntimeReference (timeBase, sizeBase); + } + double getStressFac() { return stressFac_; } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 028213f8b..77e54d886 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -114935,11 +114935,58 @@ std::cout << tmpl.render({"what", "World"}) << s + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +