diff --git a/tests/vault/gear/activity-detector-test.cpp b/tests/vault/gear/activity-detector-test.cpp
index d7ee3da0b..47fe352f1 100644
--- a/tests/vault/gear/activity-detector-test.cpp
+++ b/tests/vault/gear/activity-detector-test.cpp
@@ -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)
diff --git a/tests/vault/gear/activity-detector.hpp b/tests/vault/gear/activity-detector.hpp
index 1c9ef062f..69de4fc08 100644
--- a/tests/vault/gear/activity-detector.hpp
+++ b/tests/vault/gear/activity-detector.hpp
@@ -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
+ ...paßt perfekt hier; muß lediglich die elementaren Verifikations-Primitive hier verpacken, um semantisch relevante Elemente direkt zu prüfen +
+ +- ...allerdings liegt das an der Natur der logischen Negation selber, nicht an der unterstützung im Verifkations-Framework; ein Check ist eine Existenz-Aussage, und daher müßte zur Negation eine All-Aussage geprüft werden, durch eine erschöpfende Suche aller möglichen alternativen Prüf-Ketten. Ich hatte Fä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ützung im Verifkations-Framework; ein Check ist eine Existenz-Aussage, und daher müßte zur Negation eine All-Aussage geprüft werden, durch eine erschöpfende Suche aller möglichen alternativen Prü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ßend verifiziert habe, nur durch einzelne Testfälle geprüft)
@@ -81856,28 +81870,53 @@ Date: Thu Apr 20 18:53:17 2023 +0200+ ein Funktionsaufruf (typischwerweise von einem rigged-Functor) +
+ + +