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>
92 lines
4.7 KiB
Markdown
92 lines
4.7 KiB
Markdown
# 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.
|
|
|
|
```bash
|
|
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.
|