Library: investigate Scheduler test failures

...which turn out not to be due to the PRNG changes
 * the SchedulerCommutator_test was inadvertently broken 2024-04-10
 * SchedulerStress_test simply runs for 4min, which is not tolerated by our Testsuite setup

see also:
5b62438eb
This commit is contained in:
Fischlurch 2024-11-15 02:20:36 +01:00
parent 7ed8486774
commit bf41474004
2 changed files with 230 additions and 103 deletions

View file

@ -110,7 +110,7 @@ namespace test {
*/
void
demonstrateSimpleUsage()
{
{ MARK_TEST_FUN
SchedulerInvocation queue;
SchedulerCommutator sched;
Activity activity;
@ -141,7 +141,8 @@ namespace test {
*/
void
verify_GroomingToken()
{
{ MARK_TEST_FUN
SchedulerCommutator sched;
auto myself = std::this_thread::get_id();
@ -173,7 +174,8 @@ namespace test {
*/
void
verify_GroomingGuard()
{
{ MARK_TEST_FUN
SchedulerCommutator sched;
// Case-1: if a thread already holds the token....
@ -206,7 +208,8 @@ namespace test {
*/
void
torture_GroomingToken()
{
{ MARK_TEST_FUN
SchedulerCommutator sched;
size_t checkSum{0};
@ -281,61 +284,12 @@ namespace test {
// /** @test verify the logic to decide where and when to perform
// * the dispatch of a Scheduler Activity chain.
// */
// void
// verify_DispatchDecision()
// {
// SchedulerCommutator sched;
// ___ensureGroomingTokenReleased(sched);
//
// Time t1{10,0};
// Time t2{20,0};
// Time t3{30,0};
// Time now{t2};
//
// auto myself = std::this_thread::get_id();
// CHECK (sched.decideDispatchNow (t1, now)); // time is before now => good to execute
// CHECK (sched.holdsGroomingToken (myself)); // Side-Effect: acquired the Grooming-Token
//
// CHECK (sched.decideDispatchNow (t1, now)); // also works if Grooming-Token is already acquired
// CHECK (sched.holdsGroomingToken (myself));
//
// CHECK (sched.decideDispatchNow (t2, now)); // Boundary case time == now => good to execute
// CHECK (sched.holdsGroomingToken (myself));
//
// CHECK (not sched.decideDispatchNow (t3, now)); // Task in the future shall not be dispatched now
// CHECK (sched.holdsGroomingToken (myself)); // ...and this case has no impact on the Grooming-Token
// sched.dropGroomingToken();
//
// CHECK (not sched.decideDispatchNow (t3, now));
// CHECK (not sched.holdsGroomingToken (myself));
//
// blockGroomingToken(sched);
// CHECK (not sched.acquireGoomingToken());
//
// CHECK (not sched.decideDispatchNow (t1, now)); // unable to acquire => can not decide positively
// CHECK (not sched.holdsGroomingToken (myself));
//
// CHECK (not sched.decideDispatchNow (t2, now));
// CHECK (not sched.holdsGroomingToken (myself));
//
// unblockGroomingToken();
//
// CHECK (sched.decideDispatchNow (t2, now));
// CHECK (sched.holdsGroomingToken (myself));
// }
/** @test verify logic of queue updates and work prioritisation.
*/
void
verify_findWork()
{
{ MARK_TEST_FUN
SchedulerInvocation queue;
SchedulerCommutator sched;
@ -399,7 +353,8 @@ namespace test {
*/
void
verify_Significance()
{
{ MARK_TEST_FUN
SchedulerInvocation queue;
SchedulerCommutator sched;
@ -473,7 +428,8 @@ namespace test {
*/
void
verify_postChain()
{
{ MARK_TEST_FUN
// rigged execution environment to detect activations--------------
ActivityDetector detector;
Activity& activity = detector.buildActivationProbe ("testActivity");
@ -552,7 +508,8 @@ namespace test {
*/
void
verify_dispatch()
{
{ MARK_TEST_FUN
// rigged execution environment to detect activations--------------
ActivityDetector detector;
Activity& activity = detector.buildActivationProbe ("testActivity");
@ -621,6 +578,7 @@ namespace test {
void
integratedWorkCycle()
{ // ·==================================================================== setup a rigged Job
MARK_TEST_FUN
Time nominal{7,7};
Time start{0,1};
Time dead{0,10};

View file

@ -16716,9 +16716,7 @@
<node CREATED="1487473004949" ID="ID_1092623141" MODIFIED="1518487921076" TEXT="wenn wir die Garantie haben, da&#xdf; die Event-Loop nichts mehr macht"/>
<node CREATED="1487473038377" ID="ID_393673106" MODIFIED="1576282358105" TEXT="Policy: kein Tangible darf im dtor mit dem UI-Bus reden">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...mit der Ausnahme des Automatismus,
@ -17252,9 +17250,7 @@
<icon BUILTIN="hourglass"/>
<node CREATED="1662151277190" ID="ID_1508158518" MODIFIED="1662151299801" TEXT="bestehender Code">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...stammt im Kern noch von Joel Holdsworth &lt; 2012
@ -17773,9 +17769,7 @@
<node CREATED="1664546716995" ID="ID_1893051713" MODIFIED="1664546729304" TEXT="das zweite Icon ist entweder ein Men&#xfc;, oder ein Expander">
<node CREATED="1664546774836" ID="ID_1104234333" MODIFIED="1664548057947" TEXT="Men&#xfc; == normales Kontext-Men&#xfc;">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...das hei&#223;t, der Men&#252;-Button ist dann nur <i>pro forma </i>da, und bietet eine Fl&#228;che, auf der man zuverl&#228;ssig dieses Men&#252; trifft; letzteres ist relevant f&#252;r eine Anzeige in Listen und Bins, bei der ansonsten die Ausdehnung des Widgets stark reduziert ist. Ein Klick auf das Name-Label hat eine andere Funktion (n&#228;mlich Editieren des Namens). Ein Weiterer Aspekt ist die Drag-Geste: es ist denkbar, diese auf dem Men&#252;-Button <i>nicht</i>&#160;zu starten (wobei allerdings zu bedenken ist, das Ziehen auch noch an weitere Voraussetzungen zu kn&#252;pfen, z.B. einen Modifiere, oder den Umstand, da&#223; das Objekt auch selektiert ist)
@ -18681,9 +18675,7 @@
<icon BUILTIN="broken-line"/>
<node CREATED="1664235646216" ID="ID_1679047596" MODIFIED="1664236010445" TEXT="Ursache waren naiv verwendete stream-Manipulatoren">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
Die meisten IOS-Stream-Manipulatoren sind &#187;sticky&#171;, d.h. sie ver&#228;ndern per Seiteneffekt den Zustand im jeweiligen ostream. Ich hatte eine Methode zum Ausgeben einer Addresse, eingebaut im to-String-Framework, und diese hat std::output auf Hex-Ausgabe umgeschaltet. Erstaunlich da&#223; ich das jahrelang nicht gemerkt habe!
@ -19192,9 +19184,7 @@
</node>
<node CREATED="1664834597364" ID="ID_988500213" MODIFIED="1664834784457" TEXT="ist aber nur schlimm solange wir das Label nicht k&#xfc;rzen k&#xf6;nnen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
weil in dem Fall jedesmal das Label wieder ausgeblendet wird, und dazu insgesamt drei mal die requested_width ermittelt werden mu&#223;
@ -20323,9 +20313,7 @@
</node>
<node CREATED="1666286902148" ID="ID_716610692" MODIFIED="1666286932721" TEXT="das ist aber genau so korrekt">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
per default greift sich ein Button ja den links-Klick, und das soll auch so sein!
@ -43526,9 +43514,7 @@
</node>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1670804699664" ID="ID_654656000" MODIFIED="1670804885457" TEXT="und ja &#x2014; das ist die Pr&#xe4;misse">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
Im Regelfall m&#246;chte ich die pr&#228;zise Integer-Bruch-Arithmetik, aber ich m&#246;chte die Grenzf&#228;lle nahtlos mit integrieren, und nehme f&#252;r diese Grenzf&#228;lle absolut betrachtet erehbliche Fehler in Kauf.
@ -46004,9 +45990,7 @@
<node CREATED="1541790631410" ID="ID_1544767080" MODIFIED="1541790641506" TEXT="geh&#xf6;rt in den Domain-level"/>
<node CREATED="1541790656124" ID="ID_279205741" MODIFIED="1576282358019" TEXT="Domain-IDs eindeutig">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
das hei&#223;t.
@ -46490,9 +46474,7 @@
</node>
<node CREATED="1448078330703" ID="ID_1955501343" MODIFIED="1518487921085">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
presentation
@ -46730,9 +46712,7 @@
<node CREATED="1451177449405" ID="ID_215708646" MODIFIED="1518487921086" TEXT="zun&#xe4;chst einfach auf/zu"/>
<node CREATED="1451177459667" ID="ID_1151970636" MODIFIED="1576282358012" TEXT="wird m&#xf6;glicherweise eine Enum">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
gemeint, eine ENUM von verschiedenen Graden der Aufgeklappt-heit
@ -46874,9 +46854,7 @@
</node>
<node CREATED="1535654884104" ID="ID_1335278492" MODIFIED="1576282358011" TEXT="k&#xf6;nnte f&#xfc;r den ViewLocator n&#xfc;tzlich sein">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...denn dort fehlt noch die konkrete Implementierung,
@ -47221,9 +47199,7 @@
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
der schwierigste Teil, das Mutieren von Attributen,
@ -57531,8 +57507,7 @@
...hatte vor einiger Zeit aufger&#228;umt und einen eigenen #include &quot;lib/integral.hpp&quot; geschaffen. Dadurch ist downstream der #include f&#252;r time-value.hpp rausgefallen, und damit fehlte die String-conversion f&#252;r Rationals
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1731516926921" ID="ID_1885341686" MODIFIED="1731516970756" TEXT="die eigentliche Ursache ist das ungel&#xf6;ste Problem mit FSecs">
<richcontent TYPE="NOTE"><html>
@ -57542,8 +57517,7 @@
...dazu nochmal &#252;ber die ganze Problematik nachgedacht und entsprechende Kommentare in #1258 und #1261 hinterlassen
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
</node>
</node>
@ -57562,6 +57536,131 @@
</p>
</body>
</html></richcontent>
<node CREATED="1731630625998" ID="ID_481330961" MODIFIED="1731630636457" TEXT="scheitert stets in &#xbb;verify_Significance&#xab;"/>
<node CREATED="1731631526021" ID="ID_433361901" MODIFIED="1731631554237" TEXT="ist ein (unbemerktes) Problem in der Test-Logik">
<node BACKGROUND_COLOR="#dfaf9a" COLOR="#990033" CREATED="1731631607610" ID="ID_1850643707" MODIFIED="1731631706792" TEXT="Test gebrochen seit 5b62438eb &#x2014; 2024-04-10 20:04:53">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
ommit 5b62438eb404e20762a9f2ff6109c7cf54022064
</p>
<p>
Author: Ichthyostega &lt;prg@ichthyostega.de&gt; 2024-04-10 20:04:53
</p>
<p>
</p>
<p>
Scheduler-test: investigate logic problem related to the &#187;Tick&#171; deadline
</p>
<p>
</p>
<p>
In the end, I decided that it ''is to early to decide anything'' in this respect...
</p>
<p>
</p>
<p>
The actual situation encountered is a **Catch-22**:
</p>
<p>
&#160;* in its current form, the &#187;Tick&#171; handler detects compulsory jobs beyond deadline
</p>
<p>
&#160;* since such a Job ''must not be touched anymore,'' there is no way scheduling can proceed
</p>
<p>
&#160;* so this would constitute a ''Scheduler Emergency''
</p>
<p>
All fine &#8212; just the &#187;Tick&#171; handler ''itself is a compulsory job'' &#8212; and being a job, it can well be driven beyond its deadline. In fact this situation was encountered as part of stress testing.
</p>
<p>
</p>
<p>
Several mitigations or real solutions are conceivable, but in the end,
</p>
<p>
too little is known yet regarding the integration of the scheduler within the Engine
</p>
<p>
Thus I'll marked the problematic location and opened #1362
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="clanbomber"/>
</node>
<node CREATED="1731631583470" ID="ID_1893073184" MODIFIED="1731631885052" TEXT="im Rahmen der Stress-Tests entdeckte &#xbb;Situation&#xab;">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...die definitiv auftreten kann, und die auf einem h&#246;heren (derzeit nicht existenten) Level der Architektur behandelt werden mu&#223;, als eine <b>Scheduler-Emergency</b>.
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="info"/>
</node>
<node CREATED="1731632078651" ID="ID_912676608" MODIFIED="1731632263641" TEXT="hab damals einfach &#xbb;aufgegeben&#xab; da der Trigger-Punkt unpassenderweise in Layer-2 liegt">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...bzw dorthin gezogen ist durch den Umbau der Scheduler-Struktur, welche zwar sp&#228;t erfolgte, als Resultat der Stress-tests, aber insgesamt eine signifikante Verbessung des Codes darstellt. Leider hat dieser Umbau nun dazu gef&#252;hrt, da&#223; Layer-2 diverse &#187;Hooks&#171; auf Service-Level ansprechen mu&#223;, und das ist wiederum ein HInweis, da&#223; die Code-Anordnung nicht optimal ist
</p>
</body>
</html>
</richcontent>
<node CREATED="1731632486002" ID="ID_1151089303" MODIFIED="1731632506832" TEXT="es fehlt ein Signalisierungs-Mechanismus"/>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1731632507425" ID="ID_241976514" MODIFIED="1731632836969" TEXT="dieser w&#xfc;rde &#xfc;ber mehrere Ecken laufen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<ul>
<li>
der Trigger w&#252;rde in Scheduler::doWork() erkannt werden, was allerdings aus den Workern aufgerufen wird.
</li>
<li>
der &#187;Tick&#171; dutyCycle() w&#252;rde aber logischerweise die gleiche Situation auch erkennen
</li>
<li>
nur das Problem ist: dieser &#187;Tick&#171; k&#246;nnte unerreichbar sein, denn er liegt selber in einem Compulsory-Job, und die Queue k&#246;nnte schon vorher geblockt sein durch einen anderen Compulsory-Job
</li>
</ul>
</body>
</html>
</richcontent>
<icon BUILTIN="messagebox_warning"/>
</node>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1731632025178" ID="ID_619384635" MODIFIED="1731632065737">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
siehe auch Kommentar im Ticket <b><font color="#be0f18">#1362 Scheduler Emergency</font></b>
</p>
</body>
</html>
</richcontent>
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
https://issues.lumiera.org/ticket/1362#comment:1
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="idea"/>
</node>
</node>
</node>
<node CREATED="1731466991636" ID="ID_1891507132" MODIFIED="1731467127501" TEXT="SchedulerStress_test">
<richcontent TYPE="NOTE"><html>
@ -57587,6 +57686,66 @@
</p>
</body>
</html></richcontent>
<node COLOR="#5b280f" CREATED="1731628327498" ID="ID_173194959" MODIFIED="1731630237873" TEXT="Vermutung: Timings entsprechen nicht der Erwartung">
<icon BUILTIN="button_cancel"/>
<node CREATED="1731628371516" ID="ID_715501217" MODIFIED="1731628374056" TEXT="Fehlschl&#xe4;ge">
<node CREATED="1731628384063" ID="ID_521526066" MODIFIED="1731628384831" TEXT="watch_expenseFunction">
<node CREATED="1731628473055" ID="ID_230047256" MODIFIED="1731630198296" TEXT="Overhead-Sockel">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
scheduler-stress-test.cpp:415: watch_expenseFunction: (isLimited (3, socket, 9 ))
</p>
<p>
Hier beobachten wir ein lineares Model der Beladung; die lineare Regression hat einen konstanten Sockel(9ms) knapp oberhalb der bisher tolerierten Overheads f&#252;r start-up und spin-down (+Test-setup); erwartet werden ~6ms
</p>
</body>
</html>
</richcontent>
</node>
</node>
<node CREATED="1731628606613" ID="ID_60599371" MODIFIED="1731628607824" TEXT="setup_systematicSchedule">
<node CREATED="1731628628170" ID="ID_1205966126" MODIFIED="1731629092546" TEXT="Scheduler kann einem lockeren Schedule nicht folgen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
scheduler-stress-test.cpp:270: setup_systematicSchedule: (fabs (runTime-expected) &lt; 5000)
</p>
<p>
Hier wird zun&#228;chst &#187;auf dem Trockenen&#171; demonstriert, wie aus der Kapazit&#228;tsrechnung eine zu erwartende effektive concurrent-run-time abgeleitet wird. Am Ende wird ein tats&#228;chlicher Scheduler-Lauf mit diesem (relativ locker dimensionierten) Schedule gestartet&#160;&#160;&#8212; und <b>hier</b>&#160;&#252;berschreiten wir den <b>Timeout von 5 Sekunden</b>, was bedeutet, da&#223; das Schedule komplett aus dem Ruder gelaufen sein mu&#223; (m&#246;glicherweise wurden sogar Job-Deadlines &#252;berfahren, in welchem Fall das Scheduler unvollst&#228;ndig h&#228;ngen bleibt)
</p>
</body>
</html>
</richcontent>
</node>
</node>
</node>
<node CREATED="1731629575437" ID="ID_872653414" MODIFIED="1731629948307">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
<i>wenn </i>der Test durl&#228;uft sind die beobachteten Kenndaten des Schedulers wie erwartet
</p>
</body>
</html>
</richcontent>
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
also die Concurrency ist wirklich gut, die back-to-back-Zeit weicht nur 10ms vom theoretischen Wert ab
</p>
</body>
</html>
</richcontent>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731630239332" ID="ID_113082625" MODIFIED="1731630281906" TEXT="Vermutung: der Test l&#xe4;uft &gt; 4min &#x2014; das verletzt das Limit unseres Testsuite-Runners">
<icon BUILTIN="idea"/>
</node>
</node>
<node CREATED="1731624499756" ID="ID_293265001" MODIFIED="1731624683932" TEXT="WorkForce_test">
<richcontent TYPE="NOTE"><html>
@ -57596,8 +57755,20 @@
<font face="Monospaced" size="2">CHECK: work-force-test.cpp:425: thread_1: verify_scalePool: (2*fullCnt == uniqueCnt) </font>
</p>
</body>
</html></richcontent>
<node CREATED="1731627781627" ID="ID_123189687" MODIFIED="1731628183851" TEXT="wohl nur ein &#xbb;sporadischer&#xab; Aussetzer (bekannterma&#xdf;en fragil)">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Dieser Test skaliert den Worker-Pool, wartet dann jeweils eine (fest konfigurierte) Zeitspanne, um anschlie&#223;end den Status zu pr&#252;fen &#8212; ein bekannterma&#223;en fragiles Schema, obwohl ich inzwischen Timings ausgeknobelt habe, die auf meiner Maschine hinreichend sicher sind. F&#252;r zuverl&#228;ssiges Testen m&#252;&#223;te man auf den Status der WorkForce <i>eigens warten, </i>und daf&#252;r m&#246;chte ich jedoch kein Core-API bereitstellen, denn ich m&#246;chte niemanden ermutigen, in Richtung einer &#187;pinball-machine&#171; zu gehen....
</p>
</body>
</html>
</richcontent>
<font NAME="SansSerif" SIZE="10"/>
<icon BUILTIN="messagebox_warning"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1731467207226" ID="ID_977237610" MODIFIED="1731624884569" TEXT="TrackingHeapBlockProvider_test">
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1731467220749" ID="ID_1574698883" MODIFIED="1731624803495" TEXT="ASSERTION">
@ -57632,8 +57803,7 @@
ich hab damals auf <i>theoretischem Weg</i>&#160;die Gefahr duplikater Eintr&#228;ge entdeckt...
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -57651,8 +57821,7 @@
...und aber eine dieser Infos einfach ignoriert wird, n&#228;mlich die konkrete Info, die der im BuffHandle vom Client eingebettet ist. Daher habe ich f&#252;r die einzige Implementierung, den TrackingHeapBlockProvider beide Infos in einer Assertion verglichen. Und genau dieser Check scheitert jetzt (noch nicht klar warum)
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="idea"/>
</node>
<node CREATED="1731519941439" ID="ID_357574011" MODIFIED="1731519948226" TEXT="Untersuchung...">