engine.ts ports Swift's "Java-compatible TCP sockets" in one piece, since half a state machine could not be checked: server and client sockets (a free port from Java's random numbers on their own seed), the three-way handshake with its result (connected, invalid socket, unreachable, timed out), segments of 1460 bytes, messages up to the push, a timeout of 3 × 2.5 s with at most three attempts, closing through every Java state including TIME_WAIT (2.5 s), sequence numbers modulo 2^32. Three scenarios match the Swift engine trace for trace: a LAN with data over three segments, closing from both ends, a closed port and an unreachable host; two networks through a router with a firewall rule, data lost until the connection closes, and an accepted socket that does not hold the port of its closed listener; CLOSING, reached by a lost FIN. The engine delivers a FIN within the same close, so both ends close at once only with packet loss; an empty message does not arrive in Swift (it does not advance the sequence number), nor here. Swift's four TCP engine tests are ported, with tests for stopping, a foreign SYN+ACK at a listener and the flag names. 17 mutation probes, 16 caught; the other (delivered, not waited, not connected gives unreachable) cannot be reached through Swift's engine, which never sends a reset and always acknowledges correctly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3.9 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.jsondaneben — 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(Ergebnisconnected,invalidSocket,unreachable,timedOut),sendTcp(mitrepeatCountfür lange Nachrichten),receiveTcp,acceptedTcp,peerTcp,cleanTcp;closeSocketschließt auch TCP. 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.