Library: implement test access to hidden global RandomSequencer
this seems to be the ''classical problem situation'' where a »clean« Dependency-Injection would require to waste storage for a pointer to the same global resource in each and every distinct test class. Since the Test-Suite is effectively global — even more so now due to the reliance on "the" global `RandomSequencer` (PNRG) — we'll have to bite the bullet and access a global static variable hidden behind teh scenes.
This commit is contained in:
parent
c13d6d45f4
commit
cffa2cd6c2
4 changed files with 98 additions and 39 deletions
|
|
@ -72,14 +72,21 @@ namespace lib {
|
|||
|
||||
/// @todo this one should somehow be configurable
|
||||
EternalNucleus eternalNucleus;
|
||||
|
||||
Random::Seed defaultNucleus{defaultGen};
|
||||
}
|
||||
|
||||
|
||||
SeedNucleus::~SeedNucleus() { }
|
||||
|
||||
Random defaultGen{eternalNucleus};
|
||||
Random entropyGen{entropyNucleus};
|
||||
|
||||
SeedNucleus&
|
||||
seedFromDefaultGen()
|
||||
{
|
||||
return defaultNucleus;
|
||||
}
|
||||
|
||||
|
||||
SeedNucleus::~SeedNucleus() { }
|
||||
|
||||
void
|
||||
randomiseRandomness()
|
||||
|
|
@ -88,4 +95,5 @@ namespace lib {
|
|||
defaultGen.reseed(entropyNucleus);
|
||||
}
|
||||
|
||||
|
||||
} // namespace lib
|
||||
|
|
|
|||
|
|
@ -81,8 +81,29 @@ namespace lib {
|
|||
|
||||
/** inject controlled randomisation */
|
||||
void reseed (SeedNucleus&);
|
||||
|
||||
/** wrapper to use this generator for seeding other generators */
|
||||
class Seed;
|
||||
};
|
||||
|
||||
template<class GEN>
|
||||
class RandomSequencer<GEN>::Seed
|
||||
: public SeedNucleus
|
||||
{
|
||||
RandomSequencer& srcGen_;
|
||||
public:
|
||||
Seed(RandomSequencer& parent)
|
||||
: srcGen_{parent}
|
||||
{ }
|
||||
|
||||
uint64_t
|
||||
getSeed() override
|
||||
{
|
||||
return srcGen_.u64();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* PRNG engine to use by default: 64bit mersenne twister.
|
||||
*/
|
||||
|
|
@ -106,6 +127,10 @@ namespace lib {
|
|||
/** inject true randomness into the #defaultGen */
|
||||
void randomiseRandomness();
|
||||
|
||||
/** draw seed another Generator from the default RandomSequencer */
|
||||
SeedNucleus& seedFromDefaultGen();
|
||||
|
||||
|
||||
|
||||
/* ===== Implementation details ===== */
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
#include "lib/util.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
|
@ -48,12 +48,14 @@ namespace test {
|
|||
|
||||
using std::map;
|
||||
using std::vector;
|
||||
using std::optional;
|
||||
using std::shared_ptr;
|
||||
using boost::algorithm::trim;
|
||||
|
||||
using util::isnil;
|
||||
using util::contains;
|
||||
using util::typeStr;
|
||||
using lib::SeedNucleus;
|
||||
using lib::Random;
|
||||
|
||||
typedef map<string, Launcher*> TestMap;
|
||||
|
|
@ -97,7 +99,22 @@ namespace test {
|
|||
(*group)[testID] = test;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class SuiteSeedNucleus
|
||||
: public SeedNucleus
|
||||
{
|
||||
optional<uint64_t> fixedSeed_;
|
||||
|
||||
uint64_t
|
||||
getSeed() override
|
||||
{
|
||||
return fixedSeed_? *fixedSeed_
|
||||
: lib::entropyGen.u64();
|
||||
}
|
||||
};
|
||||
|
||||
/* ===== global implementation state ===== */
|
||||
SuiteSeedNucleus suiteSeed;
|
||||
Registry testcases;
|
||||
}
|
||||
|
||||
|
|
@ -192,17 +209,19 @@ namespace test {
|
|||
}
|
||||
|
||||
|
||||
/** draw a new random seed from a common nucleus, and re-seed the default-Gen. */
|
||||
void
|
||||
Test::seedRand()
|
||||
{
|
||||
UNIMPLEMENTED ("draw a new random seed from a common nucleus, and re-seed the default-Gen");
|
||||
lib::defaultGen.reseed (suiteSeed);
|
||||
}
|
||||
|
||||
|
||||
/** build a dedicated new RandomGen, seeded from the default-Gen */
|
||||
Random
|
||||
Test::makeRandGen()
|
||||
{
|
||||
UNIMPLEMENTED ("build a dedicated new RandomGen, seeded from the default-Gen");
|
||||
return Random{lib::seedFromDefaultGen()};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14875,9 +14875,7 @@
|
|||
</node>
|
||||
<node CREATED="1509151309866" ID="ID_1109789284" MODIFIED="1576282358112" TEXT="sollte es als als Basis iter implementieren">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...und die IterSource dann nur über WrapIter definieren.
|
||||
|
|
@ -16158,9 +16156,7 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1523222214579" ID="ID_1568226158" MODIFIED="1576282358106" STYLE="fork" TEXT="Feststellung: keine Status-Rückmeldung">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
das mag überraschend klingen,
|
||||
|
|
@ -16878,9 +16874,7 @@
|
|||
<node CREATED="1485457370310" ID="ID_1931452525" MODIFIED="1557498707221" TEXT="GtkWindow sind völlig ausreichend"/>
|
||||
<node CREATED="1485546285407" ID="ID_1129769291" MODIFIED="1557498707221">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
muß kein <b>Manager</b> sein
|
||||
|
|
@ -17498,9 +17492,7 @@
|
|||
</node>
|
||||
<node CREATED="1486751116251" HGAP="140" ID="ID_113005643" MODIFIED="1557498707222" VSHIFT="61">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Brücke: <i>gemeinsamer</i> Controller
|
||||
|
|
@ -18756,9 +18748,7 @@
|
|||
<node CREATED="1664308730228" ID="ID_964535587" MODIFIED="1664308762363" TEXT="zum Zeitpunkt der Alloc-Zuteilung haben die nested-children noch keine Allokation"/>
|
||||
<node CREATED="1664308866802" ID="ID_993068829" MODIFIED="1664308941471" TEXT="die Alloc-Zuteiltung für die Kiner passiert irgendwann später">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...was normalerweise ja auch irrelevant ist, denn per Voraussetzung sollte ein Container die Werte von seinen Kindern bereits bei seiner initialen Meldung berücksichtigt haben
|
||||
|
|
@ -46521,9 +46511,7 @@
|
|||
<node CREATED="1448078308690" ID="ID_185716114" MODIFIED="1518487921085" TEXT="Aktionen">
|
||||
<node CREATED="1448078344541" ID="ID_1781183546" MODIFIED="1576282358016" TEXT="Subjekt einer Aktion">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...ist <i>immer</i> ein <b>tangible</b>
|
||||
|
|
@ -46885,9 +46873,7 @@
|
|||
</body>
|
||||
</html></richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
ganz bewußt verzichten wir darauf,
|
||||
|
|
@ -47469,9 +47455,7 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1455895664140" ID="ID_639070488" MODIFIED="1455895669295">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
aber was dann wenn out-of-order
|
||||
|
|
@ -47765,9 +47749,7 @@
|
|||
<node CREATED="1470772440180" ID="ID_836603881" MODIFIED="1470772503839" TEXT="verify match with next src position"/>
|
||||
<node CREATED="1455928275316" ID="ID_702364156" MODIFIED="1512926191928">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
then <i>move</i> into target
|
||||
|
|
@ -47983,9 +47965,7 @@
|
|||
<node CREATED="1455930971027" ID="ID_1070880241" MODIFIED="1455930980789" TEXT="ist in jedem Einzelfall anders"/>
|
||||
<node CREATED="1455931008750" ID="ID_643730154" MODIFIED="1575133327378" TEXT="Mutator enthält Closures">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Mutator enthält die Bindung auf die konkreten Daten
|
||||
|
|
@ -57406,8 +57386,35 @@
|
|||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1731208300347" ID="ID_157287510" MODIFIED="1731208332129" TEXT="tatsächlich aber brauche ich den Nucleus in der einzelnen Test-Subklasse">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1731209451725" ID="ID_774812395" MODIFIED="1731209472619" TEXT="die Suite ist mit dem Nucleus parametrisiert"/>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1731209473303" ID="ID_1979397339" MODIFIED="1731209485557" TEXT="vielleicht läßt sich das sogar als Funktor darstellen?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1731247770927" ID="ID_886572495" MODIFIED="1731247837299" TEXT="sieht nach Dependency-Injection aus und ist effektiv global">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
das ist der klassische Fall, in dem eine »saubere« Repräsentation in der einzelnen Testklasse zu massiver Speicherverschwendung führt, weil jede Testklasse einen redundanten Pointer auf den gleichen globalen Kontext bekommt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731251266883" ID="ID_326274878" MODIFIED="1731251304272" TEXT="außerdem brauchen wir einen Seed-Wrapper um einen bestehenden Generator">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1731251305887" ID="ID_889654920" MODIFIED="1731251314393" TEXT="und das ist ein ähnlich gelagertes Problem"/>
|
||||
<node CREATED="1731251315053" ID="ID_667235767" MODIFIED="1731251348353" TEXT="das Design mit dem SeedNucleus als virtuelles Interface hat seine Schwächen">
|
||||
<icon BUILTIN="smily_bad"/>
|
||||
</node>
|
||||
<node CREATED="1731251351030" ID="ID_1463644758" MODIFIED="1731251389711" TEXT="die VTable muß für jede Instanz erneut generiert werden, die als Quelle dienen soll"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1731251390572" ID="ID_1815150553" MODIFIED="1731251416786" TEXT="damit droht die gleiche Explosion der Subklassen, die ich vermeiden wollte">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1731251418640" ID="ID_912804843" MODIFIED="1731251431186" TEXT="Ausweg: nur die Möglichkeit anbieten">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1731251432526" ID="ID_1542226880" MODIFIED="1731251441316" TEXT="als Adapter / Innere Klasse"/>
|
||||
<node CREATED="1731251444252" ID="ID_1693694322" MODIFIED="1731251453990" TEXT="erwartungsgemäß wird das (fast) nie gebraucht"/>
|
||||
<node COLOR="#338800" CREATED="1731251454674" ID="ID_481118676" MODIFIED="1731251486430" TEXT="nur eine feste globale (versteckte) Instanz : der defaultNucleus">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue