85 CHECK (55 == trap (1.23,
Time{FSecs{3,2}}));
87 CHECK (detector ==
"Rec(EventLogHeader| this = ActivityDetector(spectre) ), " 88 "Rec(call| fun = trap, this = ActivityDetector(spectre), Seq = 0 |{1.23, 0:00:01.500})"_expect);
104 uint rnd = rand() % 10000;
107 CHECK (1 == detector.currSeq());
108 CHECK (detector.ensureNoInvocation (
"funny"));
111 CHECK (2 == detector.currSeq());
112 CHECK (detector.verifySeqIncrement(2));
115 CHECK (detector.verifyInvocation (
"funny"));
116 CHECK (detector.verifyInvocation (
"funny").
arg(rnd));
117 CHECK (detector.verifyInvocation (
"funny").
seq(2));
118 CHECK (detector.verifyInvocation (
"funny").
arg(rnd).
seq(2));
119 CHECK (detector.verifyInvocation (
"funny").
seq(2).
arg(rnd));
120 CHECK (detector.ensureNoInvocation (
"bunny"));
121 CHECK (detector.ensureNoInvocation (
"funny").
arg());
122 CHECK (detector.ensureNoInvocation (
"funny").
arg(rnd+5));
123 CHECK (detector.ensureNoInvocation (
"funny").
seq(5));
124 CHECK (detector.ensureNoInvocation (
"funny").
arg(rnd).
seq(1));
128 CHECK (detector.verifyInvocation (
"funny").
seq(2)
130 .beforeInvocation (
"funny").
seq(3).
arg(rnd+1));
132 CHECK (detector ==
"Rec(EventLogHeader| this = ActivityDetector )" 133 ", Rec(event| ID = IncSeq |{1})" 134 ", Rec(event| ID = IncSeq |{2})" 135 ", Rec(call| fun = funny, this = ActivityDetector, Seq = 2 |{"+util::toString(rnd)+
"})" 136 ", Rec(event| ID = IncSeq |{3})" 137 ", Rec(call| fun = funny, this = ActivityDetector, Seq = 3 |{"+util::toString(rnd+1)+
"})"_expect);
150 uint rnd = rand() % 10000;
152 CHECK (0 == fun (rnd));
156 CHECK (42 == fun (rnd));
158 fun.implementedAs ([](uint i){
return -i; });
160 CHECK (-
int(rnd) == fun (rnd));
162 CHECK (detector.verifyInvocation(
"fakeFun").
seq(0)
163 .beforeInvocation(
"fakeFun").
seq(1)
164 .beforeInvocation(
"fakeFun").
seq(2));
181 Time nominal{FSecs{5,2}};
184 Job dummyJob{detector.buildMockJobFunctor (
"mockJob")
188 CHECK (detector.ensureNoInvocation (
"mockJob"));
189 dummyJob.triggerJob();
190 CHECK (detector.verifyInvocation (
"mockJob"));
191 CHECK (detector.verifyInvocation (
"mockJob").
arg(nominal, invoKey.part.a));
192 CHECK (detector.verifyInvocation (
"mockJob").
timeArg(nominal));
196 dummyJob.triggerJob();
198 CHECK (detector.verifyInvocation (
"mockJob").
timeArg(nominal).
seq(0)
199 .beforeInvocation (
"mockJob").
timeArg(nominal +
Time{FSecs{5}})
200 .afterSeqIncrement(1)
216 auto& ctx = detector.executionCtx;
218 activity::_verify_usable_as_ExecutionContext<decltype(detector.executionCtx)>();
225 CHECK (detector.ensureNoInvocation(CTX_WORK));
226 CHECK (detector.ensureNoInvocation(CTX_POST));
227 CHECK (detector.ensureNoInvocation(CTX_DONE));
228 CHECK (detector.ensureNoInvocation(CTX_TICK));
231 CHECK (detector.verifyInvocation(CTX_WORK).
arg(t,x));
234 CHECK (detector.verifyInvocation(CTX_DONE).
arg(t,x));
236 CHECK (activity::PASS == ctx.post (t,td, &a, ctx));
237 CHECK (detector.verifyInvocation(CTX_POST).
arg(t,td,&a,ctx));
239 CHECK (activity::PASS == ctx.tick(t));
240 CHECK (detector.verifyInvocation(CTX_TICK).
arg(t));
243 ctx.tick.returning(activity::KICK);
244 CHECK (activity::KICK == ctx.tick(t));
245 CHECK (detector.verifyInvocation(CTX_TICK).
timeArg(t));
247 CHECK (detector.verifyInvocation(CTX_WORK).
timeArg(t)
248 .beforeInvocation(CTX_DONE).
timeArg(t)
249 .beforeInvocation(CTX_POST).
timeArg(t)
251 .beforeInvocation(CTX_TICK).
timeArg(t).
seq(1));
262 auto someID =
"trap-" + randStr(4);
266 CHECK (not detector.wasInvoked (probe));
268 Time realTime = RealClock::now();
269 probe.
activate (realTime, detector.executionCtx);
271 CHECK (detector.verifyInvocation(someID).
timeArg(realTime));
274 CHECK (realTime == detector.invokeTime (probe));
275 CHECK (detector.wasInvoked (probe));
288 Activity feed{
size_t{12},
size_t{34}};
289 Activity feed2{
size_t{56},
size_t{78}};
291 string jobID =
"job-" + randStr(4);
292 Activity invoke{detector.buildMockJobFunctor(jobID), nomTime, feed};
295 CHECK (activity::PASS == invoke.activate (t1, detector.executionCtx));
296 CHECK (detector.verifyInvocation (jobID).
arg(nomTime, 12));
300 CHECK (tap.next == invoke.next);
305 tap.activate(t2, detector.executionCtx);
306 CHECK (detector.verifySeqIncrement(1)
307 .beforeInvocation(
"tap-INVOKE").
seq(1).
arg(
"JobFun-ActivityDetector."+jobID)
308 .beforeInvocation(jobID).
seq(1).
arg(nomTime,12));
313 invoke.activate (t3, detector.executionCtx);
314 CHECK (detector.verifyInvocation(jobID).
seq(2));
315 CHECK (detector.ensureNoInvocation(
"tap-INVOKE").
seq(2)
316 .beforeInvocation(jobID).
seq(2));
329 Activity followUp{size_t(1), size_t(2)};
330 subject.
next = &followUp;
332 CHECK (isSameObject (*wiring, subject));
336 CHECK (not isSameObject (*wiring, subject));
338 CHECK (wiring->data_.callback.arg ==
size_t(&subject));
339 CHECK (wiring->
next == subject.
next);
343 wiring->
activate(tt, detector.executionCtx);
344 CHECK (detector.verifyInvocation(
"tap-TICK").
arg(
"⧐ Act(TICK")
345 .beforeInvocation(
"CTX-tick").
timeArg(tt));
372 CHECK (gate.data_.condition.rest == 1);
376 notification.
activate (tt, detector.executionCtx);
378 CHECK (detector.verifyInvocation(
"CTX-post").
arg(
"22.022",
"33.033",
"tap-GATE",
"≺test::CTX≻"));
383 notification.data_.notification.target->dispatch (ts, detector.executionCtx);
384 CHECK (detector.verifyInvocation(
"tap-GATE").
seq(1).
arg(
"22.022 --notify-↯> Act(GATE"));
385 CHECK (gate.data_.condition.rest == 0);
406 gate.
next = &followUp;
409 detector.watchGate (wiring);
412 wiring->
activate(tt, detector.executionCtx);
416 CHECK (detector.verifyInvocation(
"tap-GATE").
seq(0).
timeArg(tt)
418 .beforeInvocation(
"after-GATE").
seq(1).
timeArg(tt)
419 .beforeInvocation(
"CTX-tick").
seq(1).
timeArg(tt));
Record to describe an Activity, to happen within the Scheduler's control flow.
void insert_ActivationTap()
void verifyFakeInvocation()
void watch_ActivationProbe()
void watch_ActivationTap()
Activity & insertActivationTap(Activity *&wiring, string id="")
build ActivationProbe to record each activation before passing it to the subject
void verifyMockInvocation()
static const gavl_time_t SCALE
Number of micro ticks (µs) per second as basic time scale.
void watch_notification()
activity::Proc activate(Time now, EXE &executionCtx)
Core Operation: Activate and perform this Activity.
string randStr(size_t len)
create garbage string of given length
Lumiera's internal time value datatype.
auto buildDiagnosticFun(string id)
Generic testing helper: build a λ-mock, logging all invocations.
void verifyFakeExeContext()
ActivityMatch & seq(uint seqNr)
qualifier: additionally require the indicated sequence number
Diagnostic context to record and evaluate activations within the Scheduler.
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Activity & buildActivationTap(Activity const &subject, string id="")
build ActivationProbe to record each activation before passing it to the subject
boost::rational< int64_t > FSecs
rational representation of fractional seconds
A collection of frequently used helper functions to support unit testing.
Activity & buildActivationProbe(string id)
build a rigged HOOK-Activity to record each invocation
uint incrementSeq()
increment the internal invocation sequence number
Activity * next
Activities are organised into chains to represent relations based on verbs.
Diagnostic setup to instrument and observe Activity activations.
ActivityMatch & beforeSeqIncrement(uint seqNr)
special query to match an increment of the sequence number
internal engine »heart beat« for internal maintenance hook(s)
opaque ID attached to each individual job invocation.
lib::time::Time randTime()
create a random but not insane Time value between 1s ...
void verifyMockJobFunctor()
invoke an extension point through the activity::Hook interface
Individual frame rendering task, forwarding to a closure.
ActivityMatch & timeArg(Time const &time)
qualifier: additionally match the nominal time argument of JobFunctor invocation
a family of time value like entities and their relationships.
Front-end for simplified access to the current wall clock time.
ActivityMatch & arg(ARGS const &...args)
qualifier: additionally match the function arguments
Vault-Layer implementation namespace root.
bool isSameObject(A const &a, B const &b)
compare plain object identity, bypassing any custom comparison operators.