Invocation: implement and verify extended verification

Since each `TestFrame` now has a metadata header,
we can store an additional data checksum there,
so that it is now possible both to detect if data
is in pristine state, or if it matches a changed state
recorded in the additional checksum.

So we have now three different levels of verification
 isSane:: consistent metadata header found
 isValid:: metadata header found and checksum there matches data
 isPristine:: in addition, the data is exactly as generated from the `(frameNr,family)`
This commit is contained in:
Fischlurch 2024-11-20 05:50:44 +01:00
parent 204e2f55d0
commit 3bfe8f33e0
5 changed files with 361 additions and 195 deletions

View file

@ -598,7 +598,7 @@ return: 0
END
PLANNED "Several elements" SeveralBuilder_test <<END
TEST "Several elements" SeveralBuilder_test <<END
return: 0
END

View file

@ -17,6 +17,7 @@
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"
#include "steam/engine/testframe.hpp"
#include "lib/util.hpp"
@ -70,7 +71,10 @@ namespace test {
run (Arg)
{
seedRand();
verifyBasicProperties();
TestFrame::reseed();
simpleUsage();
verifyDataContent();
verifyFrameLifecycle();
verifyFrameSeries();
useFrameTable();
@ -78,10 +82,27 @@ namespace test {
void
verifyBasicProperties()
simpleUsage()
{
CHECK (1024 < sizeof(TestFrame));
TestFrame frame;
CHECK (frame.isValid());
++frame.data()[5];
CHECK (not frame.isValid());
frame.markChecksum();
CHECK (frame.isValid());
CHECK (isSameObject(frame, frame.data())); // payload data stored embedded
CHECK (sizeof(TestFrame) > frame.data().size()); // additional metadata placed behind
}
void
verifyDataContent()
{
TestFrame frameA;
TestFrame frameB;
TestFrame frameC(5);
@ -90,6 +111,11 @@ namespace test {
CHECK (frameA != frameC);
CHECK (frameB != frameC);
CHECK (frameA.data() == frameB.data());
CHECK (frameA.data() != frameC.data());
for (uint i=0; i<frameA.data().size(); ++i)
CHECK (frameA.data()[i] == frameB.data()[i]);
CHECK (frameA.isAlive());
CHECK (frameB.isAlive());
CHECK (frameC.isAlive());
@ -98,11 +124,26 @@ namespace test {
CHECK (frameB.isSane());
CHECK (frameC.isSane());
CHECK (frameA.isValid());
CHECK (frameB.isValid());
CHECK (frameC.isValid());
CHECK (frameA.isPristine());
CHECK (frameB.isPristine());
CHECK (frameC.isPristine());
void * frameMem = &frameB;
CHECK (frameA == frameMem);
corruptMemory(frameMem,20,5);
CHECK (!frameB.isSane());
corruptMemory (frameMem,20,5);
CHECK ( frameB.isSane()); // still has valid metadata header
CHECK (not frameB.isValid()); // data checksum does not match any more
CHECK (not frameB.isPristine()); // data does not match the original generation sequence
frameB.markChecksum();
CHECK ( frameB.isSane()); // still has valid metadata header
CHECK ( frameB.isValid()); // data matches the new recorded checksum
CHECK (not frameB.isPristine()); // but data still does not match the original generation sequence
frameB = frameC;
@ -110,26 +151,36 @@ namespace test {
CHECK (frameA != frameB);
CHECK (frameA != frameC);
CHECK (frameB == frameC);
corruptMemory (frameMem, 0,sizeof(TestFrame));
CHECK (not frameB.isSane()); // now also the metadata was corrupted...
CHECK (not frameB.isValid());
VERIFY_FAIL ("corrupted metadata"
, frameB.markChecksum() ); // reject to store new checksum in the corrupted header
VERIFY_FAIL ("target TestFrame already dead or unaccessible"
, frameB = frameC); // reject to assign new content to a corrupted target
}
void
verifyFrameLifecycle()
{
CHECK (!TestFrame::isDead (this));
CHECK (!TestFrame::isAlive (this));
CHECK (not TestFrame::isDead (this));
CHECK (not TestFrame::isAlive (this));
static char buffer[sizeof(TestFrame)];
TestFrame* frame = new(&buffer) TestFrame(23);
CHECK ( TestFrame::isAlive (frame));
CHECK (!frame->isDead());
CHECK (frame->isAlive());
CHECK (frame->isSane());
CHECK (not frame->isDead());
CHECK ( frame->isAlive());
CHECK ( frame->isValid());
frame->~TestFrame();
CHECK ( TestFrame::isDead (frame));
CHECK (!TestFrame::isAlive (frame));
CHECK ( TestFrame::isDead (frame));
CHECK (not TestFrame::isAlive (frame));
CHECK ( frame->isValid());
CHECK ( frame->isSane());
}
@ -151,8 +202,8 @@ namespace test {
{
thisFrames[i].swap (prevFrames[i]);
thisFrames[i].reset (new TestFrame(nr, i));
CHECK (thisFrames[i]->isSane());
CHECK (prevFrames[i]->isSane());
CHECK (thisFrames[i]->isPristine());
CHECK (prevFrames[i]->isPristine());
CHECK (prevFrames[i]->isAlive());
CHECK (*thisFrames[i] != *prevFrames[i]); // differs from predecessor within the same channel
@ -165,18 +216,18 @@ namespace test {
} } }
/** @test the table of test frames
* computed on demand */
/** @test the table of test frames computed on demand */
void
useFrameTable()
{
TestFrame& frX = testData(3,50);
TestFrame& frY = testData(3,25);
TestFrame& frZ = testData(3,50);
TestFrame& frX = testData(50,3);
TestFrame& frY = testData(50,2);
TestFrame& frZ = testData(50,3);
CHECK (frX.isSane());
CHECK (frY.isSane());
CHECK (frZ.isSane());
CHECK (frX.isPristine());
CHECK (frY.isPristine());
CHECK (frZ.isPristine());
CHECK (frX != frY);
CHECK (frX == frZ);
@ -185,14 +236,22 @@ namespace test {
CHECK (isSameObject (frX, frZ));
corruptMemory(&frZ,40,20);
CHECK (!frX.isSane());
CHECK (!testData(3,50).isSane());
CHECK ( testData(3,51).isSane());
CHECK ( testData(3,49).isSane());
CHECK (not frX.isPristine());
CHECK (not testData(50,3).isPristine());
CHECK ( testData(51,3).isPristine());
CHECK ( testData(49,3).isPristine());
char c = testData(49,3).data()[5]; // some arbitrary content
TestFrame::reseed();
CHECK ( testData(3,50).isSane());
CHECK ( testData(50,3).isPristine());
CHECK (c != testData(49,3).data()[5]); // content regenerated with different seed
TestFrame o{49,3}; // all data content is reproducible with the new seed
CHECK (not isSameObject(o, testData(49,3)));
CHECK (o == testData(49,3));
CHECK (o.data()[5] == testData(49,3).data()[5]);
}
};

View file

@ -12,7 +12,22 @@
* *****************************************************************/
/** @file testframe.cpp
** Implementation of fake data frames to support unit testing
** Implementation of fake data frames to support unit testing.
** The data generation is based on a _discriminator seed value,_
** which is computed as a linear combination of a statically fixed anchor-seed
** combined with the family-number and sequence number. Based on this seed,
** the contents are then filled by a pseudo-random sequence.
** @note while initially drawn from real entropy, the anchor-seed can be
** reset from the default PRNG, which allows to establish a totally
** deterministically setup from test code, because the test itself
** can seed the default PRNG and thus establish a reproducible state.
**
** Additionally, beyond this basic test-data feature, the contents can be
** manipulated freely, and a new checksum can be stored in the metadata,
** which allows to build pseudo media computation functions with a
** reproducible effect so that the proper invocation of several
** computation steps invoked deep down in the render engine can
** be verified after completing a test invocation.
*/
@ -31,8 +46,9 @@
namespace steam {
namespace engine {
namespace test {
namespace engine{
namespace test {
namespace err = lumiera::error;
using util::unConst;
using std::vector;
@ -105,7 +121,7 @@ namespace test {
stampHeader()
{
static const HashVal MARK = lib::entropyGen.hash()
| 0b1000'1000'1000'1000'1000'1000'1000'1000;
| 0b1000'1000'1000'1000'1000'1000'1000'1000; //////////////////////////////TICKET #722 : not portable because HashVal ≡ size_t — should it be?
return MARK;
}
@ -201,13 +217,7 @@ namespace test {
TestFrame&
testData (uint seqNr)
{
return accessTestFrame (seqNr, 0);
}
TestFrame&
testData (uint chanNr, uint seqNr)
testData (uint seqNr, uint chanNr)
{
return accessTestFrame (seqNr,chanNr);
}
@ -227,7 +237,7 @@ namespace test {
TestFrame::reseed()
{
testFrames.reset();
drawSeed (lib::defaultGen);
dataSeed = drawSeed (lib::defaultGen);
}
@ -251,8 +261,8 @@ namespace test {
TestFrame::TestFrame (uint seq, uint family)
: header_{seq,family}
{
buildData();
ASSERT (0 < header_.distinction);
header_.checksum = buildData();
ENSURE (CREATED == header_.stage);
ENSURE (isPristine());
}
@ -269,7 +279,7 @@ namespace test {
TestFrame::operator= (TestFrame const& o)
{
if (not isAlive())
throw new error::Logic ("target TestFrame already dead or unaccessible");
throw err::Logic ("target TestFrame already dead or unaccessible");
if (not util::isSameAdr (this, o))
{
data() = o.data();
@ -280,43 +290,41 @@ namespace test {
}
/**
* Sanity check on the metadata header.
* @remark Relevant to detect memory corruption or when accessing some
* arbitrary memory location, which may or may not actually hold a TestFrame.
* Based on the assumption that it is unlikely that some random memory location
* just happens to hold our [marker word](\ref stampHeader()).
* @note this is only the base level of verification, because in addition
* \ref isValid verifies the checksum and \ref isPristine additionally
* recomputes the data generation to see if it matches the Meta::distinction
*/
bool
TestFrame::Meta::isPlausible() const
{
return _MARK_ == stampHeader()
and stage <= DISCARDED;
}
TestFrame::Meta&
TestFrame::accessHeader()
{
if (not header_.isPlausible())
throw err::Invalid{"TestFrame: missing or corrupted metadata"};
return header_;
}
TestFrame::Meta const&
TestFrame::accessHeader() const
{
///////////////////////OOO detect if valid header present and else throw
return unConst(this)->accessHeader();
}
TestFrame::StageOfLife
TestFrame::currStage() const
{
///////////////////////OOO detect if valid header present and then access
}
/** @note performing an unchecked conversion of the given
* memory location to be accessed as TestFrame.
* The sanity of the data found at that location
* is checked as well, not only the lifecycle flag.
*/
bool
TestFrame::isAlive (void* memLocation)
{
TestFrame& candidate (accessAsTestFrame (memLocation));
return candidate.isSane()
&& candidate.isAlive();
}
bool
TestFrame::isDead (void* memLocation)
{
TestFrame& candidate (accessAsTestFrame (memLocation));
return candidate.isSane()
&& candidate.isDead();
return header_.isPlausible()? header_.stage
: DISCARDED;
}
bool
@ -327,67 +335,83 @@ namespace test {
&& candidate == *this;
}
bool
TestFrame::Meta::operator== (Meta const&o) const
{
return isPlausible() and o.isPlausible()
and stage == o.stage
and checksum == o.checksum
and distinction == o.distinction;
}
bool
TestFrame::contentEquals (TestFrame const& o) const
{
for (uint i=0; i<BUFFSIZ; ++i)
if (data()[i] != o.data()[i])
return false;
return true;
return header_ == o.header_
and data() == o.data();
}
HashVal
/**
* Generate baseline data content based on the Meta::distinction seed.
* @remark the seed is a [discriminator](\ref buildDiscriminator) based
* on both the »family« and the frameNo within this family;
* thus closely related frames are very unlikely to hold the same
* baseline data. Of course, follow-up manipulations could change
* the data, which should be documented by \ref markChecksum().
*/
void
TestFrame::buildData()
{
auto gen = buildDataGenFrom (accessHeader().distinction);
for (uint i=0; i<BUFFSIZ; ++i)
data()[i] = char(gen.i(CHAR_MAX));
for (char& dat : data())
dat = char(gen.i(CHAR_MAX));
markChecksum();
}
/** verify the current data was not touched since initialisation
* @remark implemented by regenerating the data sequence deterministically,
* based on the Meta::distinction mark recorded in the metadata.
*/
bool
TestFrame::verifyData() const
TestFrame::matchDistinction() const
{
auto gen = buildDataGenFrom (accessHeader().distinction);
for (uint i=0; i<BUFFSIZ; ++i)
if (data()[i] != char(gen.i(CHAR_MAX)))
for (char const& dat : data())
if (dat != char(gen.i(CHAR_MAX)))
return false;
return true;
}
/** @return a hash checksum computed over current data content */
HashVal
TestFrame::computeChecksum() const
{
HashVal hash{0};
////////////////////////////////////////////OOO actually compute it
HashVal checksum{0};
std::hash<char> getHash;
for (char const& dat : data())
lib::hash::combine (checksum, getHash (dat));
return checksum;
}
/** @remark can be used to mark a manipulated new content as _valid_ */
HashVal
TestFrame::markChecksum()
{
return accessHeader().checksum = computeChecksum();
}
bool
TestFrame::hasValidChecksum() const
{
////////////////////////////////////////////OOO actually compute checksum and verify
}
bool
TestFrame::isAlive() const
{
return (CREATED == currStage())
|| (EMITTED == currStage());
}
bool
TestFrame::isDead() const
{
return (DISCARDED == currStage());
return accessHeader().checksum == computeChecksum();
}
bool
TestFrame::isSane() const
{
return ( (CREATED == currStage())
||(EMITTED == currStage())
||(DISCARDED == currStage()))
&& verifyData();
return header_.isPlausible();
}
bool
@ -399,9 +423,42 @@ namespace test {
bool
TestFrame::isPristine() const
{
return isValid()
and matchDistinction();
}
bool
TestFrame::isAlive() const
{
return isSane()
and hasValidChecksum();
and not isDead();
}
bool
TestFrame::isDead() const
{
return isSane()
and (DISCARDED == currStage());
}
/** @note performing an unchecked conversion of the given
* memory location to be accessed as TestFrame.
* The sanity of the data found at that location
* is checked as well, not only the lifecycle flag.
*/
bool
TestFrame::isAlive (void* memLocation)
{
TestFrame& candidate (accessAsTestFrame (memLocation));
return candidate.isAlive();
}
bool
TestFrame::isDead (void* memLocation)
{
TestFrame& candidate (accessAsTestFrame (memLocation));
return candidate.isDead();
}

View file

@ -12,7 +12,21 @@
*/
/** @file testframe.hpp
** Unit test helper to generate fake test data frames
** Unit test helper to generate fake test data frames.
** Each TestFrame holds a 1k buffer of byte data, which can be
** verified, accessed and manipulated to emulate media computations.
** A [metadata header](\ref steam::engine::test::TestFrame::Meta) is placed
** in memory behind the working buffer, which allows to detect data corruption
** and stores a lifecycle phase and a data checksum.
**
** The contents of each TestFrame are filled on creation with pseudo-random data,
** which is created from a _discriminator seed,_ based on a »family« and a »frame-nr«
** within the family. Due to the deterministic nature of these computations, the
** _pristine state_ of any frame can be determined. But the payload data is accessible
** and can be manipulated, and a new [checksum can be recorded](\ref TestFrame::markChecksum).
**
** For ease of testing, a static store of TestFrame instances is maintained internally,
** and an arbitrary memory location can be treated as TestFrame.
*/
@ -68,6 +82,8 @@ namespace test {
StageOfLife stage;
Meta (uint seq, uint family);
bool isPlausible() const;
bool operator== (Meta const&) const;
};
/** inline storage buffer for the payload media data */
@ -86,6 +102,9 @@ namespace test {
TestFrame (TestFrame const&);
TestFrame& operator= (TestFrame const&);
/** recompute and store checksum based on current contents */
HashVal markChecksum();
/** Helper to verify that a given memory location holds
* an active TestFrame instance (created, not yet destroyed)
* @return true if the TestFrame datastructure is intact and
@ -114,8 +133,8 @@ namespace test {
private:
bool contentEquals (TestFrame const& o) const;
bool verifyData() const;
HashVal buildData();
bool matchDistinction() const;
void buildData();
Meta& accessHeader();
Meta const& accessHeader() const;
StageOfLife currStage() const;
@ -131,9 +150,7 @@ namespace test {
* test frames filled with different yet reproducible pseudo random data.
* Client code is free to access and corrupt this data.
*/
TestFrame& testData (uint seqNr);
TestFrame& testData (uint chanNr, uint seqNr);
TestFrame& testData (uint seqNr =0, uint chanNr =0);

View file

@ -17871,9 +17871,7 @@
<node CREATED="1654445417792" ID="ID_503426913" MODIFIED="1654445428132" TEXT="internes Layout pa&#xdf;t sich an..."/>
<node CREATED="1654445429888" ID="ID_1772582519" MODIFIED="1654445484446" TEXT="Zweck: visueller Hinweis auf die ScrollWindowPos">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
ScrollWindowPos == wo befindet sich das Scroll-Window (sichtbarer Ausschnitt) innerhalb eines gr&#246;&#223;eren Intervalles, welches vom Widget dargestellt wird
@ -18742,9 +18740,7 @@
</node>
<node COLOR="#435e98" CREATED="1664313525651" ID="ID_117097226" MODIFIED="1664313699335">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
<b>Fazit</b>: ja die L&#246;sung <font color="#6206ae">funktioniert</font>&#160;und erscheint stabil
@ -18996,9 +18992,7 @@
</node>
<node COLOR="#33565a" CREATED="1664726003283" ID="ID_249986815" MODIFIED="1664727540442" TEXT="show(Name)? &#x25a3;">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
auch hier mehrstufige Pr&#252;fung...
@ -19552,9 +19546,7 @@
<node CREATED="1665872106235" ID="ID_1051979214" MODIFIED="1665872117349" TEXT="es bietet Hooks an...">
<node CREATED="1665872129240" ID="ID_1784194423" MODIFIED="1665872322049" TEXT="f&#xfc;r die Layout-Steuerung">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<ul>
<li>
@ -20223,9 +20215,7 @@
<icon BUILTIN="broken-line"/>
<node COLOR="#435e98" CREATED="1666286814794" ID="ID_507527806" MODIFIED="1666367151520" TEXT="anscheinend wird der Event-Handler gar nicht aufgerufen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...den eingebauten Debug-Meldungen zufolge zu urteilen
@ -21451,9 +21441,7 @@
<node CREATED="1575558950482" ID="ID_1971888026" MODIFIED="1575566297637" TEXT="was f&#xfc;r M&#xf6;glichkeiten habe ich hier.....">
<node CREATED="1575558966759" ID="ID_1387494834" MODIFIED="1575559186143" TEXT="wer auch immer ViewHook&lt;Clip&gt; implementiert, mu&#xdf; die globale Referenz halten">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
wie ich's auch drehe und wende, daran f&#252;hrt kein Weg vorbei. Weil die Referenz eben nicht wirklich global ist, sondern einen root-Kontext darstellt (n&#228;mlich die umschlie&#223;ende Timeline).
@ -24436,9 +24424,7 @@
<node CREATED="1582992261608" ID="ID_647002044" MODIFIED="1582992271986" TEXT="Track-&gt;Fork-&gt;TimelineCanvas">
<node CREATED="1582992289786" ID="ID_478649023" MODIFIED="1582996676592">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
wird komplett erledigt durch <font color="#5c2549">TrackBody::<b>establishTrackSpace</b></font>
@ -42071,9 +42057,7 @@
</node>
<node CREATED="1670517051791" ID="ID_681227378" MODIFIED="1670517268759" TEXT="nur wirksam bei relativ kleiner Pixelzahl">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
hinreichend gro&#223;e Fenster (ab ein paar hunder Pixeln) k&#246;nnen die ganze Zeitdom&#228;ne abdecken
@ -43371,9 +43355,7 @@
<node CREATED="1670816990899" ID="ID_838942819" MODIFIED="1670817021017" TEXT="aber das wird immer auf 1001/LIM_HAZARD zur&#xfc;ck gerundet"/>
<node CREATED="1670817026420" ID="ID_425109455" MODIFIED="1670817157515" TEXT="obwohl man theoretisch daran vorbeikommen sollte">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<ul>
<li>
@ -44253,9 +44235,7 @@
</node>
<node CREATED="1669932728399" ID="ID_20790978" MODIFIED="1669932757508">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
man <b>mu&#223;</b>&#160;Floating-point runden wenn man glatte Werte will
@ -45937,9 +45917,7 @@
<icon BUILTIN="idea"/>
<node CREATED="1523020094460" ID="ID_950968515" MODIFIED="1557498707234">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
(GlobalCtx)-&gt;InteractionDirector-&gt;<b>Navigator</b>
@ -46086,9 +46064,7 @@
<icon BUILTIN="yes"/>
<node CREATED="1664669186884" ID="ID_458273565" MODIFIED="1664669799291" TEXT="BEM-Notation sinnvoll verwenden">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
block[__element][--modifier]
@ -46231,9 +46207,7 @@
<node CREATED="1448078381288" ID="ID_1570425925" MODIFIED="1518487921085" TEXT="state mark">
<node CREATED="1448078528725" ID="ID_1776152068" MODIFIED="1518487921085">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
vom <i>tangible </i>initiiert
@ -56402,8 +56376,9 @@
</html></richcontent>
<icon BUILTIN="messagebox_warning"/>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1701698621411" ID="ID_1690934543" MODIFIED="1731978172076" TEXT="Vorsicht: lib::hash::combine ist schwach">
<node BACKGROUND_COLOR="#d9d2e2" COLOR="#690f14" CREATED="1701698621411" FOLDED="true" ID="ID_1690934543" MODIFIED="1731987558928" TEXT="Vorsicht: lib::hash::combine ist schwach">
<icon BUILTIN="messagebox_warning"/>
<icon BUILTIN="button_cancel"/>
<node CREATED="1701698649934" ID="ID_1402802007" MODIFIED="1701698665460" TEXT="das ist die Fallback-Implementierung aus boost::hash"/>
<node CREATED="1701698666056" ID="ID_1059722984" MODIFIED="1701698723192" TEXT="boost::hash verwendet aber auf 64bit eine st&#xe4;rkere Impl">
<richcontent TYPE="NOTE"><html>
@ -56463,11 +56438,16 @@
</node>
</node>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1731987525974" ID="ID_890369638" MODIFIED="1731987552620" TEXT="lib::hash::combine ist jetzt die Boost-Impl (und 32bit sind kaputt)">
<icon BUILTIN="clanbomber"/>
</node>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1701698319632" ID="ID_1255956298" MODIFIED="1701698326482" TEXT="Bedeutung der Hash-Values">
<icon BUILTIN="hourglass"/>
<node CREATED="1701698328124" ID="ID_420862396" MODIFIED="1701698341086" TEXT="ein Zweck ist nat&#xfc;rlich: Hashtables"/>
<node CREATED="1701698342243" ID="ID_2662858" MODIFIED="1701698366532" TEXT="Invocation-Instance-ID &#x27fc; Cache-Keys"/>
<node CREATED="1731987573783" ID="ID_1292616947" MODIFIED="1731987583666" TEXT="Generieren von &#xbb;systematischen IDs&#xab;"/>
<node CREATED="1731987591582" ID="ID_208434005" MODIFIED="1731987598664" TEXT="Aber auch: erzeugen von UUIDs"/>
</node>
</node>
<node CREATED="1729977413447" ID="ID_683858939" MODIFIED="1729977421201" TEXT="Tests">
@ -56758,8 +56738,8 @@
</html></richcontent>
<arrowlink COLOR="#943e5b" DESTINATION="ID_939285679" ENDARROW="Default" ENDINCLINATION="-1142;-205;" ID="Arrow_ID_1632825391" STARTARROW="None" STARTINCLINATION="1971;131;"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1728786907104" ID="ID_142347061" MODIFIED="1731900709058" TEXT="Umbauten">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1728786907104" ID="ID_142347061" MODIFIED="1732076967655" TEXT="Umbauten">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1728786911759" ID="ID_1026206450" MODIFIED="1731900644399" TEXT="Basis-Seed in globale Variable">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1731895116455" ID="ID_1175003078" MODIFIED="1731900549018" TEXT="reseed-Operation">
@ -56777,8 +56757,7 @@
Diskriminator-ID &#8788; (<font color="#592cc8">seq</font>+1) * (<font color="#6c433b">dataSeed</font>+<font color="#6f0ed0">family</font>)
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1731943561624" ID="ID_1209671030" MODIFIED="1731943647377">
<richcontent TYPE="NODE"><html>
@ -56788,8 +56767,7 @@
Erl&#228;uterung: jede &#187;family&#171; hat ein eigenes<i>&#160;Stepping</i>
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1731943679360" ID="ID_1740781453" MODIFIED="1731943717151" TEXT="es kann trotzdem zu Kollisionen kommen &#x2014; das ist aber f&#xfc;r kleine seq-Nr unwahrscheinlich"/>
<node CREATED="1731943742648" ID="ID_594247384" MODIFIED="1731943827486" TEXT="gef&#xe4;hrlich w&#xe4;re DataSeed sehr klein oder nahe Max-uint">
@ -56800,8 +56778,7 @@
...weil es dann passieren k&#246;nnte, da&#223; f&#252;r bestimmte Familien die Frames sich nicht mehr unterscheiden
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
<node COLOR="#338800" CREATED="1731900560669" ID="ID_553408936" MODIFIED="1731900581648" TEXT="diesen aber ansonsten aus dem default / oder entropy-Generator ziehen">
@ -56820,17 +56797,17 @@
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728786946155" ID="ID_1878547941" MODIFIED="1728787040942" TEXT="Datenlayout und Alignment">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1728786946155" ID="ID_1878547941" MODIFIED="1732076308540" TEXT="Datenlayout und Alignment">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1730835658062" ID="ID_1432722861" MODIFIED="1730835681825" TEXT="festes 64bit-Alingment">
<linktarget COLOR="#5b9aaa" DESTINATION="ID_1432722861" ENDARROW="Default" ENDINCLINATION="63;7;" ID="Arrow_ID_1569718697" SOURCE="ID_1990276915" STARTARROW="None" STARTINCLINATION="61;0;"/>
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731944016612" ID="ID_1328551493" MODIFIED="1731944033914" TEXT="definiere Metadaten-Header">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1731944016612" ID="ID_1328551493" MODIFIED="1732076311665" TEXT="definiere Metadaten-Header">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731944023419" ID="ID_799758026" MODIFIED="1731944033915" TEXT="lege diesen hinter die Nutzdaten">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1731944023419" ID="ID_799758026" MODIFIED="1732076312763" TEXT="lege diesen hinter die Nutzdaten">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#338800" CREATED="1728787025826" ID="ID_1972770219" MODIFIED="1730835694593" TEXT="Accessor und Iteration">
@ -56851,12 +56828,14 @@
<icon BUILTIN="idea"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728786962056" ID="ID_231763184" MODIFIED="1728787040943" TEXT="Verifikations-Methoden">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1728786962056" ID="ID_231763184" MODIFIED="1732076307057" TEXT="Verifikations-Methoden">
<icon BUILTIN="button_ok"/>
<node CREATED="1728786973094" ID="ID_899991782" MODIFIED="1728786978286" TEXT="Datenpr&#xfc;fsumme">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731947548990" ID="ID_589371487" MODIFIED="1731947561331" TEXT="berechnen">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1731972983573" ID="ID_690852884" MODIFIED="1731972994119" TEXT="Technologie : Hash-Verkettung">
<node COLOR="#338800" CREATED="1731947548990" ID="ID_589371487" MODIFIED="1731987638572" TEXT="berechnen">
<icon BUILTIN="button_ok"/>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1731972983573" FOLDED="true" ID="ID_690852884" MODIFIED="1731987623395" TEXT="Technologie : Hash-Verkettung">
<icon BUILTIN="info"/>
<icon BUILTIN="messagebox_warning"/>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1731972995891" ID="ID_591783472" LINK="https://issues.lumiera.org/ticket/722" MODIFIED="1731973048277" TEXT="#722 : total verworrene Situation">
<icon BUILTIN="messagebox_warning"/>
</node>
@ -56874,26 +56853,26 @@
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731947552403" ID="ID_604836518" MODIFIED="1731947561332" TEXT="im Header hinterlegen">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1731947552403" ID="ID_604836518" MODIFIED="1732076298236" TEXT="im Header hinterlegen">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731947702842" ID="ID_745455518" MODIFIED="1731947715463" TEXT="pr&#xfc;fen">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1731947702842" ID="ID_745455518" MODIFIED="1732076299045" TEXT="pr&#xfc;fen">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node CREATED="1728786979373" ID="ID_772580400" MODIFIED="1728786987393" TEXT="Metadaten-Erkennung">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731947576264" ID="ID_767046037" MODIFIED="1731947717471" TEXT="Header-Stamp">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1731947576264" ID="ID_767046037" MODIFIED="1731987644829" TEXT="Header-Stamp">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731947640352" ID="ID_122461720" MODIFIED="1731947717470" TEXT="Header lokalisieren">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1731947640352" ID="ID_122461720" MODIFIED="1732076301202" TEXT="Header lokalisieren">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731947651342" ID="ID_1504134040" MODIFIED="1731947717470" TEXT="Plausibilit&#xe4;tspr&#xfc;fung">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1731947651342" ID="ID_1504134040" MODIFIED="1732076302206" TEXT="Plausibilit&#xe4;tspr&#xfc;fung">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node CREATED="1728786988308" ID="ID_103079985" MODIFIED="1728786992576" TEXT="Pr&#xe4;dikate">
<node CREATED="1728779817892" ID="ID_882765451" MODIFIED="1728779971755" TEXT="isSane">
<node COLOR="#338800" CREATED="1728779817892" ID="ID_882765451" MODIFIED="1732076303146" TEXT="isSane">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -56902,8 +56881,9 @@
</p>
</body>
</html></richcontent>
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1728779408099" ID="ID_1517743638" MODIFIED="1728779644910" TEXT="isValid">
<node COLOR="#338800" CREATED="1728779408099" ID="ID_1517743638" MODIFIED="1732076304073" TEXT="isValid">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -56912,8 +56892,9 @@
</p>
</body>
</html></richcontent>
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1728779415747" ID="ID_1413902264" MODIFIED="1728779750157" TEXT="isPristine">
<node COLOR="#338800" CREATED="1728779415747" ID="ID_1413902264" MODIFIED="1732076304854" TEXT="isPristine">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -56922,10 +56903,51 @@
</p>
</body>
</html></richcontent>
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1732076969096" ID="ID_1343558296" MODIFIED="1732077063323" TEXT="TestFrame_test erg&#xe4;nzen">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1732076980774" ID="ID_211524538" MODIFIED="1732076985614" TEXT="simpleUsage hinzuf&#xfc;gen">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1732076986438" ID="ID_1218578666" MODIFIED="1732077000535" TEXT="erweiterte Semantik der Verifikationen demonstrieren">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1732077001196" ID="ID_1390693953" MODIFIED="1732077007240" TEXT="direkten Datenzugriff testen">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1732077007955" ID="ID_1210655537" MODIFIED="1732077013546" TEXT="korrupten Header erkennen">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1732077014162" ID="ID_432187186" MODIFIED="1732077032047" TEXT="Zugriffsschutz bei korruptem Header demonstrieren">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1732077038422" ID="ID_1272545407" MODIFIED="1732077340288" TEXT="TestFrame::reseed() und reproduzierbare Daten">
<arrowlink COLOR="#7da6b6" DESTINATION="ID_677674501" ENDARROW="Default" ENDINCLINATION="516;0;" ID="Arrow_ID_487260711" STARTARROW="None" STARTINCLINATION="52;174;"/>
<icon BUILTIN="button_ok"/>
<node BACKGROUND_COLOR="#e0e9b0" COLOR="#338800" CREATED="1732077116460" HGAP="27" ID="ID_824130783" MODIFIED="1732077266626" TEXT="wer testet, der findet..." VSHIFT="5">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
frameNr und seqNr - Parameter waren vertauscht bei testData()
</p>
<p>
Das habe ich erst bemerkt, als ich tats&#228;chlich dazu noch einen frei stehenden TestFrame mit gleichen Koordinaten erzeugt und verglichen habe...
</p>
<p>
<font color="#c00d9b" size="2">GnaGnaGna</font>
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="smiley-oh"/>
</node>
</node>
</node>
</node>
</node>
<node CREATED="1729979079809" ID="ID_1106549131" MODIFIED="1729979157169" TEXT="Eigenschaften">
@ -56951,13 +56973,13 @@
</body>
</html></richcontent>
</node>
<node CREATED="1728778080366" ID="ID_538027040" MODIFIED="1728778216760" TEXT="kann Konsistenz und damit Korruption erkennen"/>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1728778477601" ID="ID_1982890559" MODIFIED="1729979127554" TEXT="direkter Zugang zu den Daten / Iteration">
<icon BUILTIN="hourglass"/>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1728778256504" ID="ID_761486398" MODIFIED="1729979130395" TEXT="Hash-Pr&#xfc;fsumme">
<icon BUILTIN="hourglass"/>
<node CREATED="1728779390394" ID="ID_641061651" MODIFIED="1728779648647" TEXT="damit weitere Zust&#xe4;nde">
<node COLOR="#435e98" CREATED="1728778080366" ID="ID_538027040" MODIFIED="1732077295197" TEXT="kann Konsistenz und damit Korruption erkennen"/>
<node COLOR="#435e98" CREATED="1728778477601" ID="ID_1982890559" MODIFIED="1732077290931" TEXT="direkter Zugang zu den Daten / Iteration"/>
<node COLOR="#338800" CREATED="1728778256504" ID="ID_761486398" MODIFIED="1732077298950" TEXT="Hash-Pr&#xfc;fsumme">
<icon BUILTIN="button_ok"/>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1728779390394" ID="ID_641061651" MODIFIED="1732077335099" TEXT="damit weitere Zust&#xe4;nde">
<arrowlink COLOR="#78aab5" DESTINATION="ID_1787108836" ENDARROW="Default" ENDINCLINATION="100;0;" ID="Arrow_ID_1535937187" STARTARROW="None" STARTINCLINATION="19;39;"/>
<icon BUILTIN="info"/>
<node CREATED="1728779817892" ID="ID_1087879898" MODIFIED="1728779971755" TEXT="isSane">
<richcontent TYPE="NOTE"><html>
<head/>
@ -57001,10 +57023,15 @@
</body>
</html></richcontent>
<icon BUILTIN="forward"/>
<node COLOR="#435e98" CREATED="1729979325605" ID="ID_1787108836" MODIFIED="1729979344957" TEXT="verifyBasicProperties"/>
<node COLOR="#435e98" CREATED="1732077082368" ID="ID_688942006" MODIFIED="1732077086288" TEXT="simpleUsage"/>
<node COLOR="#435e98" CREATED="1729979325605" ID="ID_1787108836" MODIFIED="1732077328386" TEXT="verifyDataContent">
<linktarget COLOR="#78aab5" DESTINATION="ID_1787108836" ENDARROW="Default" ENDINCLINATION="100;0;" ID="Arrow_ID_1535937187" SOURCE="ID_641061651" STARTARROW="None" STARTINCLINATION="19;39;"/>
</node>
<node COLOR="#435e98" CREATED="1729979325606" ID="ID_310206117" MODIFIED="1729979344958" TEXT="verifyFrameLifecycle"/>
<node COLOR="#435e98" CREATED="1729979325607" ID="ID_53249086" MODIFIED="1729979344958" TEXT="verifyFrameSeries"/>
<node COLOR="#435e98" CREATED="1729979325607" ID="ID_677674501" MODIFIED="1729979344958" TEXT="useFrameTable"/>
<node COLOR="#435e98" CREATED="1729979325607" ID="ID_677674501" MODIFIED="1732077340288" TEXT="useFrameTable">
<linktarget COLOR="#7da6b6" DESTINATION="ID_677674501" ENDARROW="Default" ENDINCLINATION="516;0;" ID="Arrow_ID_487260711" SOURCE="ID_1272545407" STARTARROW="None" STARTINCLINATION="52;174;"/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1730904143330" FOLDED="true" ID="ID_25783469" MODIFIED="1731864866245" TEXT="#1378 controlled random seed for tests">
@ -92272,11 +92299,11 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</html></richcontent>
</node>
<node CREATED="1728778080366" ID="ID_1631642281" MODIFIED="1728778216760" TEXT="kann Konsistenz und damit Korruption erkennen"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1728777587128" ID="ID_939285679" MODIFIED="1728786873689" TEXT="fehlt bisher">
<node COLOR="#435e98" CREATED="1728777587128" ID="ID_939285679" MODIFIED="1732077390669" TEXT="fehlt bisher">
<linktarget COLOR="#943e5b" DESTINATION="ID_939285679" ENDARROW="Default" ENDINCLINATION="-1142;-205;" ID="Arrow_ID_1632825391" SOURCE="ID_1372116679" STARTARROW="None" STARTINCLINATION="1971;131;"/>
<icon BUILTIN="broken-line"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728778245232" ID="ID_1565084791" MODIFIED="1728780108303" TEXT="ein kontrollierbarer Seeding-Mechanismus">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1728778245232" ID="ID_1565084791" MODIFIED="1732077388649" TEXT="ein kontrollierbarer Seeding-Mechanismus">
<icon BUILTIN="button_ok"/>
<node CREATED="1728777747523" ID="ID_179758750" MODIFIED="1728781968593" TEXT="verwendet bisher boost::random">
<icon BUILTIN="messagebox_warning"/>
</node>
@ -92342,7 +92369,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1728778599970" ID="ID_360776020" MODIFIED="1728778748251" TEXT="Layout und Alignment k&#xf6;nnten besser sein">
<node COLOR="#435e98" CREATED="1728778599970" ID="ID_360776020" MODIFIED="1732077394007" TEXT="Layout und Alignment k&#xf6;nnten besser sein">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -92352,9 +92379,13 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</body>
</html></richcontent>
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1731894841452" ID="ID_1246150422" MODIFIED="1731894867857" TEXT="Storage besser als Deque (damit Adressen stabil bleiben)"/>
<node CREATED="1728778765874" ID="ID_1342398369" MODIFIED="1728778778502" TEXT="der Metadatenblock sollte am Ende sein"/>
<node CREATED="1728778790871" ID="ID_92579679" MODIFIED="1728779021706" TEXT="Metadaten sollten optional sein">
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1731894841452" ID="ID_1246150422" MODIFIED="1732077402965" TEXT="Storage besser als Deque (damit Adressen stabil bleiben)">
<icon BUILTIN="flag-pink"/>
</node>
<node COLOR="#338800" CREATED="1728778765874" ID="ID_1342398369" MODIFIED="1732077408909" TEXT="der Metadatenblock sollte am Ende sein">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1728778790871" ID="ID_92579679" MODIFIED="1732077410923" TEXT="Metadaten sollten optional sein">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -92363,8 +92394,9 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</p>
</body>
</html></richcontent>
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1728779023048" ID="ID_1104714285" MODIFIED="1728779233787" TEXT="man sollte die Pr&#xfc;fsumme explizit markieren k&#xf6;nnen">
<node COLOR="#338800" CREATED="1728779023048" ID="ID_1104714285" MODIFIED="1732077413211" TEXT="man sollte die Pr&#xfc;fsumme explizit markieren k&#xf6;nnen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -92373,14 +92405,15 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</p>
</body>
</html></richcontent>
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728778477601" ID="ID_1156423837" MODIFIED="1728778494727" TEXT="direkter Zugang zu den Daten / Iteration">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1728778477601" ID="ID_1156423837" MODIFIED="1732077415016" TEXT="direkter Zugang zu den Daten / Iteration">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728778256504" ID="ID_602872488" MODIFIED="1728778284412" TEXT="Hash-Pr&#xfc;fsumme">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1728779390394" ID="ID_1699887806" MODIFIED="1728779648647" TEXT="damit weitere Zust&#xe4;nde">
<node COLOR="#338800" CREATED="1728778256504" ID="ID_602872488" MODIFIED="1732077417630" TEXT="Hash-Pr&#xfc;fsumme">
<icon BUILTIN="button_ok"/>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1728779390394" ID="ID_1699887806" MODIFIED="1732077442133" TEXT="damit weitere Verifikationen realisierbar...">
<node CREATED="1728779817892" ID="ID_1916046984" MODIFIED="1728779971755" TEXT="isSane">
<richcontent TYPE="NOTE"><html>
<head/>