An ARP lookup asks, waits a round trip, asks once more and gives up after another round trip; then host unreachable, observed at the sender itself or sent back by the router (for ICMP only for an echo request). A waiting sender wakes after what else happens at that time. A ping then waits a round trip for its answer, counted from when it left. Swift asks twice at once while events run and lets the packet wait without end when the address exists anywhere in the network; the option swiftArp keeps that for the Swift comparison, and three scenarios are compared with Swift until the trace where ARP fails or a ping goes unanswered. arpJava.test.ts compares ArpRun: both pings match; the two UDP stories wait for Java's transport thread (next step). DNS without a server now matches Java too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
95 lines
5.0 KiB
Markdown
95 lines
5.0 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. Ebenso stellt `swiftArp` Swifts ARP in
|
|
der Ereignisverarbeitung nach (beide Anfragen zugleich, Warteliste ohne
|
|
Ende); drei Szenarien vergleicht der Test nur bis zu der Spur, an der ARP
|
|
scheitert oder ein Ping unbeantwortet bleibt (`SWIFT_UNTIL_TRACE`).
|
|
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.
|