78 CHECK (55 == trap (1.23,
Time{FSecs{3,2}}));
80 CHECK (detector ==
"Rec(EventLogHeader| this = ActivityDetector(spectre) ), " 81 "Rec(call| fun = trap, this = ActivityDetector(spectre), Seq = 0 |{1.23, 0:00:01.500})"_expect);
97 uint rnd =
rani(10000);
100 CHECK (1 == detector.currSeq());
101 CHECK (detector.ensureNoInvocation (
"funny"));
104 CHECK (2 == detector.currSeq());
105 CHECK (detector.verifySeqIncrement(2));
108 CHECK (detector.verifyInvocation (
"funny"));
109 CHECK (detector.verifyInvocation (
"funny").
arg(rnd));
110 CHECK (detector.verifyInvocation (
"funny").
seq(2));
111 CHECK (detector.verifyInvocation (
"funny").
arg(rnd).
seq(2));
112 CHECK (detector.verifyInvocation (
"funny").
seq(2).
arg(rnd));
113 CHECK (detector.ensureNoInvocation (
"bunny"));
114 CHECK (detector.ensureNoInvocation (
"funny").
arg());
115 CHECK (detector.ensureNoInvocation (
"funny").
arg(rnd+5));
116 CHECK (detector.ensureNoInvocation (
"funny").
seq(5));
117 CHECK (detector.ensureNoInvocation (
"funny").
arg(rnd).
seq(1));
121 CHECK (detector.verifyInvocation (
"funny").
seq(2)
123 .beforeInvocation (
"funny").
seq(3).
arg(rnd+1));
125 CHECK (detector ==
"Rec(EventLogHeader| this = ActivityDetector )" 126 ", Rec(event| ID = IncSeq |{1})" 127 ", Rec(event| ID = IncSeq |{2})" 128 ", Rec(call| fun = funny, this = ActivityDetector, Seq = 2 |{"+util::toString(rnd)+
"})" 129 ", Rec(event| ID = IncSeq |{3})" 130 ", Rec(call| fun = funny, this = ActivityDetector, Seq = 3 |{"+util::toString(rnd+1)+
"})"_expect);
143 uint rnd =
rani(10000);
145 CHECK (0 == fun (rnd));
149 CHECK (42 == fun (rnd));
151 fun.implementedAs ([](uint i){
return -i; });
153 CHECK (-
int(rnd) == fun (rnd));
155 CHECK (detector.verifyInvocation(
"fakeFun").
seq(0)
156 .beforeInvocation(
"fakeFun").
seq(1)
157 .beforeInvocation(
"fakeFun").
seq(2));
174 Time nominal{FSecs{5,2}};
177 Job dummyJob{detector.buildMockJobFunctor (
"mockJob")
181 CHECK (detector.ensureNoInvocation (
"mockJob"));
182 dummyJob.triggerJob();
183 CHECK (detector.verifyInvocation (
"mockJob"));
184 CHECK (detector.verifyInvocation (
"mockJob").
arg(nominal, invoKey.part.a));
185 CHECK (detector.verifyInvocation (
"mockJob").
timeArg(nominal));
189 dummyJob.triggerJob();
191 CHECK (detector.verifyInvocation (
"mockJob").
timeArg(nominal).
seq(0)
192 .beforeInvocation (
"mockJob").
timeArg(nominal +
Time{FSecs{5}})
193 .afterSeqIncrement(1)
209 auto& ctx = detector.executionCtx;
211 activity::_verify_usable_as_ExecutionContext<decltype(detector.executionCtx)>();
218 CHECK (detector.ensureNoInvocation(CTX_WORK));
219 CHECK (detector.ensureNoInvocation(CTX_POST));
220 CHECK (detector.ensureNoInvocation(CTX_DONE));
221 CHECK (detector.ensureNoInvocation(CTX_TICK));
224 CHECK (detector.verifyInvocation(CTX_WORK).
arg(t,x));
227 CHECK (detector.verifyInvocation(CTX_DONE).
arg(t,x));
229 CHECK (activity::PASS == ctx.post (t,td, &a, ctx));
230 CHECK (detector.verifyInvocation(CTX_POST).
arg(t,td,&a,ctx));
232 CHECK (activity::PASS == ctx.tick(t));
233 CHECK (detector.verifyInvocation(CTX_TICK).
arg(t));
236 ctx.tick.returning(activity::KICK);
237 CHECK (activity::KICK == ctx.tick(t));
238 CHECK (detector.verifyInvocation(CTX_TICK).
timeArg(t));
240 CHECK (detector.verifyInvocation(CTX_WORK).
timeArg(t)
241 .beforeInvocation(CTX_DONE).
timeArg(t)
242 .beforeInvocation(CTX_POST).
timeArg(t)
244 .beforeInvocation(CTX_TICK).
timeArg(t).
seq(1));
255 auto someID =
"trap-" + randStr(4);
259 CHECK (not detector.wasInvoked (probe));
261 Time realTime = RealClock::now();
262 probe.
activate (realTime, detector.executionCtx);
264 CHECK (detector.verifyInvocation(someID).
timeArg(realTime));
267 CHECK (realTime == detector.invokeTime (probe));
268 CHECK (detector.wasInvoked (probe));
281 Activity feed{
size_t{12},
size_t{34}};
282 Activity feed2{
size_t{56},
size_t{78}};
284 string jobID =
"job-" + randStr(4);
285 Activity invoke{detector.buildMockJobFunctor(jobID), nomTime, feed};
288 CHECK (activity::PASS == invoke.activate (t1, detector.executionCtx));
289 CHECK (detector.verifyInvocation (jobID).
arg(nomTime, 12));
293 CHECK (tap.next == invoke.next);
298 tap.activate(t2, detector.executionCtx);
299 CHECK (detector.verifySeqIncrement(1)
300 .beforeInvocation(
"tap-INVOKE").
seq(1).
arg(
"JobFun-ActivityDetector."+jobID)
301 .beforeInvocation(jobID).
seq(1).
arg(nomTime,12));
306 invoke.activate (t3, detector.executionCtx);
307 CHECK (detector.verifyInvocation(jobID).
seq(2));
308 CHECK (detector.ensureNoInvocation(
"tap-INVOKE").
seq(2)
309 .beforeInvocation(jobID).
seq(2));
322 Activity followUp{size_t(1), size_t(2)};
323 subject.
next = &followUp;
325 CHECK (isSameObject (*wiring, subject));
329 CHECK (not isSameObject (*wiring, subject));
331 CHECK (wiring->data_.callback.arg ==
size_t(&subject));
332 CHECK (wiring->
next == subject.
next);
336 wiring->
activate(tt, detector.executionCtx);
337 CHECK (detector.verifyInvocation(
"tap-TICK").
arg(
"⧐ Act(TICK")
338 .beforeInvocation(
"CTX-tick").
timeArg(tt));
365 CHECK (gate.data_.condition.rest == 1);
369 notification.
activate (tt, detector.executionCtx);
371 CHECK (detector.verifyInvocation(
"CTX-post").
arg(
"22.022",
"33.033",
"tap-GATE",
"≺test::CTX≻"));
376 notification.data_.notification.target->dispatch (ts, detector.executionCtx);
377 CHECK (detector.verifyInvocation(
"tap-GATE").
seq(1).
arg(
"22.022 --notify-↯> Act(GATE"));
378 CHECK (gate.data_.condition.rest == 0);
399 gate.
next = &followUp;
402 detector.watchGate (wiring);
405 wiring->
activate(tt, detector.executionCtx);
409 CHECK (detector.verifyInvocation(
"tap-GATE").
seq(0).
timeArg(tt)
411 .beforeInvocation(
"after-GATE").
seq(1).
timeArg(tt)
412 .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.
int rani(uint bound=_iBOUND())
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.
Simplistic 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, based directly on the referee's memory identities. ...