Testabdeckung

ForgeIEC wird durch eine umfassende automatisierte Test-Suite abgesichert. Jeder Commit wird vor dem Merge gegen 117 Unit-Tests geprueft, die den vollstaendigen IEC 61131-3 Structured Text Sprachvorrat, alle Standard-Funktionsbausteine und das Multi-Task-Threading-System abdecken.

Test-Suiten im Ueberblick

SuiteTestsPrueft
FStCompilerTest101Vollstaendiger ST-Sprachvorrat
FStLibraryTest8Alle 132 Standard-Bausteine (FBs + FCs)
FCodeGeneratorThreadingTest8Multi-Task-Scheduling + Lock-free Sync
Gesamt1170 Fehler

1. ST-Sprachvorrat (FStCompilerTest)

101 Tests pruefen jeden unterstuetzten IEC 61131-3 Structured Text Sprachkonstrukt. Jeder Test kompiliert ein ST-Fragment durch den FStCompiler und verifiziert den generierten C++-Code.

1.1 Zuweisungen

TestST-CodePrueft
assignSimplea := 42;Einfache Zuweisung
assignExpressiona := b + 1;Ausdruck-Zuweisung
assignExternalExtVar := 10;VAR_EXTERNAL Zugriff
assignGvlQualifiedGVL.ExtVar := 5;Qualifizierter GVL-Pfad

1.2 Arithmetische Operatoren

TestST-CodeC-Operator
arithmeticAdda := b + 1;+
arithmeticSuba := b - 1;-
arithmeticMula := b * 2;*
arithmeticDiva := b / 2;/
arithmeticModa := b MOD 3;%
arithmeticPowerc := x ** 2.0;EXPT()
arithmeticNegatea := -b;-(...)
arithmeticParenthesesa := (b + 1) * 2;Klammerung

1.3 Vergleichsoperatoren

TestST-CodeC-Operator
compareEqualflag := a = b;==
compareNotEqualflag := a <> b;!=
compareLessflag := a < b;<
compareGreaterflag := a > b;>
compareLessEqualflag := a <= b;<=
compareGreaterEqualflag := a >= b;>=

1.4 Boolesche Operatoren

TestST-CodeC-Operator
boolAndflag := flag AND flag;&&
boolOrflag := flag OR flag;||
boolXorflag := flag XOR flag;^
boolNotflag := NOT flag;!

1.5 Literale

TestST-CodePrueft
literalIntegera := 12345;Ganzzahl
literalRealc := 3.14;Fliesskomma
literalBoolTrueflag := TRUE;Boolescher Wert
literalBoolFalseflag := FALSE;Boolescher Wert
literalStringtext := 'hello';Zeichenkette
literalTimecounter := T#500ms;Zeitkonstante

1.6 Kontrollstrukturen

IF / ELSIF / ELSE / END_IF

TestPrueft
ifSimpleEinfache Bedingung
ifElseIf-Else-Verzweigung
ifElsifMehrfachverzweigung mit ELSIF
ifNestedVerschachtelte IF-Bloecke

FOR / WHILE / REPEAT

TestPrueft
forSimpleFOR idx := 0 TO 10 DO
forWithByFOR mit BY-Schrittweite
whileLoopWHILE-Schleife
repeatUntilREPEAT/UNTIL-Schleife

CASE

TestPrueft
caseStatementCASE/OF mit mehreren Labels + switch/case/break

RETURN / EXIT

TestPrueft
returnStatementRETURN → goto __end
exitStatementEXIT innerhalb FOR → break

1.7 Funktionsbausteine (FB-Aufrufe)

TestPrueft
fbCallWithInputsMyTon(IN := flag, PT := T#500ms);
fbCallWithOutputAssignMyTimer(IN := flag, Q => flag); — OUT => Zuweisung

1.8 Array-Zugriffe

TestPrueft
arrayReadSubscripta := arr[3];
arrayWriteSubscriptarr[5] := 42;
arrayComputedIndexa := arr[idx + 1];
arrayInForLoopArray-Zugriff in FOR-Schleife

2. Standard-Bibliothek (FStLibraryTest)

8 datengetriebene Tests pruefen alle 132 Bloecke aus der Standard-Bibliothek (standard_library.sql) automatisch.

2.1 Funktionsbausteine (13 FBs)

TestPrueft
fbSingleInstanceJeder FB einzeln instanziierbar und aufrufbar
fbDoubleInstanceZwei Instanzen desselben FB-Typs gleichzeitig
fbOutputReadAlle Ausgaenge nach dem Aufruf lesbar

Abgedeckte FBs: SR, RS, R_TRIG, F_TRIG, CTU, CTD, CTUD, TON, TOF, TP, RTC, SEMA, RampGen

2.2 Funktionen (119 FCs)

TestPrueft
fcCallJede FC mit korrekten Parametern aufrufbar (104 getestet)
fcInExpressionFC-Rueckgabewert in Ausdruecken verwendbar

Abgedeckte Kategorien:

  • Arithmetik: ADD, SUB, MUL, DIV, MOD, EXPT, ABS
  • Vergleich: EQ, NE, LT, GT, LE, GE
  • Trigonometrie: SIN, COS, TAN, ASIN, ACOS, ATAN, ATAN2
  • Logarithmus: EXP, LN, LOG, SQRT
  • Selektion: SEL, MUX, LIMIT, MIN, MAX, MOVE, CLAMP
  • String: LEN, LEFT, RIGHT, MID, CONCAT, INSERT, DELETE, REPLACE, FIND
  • Bitshift: SHL, SHR, ROL, ROR
  • Typkonvertierung: 60+ Konvertierungsfunktionen (BOOL_TO_INT, INT_TO_REAL, …)
  • ForgeIEC-Erweiterungen: LERP, MAP_RANGE, HYPOT, DEG, RAD, IK_2Link, CABS, CADD, CMUL, CSUB, CARG, CCONJ, CPOLAR, CRECT

3. Multi-Task-Threading (FCodeGeneratorThreadingTest)

8 Tests pruefen das vollstaendige Multi-Task-Scheduling-System gemaess der Design-Spezifikation (MT-spec, docs/design/multi-task-scheduler.md).

TestPrueft
singleProgramDefaultTaskEin PROGRAM ohne explizite Task → DefaultTask-Synthese, kein Threading
twoProgramsTwoTasksZwei Tasks → RESOURCE0_start__, Legacy-Shim config_run__, beide Task-Threads
crossPrimitiveAtomicEmissionGeteilte INT-Variable → std::atomic<> Location-Storage, __GET_EXTERNAL_ATOMIC im Body
crossStructuredDoubleBufferGeteilter STRUCT → __DBUF_[2] + thread_local __snap_ + Double-Buffer copy-in/out
localVarNoSyncVariable nur in einem Task → normales __SET_EXTERNAL, kein Atomic
conflictTwoWritersZwei Tasks schreiben dieselbe Variable → Compile-Warnung
singleProgramDefaultTaskBackward-Kompatibilitaet: bestehende Projekte laufen unveraendert

Multi-Task-Architektur

Primary Task (Task 0)          Secondary Tasks (1..N)
    |                               |
    | config_run__()                | RESOURCE0_task_thread__()
    |   ├─ sync_in                  |   ├─ dbuf_rd (copy-in)
    |   ├─ TASK0_body__()           |   ├─ TASKn_body__()
    |   └─ sync_out                 |   └─ dbuf_wr (copy-out)
    |                               |
    | [unter bufferLock]            | [lock-free]

Sync-Mechanismen:

  • CrossPrimitive (BOOL, INT, REAL, …): std::atomic<T> auf der Location-Variable, __GET_EXTERNAL_ATOMIC / __SET_EXTERNAL_ATOMIC im Body-Code
  • CrossStructured (STRUCT, ARRAY, STRING): Double-Buffer __DBUF_[2] mit atomarem Write-Index, thread_local Snapshots __snap_ fuer Set-Konsistenz