Activity-Lang: complete first test verification tool

...now able to verify that arbitrary functions have been invoked
...all of this is still preparatory work
This commit is contained in:
Fischlurch 2023-08-15 02:23:40 +02:00
parent e3f1aa4f7c
commit 94528d67dc
3 changed files with 160 additions and 101 deletions

View file

@ -94,7 +94,10 @@ namespace test {
/** @test verify the setup and detection of instrumented invocations
* @todo WIP 7/23 define implement
* - a _sequence number_ is embedded into the ActivityDetector
* - this sequence number is recorded into an attribute at each invocation
* - a DSL for verification is provided (based on the EventLog)
* - arguments and sequence numbers can be explicitly checked
*/
void
verifyMockInvocation()
@ -107,7 +110,7 @@ namespace test {
CHECK (1 == detector.currSeq());
CHECK (detector.ensureNoInvocation ("funny"));
detector.markSequence();
++detector;
CHECK (2 == detector.currSeq());
CHECK (detector.verifySeqIncrement(2));
@ -117,13 +120,13 @@ namespace test {
CHECK (detector.verifyInvocation ("funny").seq(2));
CHECK (detector.verifyInvocation ("funny").arg(rnd).seq(2));
CHECK (detector.verifyInvocation ("funny").seq(2).arg(rnd));
CHECK (detector.ensureNoInvocation ("bunny"));
CHECK (detector.ensureNoInvocation ("funny").arg());
CHECK (detector.ensureNoInvocation ("funny").arg(-rnd));
CHECK (detector.ensureNoInvocation ("funny").seq(5));
CHECK (detector.ensureNoInvocation ("funny").arg(rnd).seq(1));
CHECK (detector.ensureNoInvocation ("bunny")); // wrong name
CHECK (detector.ensureNoInvocation ("funny").arg()); // fails since empty argument list expected
CHECK (detector.ensureNoInvocation ("funny").arg(rnd+5)); // expecting wrong argument
CHECK (detector.ensureNoInvocation ("funny").seq(5)); // expecting wrong sequence number
CHECK (detector.ensureNoInvocation ("funny").arg(rnd).seq(1)); // expecting correct argument, but wrong sequence
detector.markSequence();
++detector;
fun (rnd+1);
CHECK (detector.verifyInvocation ("funny").seq(2)
.beforeSeqIncrement(3)

View file

@ -31,12 +31,29 @@
** means of indirection and extension. As a remedy, a set of preconfigured
** _detector Activity records_ is provided, which drop off event log messages
** by side effect. These detector probes can be wired in as decorators into
** a otherwise valid Activity-Term, allowing to watch and verify patterns
** an otherwise valid Activity-Term, allowing to watch and verify patterns
** of invocation -- which might even happen concurrently.
**
** @todo WIP-WIP-WIP 7/2023 right now this is a rather immature attempt
** towards a scaffolding to propel the build-up of the scheduler.
**
** # Usage
**
** An ActivityDetector instance can be created in local storage to get an arsenal
** of probing tools and detectors, which are internally wired to record activation
** into an lib::test::EventLog embedded into the ActivityDetector instance. A
** _verification DSL_ is provided, internally relying on the building blocks and
** the chained-search mechanism known from the EventLog. To distinguish similar
** invocations and activations, a common _sequence number_ is maintained within
** the ActivityDetector instance, which can be incremented explicitly. All
** relevant events also capture the current sequence number as an attribute
** of the generated log record.
**
** ## Observation tools
** - ActivityDetector::buildDiadnosticFun(id) generates a functor object with
** _arbitrary signature,_ which records any invocation and arguments.
** The corresponding verification matcher is #verifyInvocation(id)
**
** @todo WIP-WIP-WIP 8/2023 gradually gaining traction.
** @see SchedulerActivity_test
** @see EventLog_test (demonstration of EventLog capbabilities)
*/
@ -97,40 +114,6 @@ namespace test {
// using vault::gear::JobClosure;
/** Marker for invocation sequence */
class Seq
{
uint step_;
public:
Seq (uint start =0)
: step_{start}
{ }
operator uint() const
{
return step_;
}
operator string() const
{
return util::toString (step_);
}
uint
operator++()
{
++step_;
return step_;
}
bool
operator== (Seq const& o)
{
return step_ == o.step_;
}
};
namespace {// Event markers
const string MARK_INC{"IncSeq"};
const string MARK_SEQ{"Seq"};
@ -139,6 +122,12 @@ namespace test {
class ActivityDetector;
/**
* @internal ongoing evaluation and match of observed activities.
* @remark this temporary object provides a builder API for creating
* chained verifications, similar to the usage of lib::test::EventLog.
* Moreover, it is convertible to `bool` to retrieve the verification result.
*/
class ActivityMatch
: private lib::test::EventMatch
{
@ -153,6 +142,10 @@ namespace test {
public:
// standard copy acceptable
/** final evaluation of the verification query,
* usually triggered from the unit test `CHECK()`.
* @note failure cause is printed to STDERR.
*/
operator bool() const { return _Parent::operator bool(); }
@ -178,7 +171,7 @@ namespace test {
// EventMatch& afterMatch (string regExp);
// EventMatch& afterEvent (string match);
// EventMatch& afterEvent (string classifier, string match);
// EventMatch& afterCall (string match);
ActivityMatch& afterInvocation (string match) { return delegate (&EventMatch::afterCall, move(match)); }
/** qualifier: additionally match the function arguments */
template<typename...ARGS>
@ -196,6 +189,7 @@ namespace test {
return *this;
}
/** special query to match an increment of the sequence number */
ActivityMatch&
beforeSeqIncrement (uint seqNr)
{
@ -203,7 +197,13 @@ namespace test {
return *this;
}
private:
/** @internal helper to delegate to the inherited matcher building blocks
* @note since ActivityMatch can only be created by ActivityDetector,
* we can be sure the EventMatch reference returned from these calls
* is actually a reference to `*this`, and can thus be downcasted.
* */
template<typename...ARGS>
ActivityMatch&
delegate (_Parent& (_Parent::*fun) (ARGS...), ARGS&& ...args)
@ -216,7 +216,11 @@ namespace test {
/**
* Diagnostic context to record and evaluate activations within the Scheduler.
* @todo WIP-WIP-WIP 7/23 a new loopy hope
* The provided tools and detectors are wired back internally, such as to record
* any observations into an lib::test::EventLog instance. Thus, after performing
* rigged functionality, the expected activities and their order can be verified.
* @see ActivityDetector_test
* @todo WIP-WIP-WIP 8/23 gradually building the verification tools needed...
*/
class ActivityDetector
: util::NonCopyable
@ -224,7 +228,7 @@ namespace test {
using EventLog = lib::test::EventLog;
EventLog eventLog_;
Seq invocationSeq_;
uint invocationSeq_;
/**
* A Mock functor, logging all invocations into the EventLog
@ -236,14 +240,14 @@ namespace test {
string id_;
EventLog* log_;
Seq const* seqNr_;
uint const* seqNr_;
RetVal retVal_;
public:
DiagnosticFun (string id, EventLog& masterLog, Seq const& seqNr)
DiagnosticFun (string id, EventLog& masterLog, uint const& invocationSeqNr)
: id_{id}
, log_{&masterLog}
, seqNr_{&seqNr}
, seqNr_{&invocationSeqNr}
, retVal_{}
{ }
@ -261,7 +265,7 @@ namespace test {
operator() (ARGS const& ...args)
{
log_->call (log_->getID(), id_, args...)
.addAttrib (MARK_SEQ, *seqNr_);
.addAttrib (MARK_SEQ, util::toString(*seqNr_));
return *retVal_;
}
};
@ -278,6 +282,15 @@ namespace test {
return util::join (eventLog_);
}
string
showLog() const
{
return "\n____Event-Log___________________________\n"
+ util::join (eventLog_, "\n")
+ "\n────╼━━━━━━━━╾──────────────────────────"
;
}
void
clear(string newID)
{
@ -287,11 +300,12 @@ namespace test {
eventLog_.clear (newID);
}
/** increment the internal invocation sequence number */
uint
operator++()
{
++invocationSeq_;
eventLog_.event (MARK_INC, invocationSeq_);
eventLog_.event (MARK_INC, util::toString(invocationSeq_));
return invocationSeq_;
}
@ -301,12 +315,6 @@ namespace test {
return invocationSeq_;
}
uint
markSequence()
{
return operator++();
}
/**
* Generic testing helper: build a λ-mock, logging all invocations
@ -348,16 +356,6 @@ namespace test {
}
string
showLog() const
{
return "\n____Event-Log___________________________\n"
+ util::join (eventLog_, "\n")
+ "\n────╼━━━━━━━━╾──────────────────────────"
;
}
private:
};

View file

@ -79423,14 +79423,14 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1689200449333" ID="ID_386403564" MODIFIED="1689200453433" TEXT="usage scenarios"/>
</node>
<node CREATED="1689201354393" HGAP="24" ID="ID_1250518280" MODIFIED="1689201365333" TEXT="Hilfsmittel" VSHIFT="2">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689201660559" ID="ID_747497995" MODIFIED="1689201666007" TEXT="ActivityDetector">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1689201660559" ID="ID_747497995" MODIFIED="1692057369715" TEXT="ActivityDetector">
<icon BUILTIN="pencil"/>
<node CREATED="1689201667734" ID="ID_901153159" MODIFIED="1689201676495" TEXT="speziell verdrahtete Activity">
<icon BUILTIN="info"/>
<node CREATED="1689201677836" ID="ID_166879509" MODIFIED="1689201693231" TEXT="kann ihre Aktivierung dokumentieren"/>
<node CREATED="1689201999161" ID="ID_554259263" MODIFIED="1689202008524" TEXT="kann Gate-Verhalten aufzeichnen"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689202062345" ID="ID_373470992" MODIFIED="1689202169154" TEXT="implementiert als eigenst&#xe4;ndiges Test-Hilfsmittel">
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1689202062345" ID="ID_373470992" MODIFIED="1692057818268" TEXT="implementiert als eigenst&#xe4;ndiges Test-Hilfsmittel">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -79439,11 +79439,19 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</p>
</body>
</html></richcontent>
<arrowlink COLOR="#5f8998" DESTINATION="ID_284088835" ENDARROW="Default" ENDINCLINATION="347;-1232;" ID="Arrow_ID_1573724609" STARTARROW="None" STARTINCLINATION="634;35;"/>
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1689202013167" ID="ID_1086517923" MODIFIED="1689202038445" TEXT="Idee: EventLog verwenden?">
<node COLOR="#435e98" CREATED="1689202013167" ID="ID_1086517923" MODIFIED="1692057436906" TEXT="Idee: EventLog verwenden?">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...pa&#223;t perfekt hier; mu&#223; lediglich die elementaren Verifikations-Primitive hier verpacken, um semantisch relevante Elemente direkt zu pr&#252;fen
</p>
</body>
</html></richcontent>
<icon BUILTIN="idea"/>
<icon BUILTIN="help"/>
</node>
</node>
</node>
@ -81640,6 +81648,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689204967974" ID="ID_284088835" MODIFIED="1690070044262" TEXT="ActivityDetector">
<linktarget COLOR="#794f4b" DESTINATION="ID_284088835" ENDARROW="Default" ENDINCLINATION="-685;-107;" ID="Arrow_ID_1213725911" SOURCE="ID_1647246120" STARTARROW="None" STARTINCLINATION="518;48;"/>
<linktarget COLOR="#5f8998" DESTINATION="ID_284088835" ENDARROW="Default" ENDINCLINATION="347;-1232;" ID="Arrow_ID_1573724609" SOURCE="ID_373470992" STARTARROW="None" STARTINCLINATION="634;35;"/>
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1689204985122" ID="ID_1020676746" MODIFIED="1690832427037" TEXT="Rahmen schaffen">
<icon BUILTIN="pencil"/>
@ -81673,7 +81682,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node COLOR="#435e98" CREATED="1690832539878" ID="ID_1163728085" MODIFIED="1690832566800" TEXT="Problem: brauche einen generischen Funktor mit vorgegebener Signatur">
<icon BUILTIN="messagebox_warning"/>
</node>
<node COLOR="#435e98" CREATED="1690832634093" ID="ID_1752068820" MODIFIED="1690832811893" TEXT="Problem&#xb2;: _Fun liefert Types&lt;ARGS...&gt;">
<node COLOR="#435e98" CREATED="1690832634093" FOLDED="true" ID="ID_1752068820" MODIFIED="1690832811893" TEXT="Problem&#xb2;: _Fun liefert Types&lt;ARGS...&gt;">
<icon BUILTIN="messagebox_warning"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1690832673285" ID="ID_1336668998" MODIFIED="1690832758349" TEXT="daraus kann ich nicht ohne Weiteres einen Funktions-Operator gewinnen">
<richcontent TYPE="NOTE"><html>
@ -81727,12 +81736,12 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1689205029658" ID="ID_1144318045" MODIFIED="1690918967997" TEXT="Verifikationen">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1690899802680" ID="ID_383665548" MODIFIED="1690899840591" TEXT="Problem: zweifelsfreie Verifikation im Log">
<node COLOR="#435e98" CREATED="1690899802680" ID="ID_383665548" MODIFIED="1692053471680" TEXT="Problem: zweifelsfreie Verifikation im Log">
<icon BUILTIN="messagebox_warning"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1690899845778" ID="ID_527585169" MODIFIED="1690899886750" TEXT="mu&#xdf; fehl-Matches vermeiden">
<icon BUILTIN="clanbomber"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1690899868436" ID="ID_1034519064" MODIFIED="1690899890797" TEXT="Log sollte idealerweise komplett verifizierbar sein">
<node COLOR="#435e98" CREATED="1690899868436" ID="ID_1034519064" MODIFIED="1692053475620" TEXT="Log sollte idealerweise komplett verifizierbar sein">
<icon BUILTIN="yes"/>
</node>
<node COLOR="#435e98" CREATED="1690899789651" ID="ID_495093897" MODIFIED="1690918956649" TEXT="eine Sequenz-Nummer einf&#xfc;hren">
@ -81740,18 +81749,23 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1690899895228" ID="ID_689471700" MODIFIED="1690899900231" TEXT="an die Instanz gebunden"/>
<node CREATED="1690899900699" ID="ID_1842080361" MODIFIED="1690899905547" TEXT="damit 100% reproduzierbar"/>
<node CREATED="1690899906154" ID="ID_350339048" MODIFIED="1690899917269" TEXT="impliziert eine Aufruf-Sequenz"/>
<node COLOR="#338800" CREATED="1690900159528" ID="ID_689193567" MODIFIED="1690918955037" TEXT="Wrapper-Typ verwenden (keinen primitiven Typ)">
<node COLOR="#5b280f" CREATED="1690900159528" ID="ID_689193567" MODIFIED="1692054827928" TEXT="Wrapper-Typ verwenden (keinen primitiven Typ)">
<icon BUILTIN="button_ok"/>
<icon BUILTIN="button_cancel"/>
<node CREATED="1692054834915" ID="ID_1421903109" MODIFIED="1692054857935" TEXT="gute L&#xf6;sung &#x2014; aber nicht mehr notwendig"/>
<node CREATED="1692054858501" ID="ID_1232436461" MODIFIED="1692054880032" TEXT="durch die Test-DSL stets eindeutig"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1690899920322" ID="ID_67461983" MODIFIED="1691967256168" TEXT="den Einzel-Aufruf mit der Sequenz-Nummer markieren">
<node COLOR="#435e98" CREATED="1690899920322" ID="ID_67461983" MODIFIED="1692053481500" TEXT="den Einzel-Aufruf mit der Sequenz-Nummer markieren">
<arrowlink COLOR="#fddadc" DESTINATION="ID_67251959" ENDARROW="Default" ENDINCLINATION="250;-68;" ID="Arrow_ID_996698966" STARTARROW="None" STARTINCLINATION="142;7;"/>
<icon BUILTIN="idea"/>
</node>
</node>
</node>
<node CREATED="1691876350208" ID="ID_105178925" MODIFIED="1691876353502" TEXT="Test-DSL">
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1691876526510" ID="ID_1716550315" MODIFIED="1691876762417" TEXT="RLY?">
<node CREATED="1691876350208" ID="ID_105178925" MODIFIED="1692057162964" TEXT="Test-DSL">
<icon BUILTIN="info"/>
<node COLOR="#435e98" CREATED="1691876526510" FOLDED="true" ID="ID_1716550315" MODIFIED="1692053499368" TEXT="RLY?">
<icon BUILTIN="help"/>
<icon BUILTIN="yes"/>
<node CREATED="1691876547403" ID="ID_513238141" MODIFIED="1691876555015" TEXT="das hier ist ein single-use-setup">
<icon BUILTIN="messagebox_warning"/>
</node>
@ -81814,8 +81828,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1692022438369" ID="ID_1637851255" MODIFIED="1692022901645" TEXT="negativ-Checks unterst&#xfc;tzen">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1692022438369" ID="ID_1637851255" MODIFIED="1692034017019" TEXT="negativ-Checks unterst&#xfc;tzen">
<icon BUILTIN="button_ok"/>
<node CREATED="1692022449108" ID="ID_1801262965" MODIFIED="1692022587083">
<richcontent TYPE="NODE"><html>
<head/>
@ -81834,12 +81848,12 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</body>
</html></richcontent>
</node>
<node CREATED="1692022627772" ID="ID_13278224" MODIFIED="1692022860849" TEXT="sowas ist offensichtlich plausibel &#x2014; aber auch problematisch">
<node CREATED="1692022627772" ID="ID_13278224" MODIFIED="1692034088880" TEXT="sowas ist offensichtlich plausibel &#x2014; aber nicht trivial">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...allerdings liegt das an der Natur der logischen Negation selber, nicht an der unterst&#252;tzung im Verifkations-Framework; ein Check ist eine Existenz-Aussage, und daher m&#252;&#223;te zur Negation eine All-Aussage gepr&#252;ft werden, durch eine ersch&#246;pfende Suche aller m&#246;glichen alternativen Pr&#252;f-Ketten. Ich hatte F&#228;lle, in denen das durchaus vorhandene Backtracking das nicht leisten konnte
...allerdings liegt das an der Natur der logischen Negation selber, nicht an der unterst&#252;tzung im Verifkations-Framework; ein Check ist eine Existenz-Aussage, und daher m&#252;&#223;te zur Negation eine All-Aussage gepr&#252;ft werden, durch eine ersch&#246;pfende Suche aller m&#246;glichen alternativen Pr&#252;f-Ketten. Anfangs habe ich das nicht gemacht, aber 9/2018 habe ich richtiges Backtracking eingebaut; damit sollte das nun korrekt funktionieren (was ich aber nie abschlie&#223;end verifiziert habe, nur durch einzelne Testf&#228;lle gepr&#252;ft)
</p>
</body>
</html></richcontent>
@ -81856,28 +81870,53 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node CREATED="1692053606731" ID="ID_1933077437" MODIFIED="1692053612252" TEXT="Elemente">
<node CREATED="1692053562969" ID="ID_962655454" MODIFIED="1692053567405" TEXT="Einstieg">
<node CREATED="1692053568231" ID="ID_784483169" MODIFIED="1692053593488" TEXT="verify&lt;XXX&gt;"/>
<node CREATED="1692053572759" ID="ID_918717888" MODIFIED="1692053589493" TEXT="ensureNo&lt;XXX&gt;"/>
</node>
<node CREATED="1690899978840" ID="ID_70827658" MODIFIED="1690899987515" TEXT="einen Funktionsaufruf verifizieren">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1690900023906" ID="ID_1470650457" MODIFIED="1690918796008" TEXT="markSequence()">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1692053614738" ID="ID_906593629" MODIFIED="1692053626611" TEXT="Verkettung">
<node CREATED="1692053627648" ID="ID_1007664705" MODIFIED="1692053636288" TEXT="before&lt;XXX&gt;"/>
<node CREATED="1692053636959" ID="ID_649601465" MODIFIED="1692053644833" TEXT="after&lt;XXX&gt;"/>
</node>
<node CREATED="1692053678701" ID="ID_928530756" MODIFIED="1692053682004" TEXT="Verifikationen">
<node CREATED="1692053683256" ID="ID_1535852650" MODIFIED="1692057066275" TEXT="Invocation">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
ein Funktionsaufruf (typischwerweise von einem rigged-Functor)
</p>
</body>
</html></richcontent>
<arrowlink COLOR="#4a425e" DESTINATION="ID_70827658" ENDARROW="Default" ENDINCLINATION="-42;-73;" ID="Arrow_ID_578101667" STARTARROW="None" STARTINCLINATION="-243;46;"/>
</node>
</node>
</node>
</node>
<node COLOR="#435e98" CREATED="1690899978840" ID="ID_70827658" MODIFIED="1692057153084" TEXT="einen Funktionsaufruf verifizieren">
<linktarget COLOR="#4a425e" DESTINATION="ID_70827658" ENDARROW="Default" ENDINCLINATION="-42;-73;" ID="Arrow_ID_578101667" SOURCE="ID_1535852650" STARTARROW="None" STARTINCLINATION="-243;46;"/>
<icon BUILTIN="forward"/>
<node COLOR="#338800" CREATED="1690900023906" ID="ID_1470650457" MODIFIED="1692034143231" TEXT="markSequence()">
<icon BUILTIN="button_ok"/>
<node CREATED="1691967036611" ID="ID_1281722986" MODIFIED="1691967047702" TEXT="was bedeutet das &#xfc;berhaupt?"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1691967048250" ID="ID_1226565848" MODIFIED="1691967068615" TEXT="Ansatz: eine interne Sequenznummer hochsetzen">
<node COLOR="#435e98" CREATED="1691967048250" ID="ID_1226565848" MODIFIED="1692034118800" TEXT="Ansatz: eine interne Sequenznummer hochsetzen">
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1691967069495" ID="ID_67251959" MODIFIED="1691967245462" TEXT="wie/wo kann die zuverl&#xe4;ssig gepr&#xfc;ft werden?">
<node COLOR="#435e98" CREATED="1691967069495" ID="ID_67251959" MODIFIED="1692034115613" TEXT="wie/wo kann die zuverl&#xe4;ssig gepr&#xfc;ft werden?">
<linktarget COLOR="#fddadc" DESTINATION="ID_67251959" ENDARROW="Default" ENDINCLINATION="250;-68;" ID="Arrow_ID_996698966" SOURCE="ID_67461983" STARTARROW="None" STARTINCLINATION="142;7;"/>
<icon BUILTIN="help"/>
<node COLOR="#5b280f" CREATED="1691967116385" ID="ID_1378863406" MODIFIED="1691967128672" TEXT="erste Idee: zus&#xe4;tzliche Eintr&#xe4;ge im Log">
<node COLOR="#5b280f" CREATED="1691967116385" FOLDED="true" ID="ID_1378863406" MODIFIED="1692057197043" TEXT="erste Idee: zus&#xe4;tzliche Eintr&#xe4;ge im Log">
<icon BUILTIN="button_cancel"/>
<node CREATED="1691967129967" ID="ID_904829426" MODIFIED="1691967134017" TEXT="einfach umzusetzen"/>
<node CREATED="1691967134523" ID="ID_564127342" MODIFIED="1691967140537" TEXT="aber umst&#xe4;ndlich in der Handhabung"/>
<node CREATED="1691967149276" ID="ID_291271617" MODIFIED="1691967157215" TEXT="und noch schlimmer: nicht eindeutig"/>
<node CREATED="1691967141625" ID="ID_1932163820" MODIFIED="1691967147977" TEXT="und m&#xfc;llt das Log zu"/>
</node>
<node CREATED="1691967161499" ID="ID_368230212" MODIFIED="1691967174065" TEXT="das strukturierte EventLog nutzen">
<node COLOR="#435e98" CREATED="1691967161499" ID="ID_368230212" MODIFIED="1692057203746" TEXT="das strukturierte EventLog nutzen">
<icon BUILTIN="idea"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1691967175689" ID="ID_746233199" MODIFIED="1691967185000" TEXT="Attribut &quot;Seq&quot; einf&#xfc;hren">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1691967175689" FOLDED="true" ID="ID_746233199" MODIFIED="1692057208657" TEXT="Attribut &quot;Seq&quot; einf&#xfc;hren">
<icon BUILTIN="button_ok"/>
<node CREATED="1691967277027" ID="ID_1776684493" MODIFIED="1691967284636" TEXT="Problem: Logging API">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1691967309343" ID="ID_244666662" MODIFIED="1691967318610" TEXT="hat typischerweise bereits eine offene Argumentliste"/>
@ -81895,13 +81934,19 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1691967188541" ID="ID_190903532" MODIFIED="1691967210908" TEXT="dieses dann per Zusatz-Match pr&#xfc;fbar machen">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1691967188541" ID="ID_190903532" MODIFIED="1692034109205" TEXT="dieses dann per Zusatz-Match pr&#xfc;fbar machen">
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1692034126251" ID="ID_1071125044" MODIFIED="1692034134849" TEXT="Eintrag im Log hinterlassen">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#5b280f" CREATED="1690900069493" ID="ID_917256156" MODIFIED="1691966998192" TEXT="verifyInvocation(fun, Seq(i), args...)">
<node COLOR="#338800" CREATED="1692034135474" ID="ID_1900678596" MODIFIED="1692034140342" TEXT="diesen &#xfc;berpr&#xfc;fbar machen">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#5b280f" CREATED="1690900069493" FOLDED="true" ID="ID_917256156" MODIFIED="1691966998192" TEXT="verifyInvocation(fun, Seq(i), args...)">
<icon BUILTIN="button_cancel"/>
<node COLOR="#5b280f" CREATED="1691622557790" ID="ID_307528565" MODIFIED="1691966784058" TEXT="lenient arguments?">
<icon BUILTIN="help"/>
@ -81934,10 +81979,11 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1690900069493" ID="ID_1755197034" MODIFIED="1691967022305" TEXT="verifyInvocation(fun).args(args...).seq(i)">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1692022948289" ID="ID_1815506838" MODIFIED="1692022990708" TEXT="unerwartete Konversion &#x27fc; unsigned">
<node COLOR="#338800" CREATED="1690900069493" ID="ID_1755197034" MODIFIED="1692034147917" TEXT="verifyInvocation(fun).args(args...).seq(i)">
<icon BUILTIN="button_ok"/>
<node COLOR="#5b280f" CREATED="1692022948289" FOLDED="true" ID="ID_1815506838" MODIFIED="1692057190630" TEXT="unerwartete Konversion &#x27fc; unsigned">
<icon BUILTIN="broken-line"/>
<icon BUILTIN="button_cancel"/>
<node CREATED="1692023011767" ID="ID_1384711805" MODIFIED="1692023028638">
<richcontent TYPE="NODE"><html>
<head/>
@ -81959,6 +82005,18 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</html></richcontent>
<icon BUILTIN="info"/>
</node>
<node COLOR="#338800" CREATED="1692054307541" ID="ID_1769927803" MODIFIED="1692054409990" TEXT="works as designed: rnd ist als uint definiert">
<icon BUILTIN="smiley-oh"/>
</node>
</node>
<node COLOR="#338800" CREATED="1692057091775" ID="ID_740116196" MODIFIED="1692057109965" TEXT="Verifikation der Sequenznummer direkt als Attribut">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1692057111589" ID="ID_1585757937" MODIFIED="1692057117532" TEXT="Verifikation der Argumente">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1692057121026" ID="ID_497674613" MODIFIED="1692057142215" TEXT="Verifikation mehrerer Aufrufe mit Reihenfolge und verschiedener Sequenznummer">
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>