Files
mdg-filius/tools/swift-oracle/README.md
T
julian.kiedaischandClaude Opus 5.5 efc7c440f6 feat(core): a cable carries one frame after the other, as in Java
Java's SimplexVerbindung sleeps a cable's delay with the port's buffer
locked: frames on one cable leave one after the other, and a frame shows
in the packet log when it leaves. The engine now queues a frame in the
output buffer until the one before has arrived (ethernetLinkDeparture).
Swift sends a cable's frames at once; the option swiftCables keeps that for
the Swift comparison, which goes on checking everything else trace by
trace.

With the queue, the Java comparisons match within 120 ms (was 200); a
state of the TCP stories within 250 ms, where the engine's calls block
one after the other.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 16:37:45 +00:00

4.7 KiB

Swift-Orakel

Der Swift-Kern von filius-ipad (Laufzeit, Modell, .fls, Berichte — alles ohne Oberfläche) lässt sich unter Linux bauen. Dieses Werkzeug nutzt das als Maßstab für die Übertragung: Ein Szenario wird einmal als JSON beschrieben, in Swift abgespielt, und die TypeScript-Übertragung muss dieselbe Ausgabe liefern — jedes einzelne Spurereignis, jede Antwort, den Endzustand.

npm run oracle          # = tools/swift-oracle/run.sh (braucht Docker)
npm test                # vergleicht mit den geschriebenen *.swift.json
  • Szenarien: packages/core/test/scenarios/<name>.scenario.json
  • Ergebnis aus Swift: <name>.swift.json daneben — wird eingecheckt, damit die Tests ohne Docker und ohne Swift laufen.
  • Vergleich: packages/core/test/oracle.test.ts. Er meldet das erste abweichende Spurereignis mit Nummer.
  • Schritte: ping, traceroute, resolveMac, advance, packetLoss, sat, speed; UDP (seit F2): bindUdp (Knoten, optional Port, lokale Adresse, Gegenstelle; Ergebnis die Socket-ID), sendUdp (Socket, Text, optional Ziel und Port), receiveUdp (Socket, optional Wartezeit), closeSocket; TCP: openTcpServer, openTcpClient, connectTcp (Ergebnis connected, invalidSocket, unreachable, timedOut), sendTcp (mit repeatCount für lange Nachrichten), receiveTcp, acceptedTcp, peerTcp, cleanTcp; closeSocket schließt auch TCP; DHCP: runDhcp (Ergebnis der Client-Status). Szenarien können dhcpServers (Bereich, eigene Einstellungen, feste Zuordnungen) und dhcpClients angeben; das Ergebnis enthält die Gerätekonfiguration und den DHCP-Zustand (Clients, Leases, Angebote, Sperrliste, Server). Seit F2.3b folgt der DHCP-Client des Kerns Java statt Swift; die vier DHCP-Szenarien vergleicht dhcpJava.test.ts mit Java-Läufen (tools/java-oracle, DhcpRun), am Swift-Ergebnis prüft der Test nur noch, dass sie abweichen. Ebenso seit F2.3c die drei TCP-Szenarien (tcpJava.test.ts, TcpRun). Seit F2.3d befördert ein Kabel des Kerns einen Frame nach dem anderen wie Java; der Swift-Vergleich startet die Engine mit swiftCables (alle Frames zugleich, wie Swift) und prüft so alles andere weiter Spur für Spur. Das Ergebnis enthält die Sockets mit der Länge ihrer Warteschlange, dem TCP-Zustand, dem annehmenden Socket und den Sitzungswerten.

Korpus

--corpus importiert jede .fls unter corpus/ und schreibt corpus/corpus.swift.json: je Datei die Zählwerte und Warnungen des Imports und unter state Swifts ganzes importiertes Modell ohne die zufälligen UUIDs (Geräte, Ports und Kabel als Indizes, IP-Konfiguration, Doku-Elemente mit ihren abgeleiteten IDs). Daran misst packages/fls/test/importProject.test.ts den Umbau — auf den 13 Dateien, die Swift vollständig liest.

Dateisystem und Strings

--vfs spielt die Fälle aus packages/core/test/vfs.cases.json im virtuellen Dateisystem ab (jedes Ergebnis, jeder Fehler samt Werten, der Endzustand mit SHA-256 der Binärdaten). --strings misst, was Swift aus Strings macht, wo JavaScript abweicht: Trimmen, Kleinschreibung, Gleichheit, Sortierung, Base64 — und die ganzen Mengen whitespacesAndNewlines und controlCharacters über alle Unicode-Skalare. Grenze: Das ist Foundation unter Linux; ihre Steuerzeichen-Tabelle hat in Ebene 14 einen Fehler, den der Port nicht übernimmt.

--email-files server|client liest die Kontodateien (packages/fls/test/email-*.cases.txt) mit Swifts TopologyRuntimeEmailStorage.decodeJavaServer/decodeJavaClient.

--dns-hosts liest dieselben /dns/hosts-Fälle wie das Java-Orakel (packages/fls/test/dns-hosts.cases.txt) mit Swifts TopologyDNSHostsFileCodec; unter state stehen die DNS-Einträge jedes Servers (dnsServer.records) und E-Mail-Client und -Server mit Konten und Nachrichten (emailClient, emailServer).

Wie es gebaut wird

fetch-upstream.sh holt filius-ipad am festen Stand 3b5ded0 und kopiert die oberflächenfreien Quellen nach Sources/FiliusCore/ (nicht eingecheckt). Apple-Module, die es unter Linux nicht gibt, sind auf das Nötige verkleinert:

Modul Ersatz
CoreGraphics Foundation (hat CGPoint/CGFloat unter Linux)
CryptoKit swift-crypto (gleiche Schnittstelle)
Compression eine Funktion, compression_decode_buffer mit rohem DEFLATE über zlib
Network entfällt: TopologyRemoteLinkLANController.swift wird nicht mitgebaut

patches/linux-type-checker.patch teilt zwei lange Ausdrücke auf, an denen der Linux-Compiler die Typprüfung abbricht. Das Verhalten ändert sich dadurch nicht.

Neue Schrittarten

Eine Schrittart gibt es zweimal — in Sources/Oracle/main.swift und in packages/core/test/oracle.test.ts. Beide müssen dasselbe JSON schreiben.