fix(fls): read and write a network card's wireless flag
A notebook that joins a switch's wireless network has its card marked wireless (NetzwerkInterface.setWireless, Betriebssystem.wireless()), next to the wireless cable. The reader did not read it, the writer did not write it, and the Java oracle did not report it, so the Java-against-Java writer test could not see the loss. Found while exporting the editor model: the corpus has 18 wireless cards, one at each wireless cable. The oracle now reports `wireless` per interface; FlsInterface has it; the writer sets it. The synthetic topology has a wireless card; a mutation probe that drops it is caught by Java. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -42,7 +42,7 @@ Swift-Pfade relativ zu `filius-ipad/ios/FiliusPad/TopologyEditor/` (Stand
|
|||||||
| `src/systemSoftware.ts` | Java `SwitchFirmware`, `Betriebssystem`, `VermittlungsrechnerBetriebssystem`, `GatewayFirmware`, `Weiterleitungstabelle`, `Firewall`, `FirewallRule`, `DHCPServer`, `ModemFirmware`, `Dateisystem`, `Datei` | neu nach Java: SSID, Lernzeit, RIP, manuelle Routen, Router-Firewall (an allen Stellen, an denen die Datei sie erreicht), DHCP (ein kaputter statischer Eintrag fällt allein weg, Java verliert alle folgenden), statische NAT, Modem, Dateisystem (bei Router und Heimrouter das, was die Datei zu den Vorlagen des Konstruktors hinzufügt, oder eine eigene Wurzel, die sie ersetzt), installierte Programme von Rechner und Notebook; `Character.isWhitespace` am JDK gemessen; gegen Java geprüft |
|
| `src/systemSoftware.ts` | Java `SwitchFirmware`, `Betriebssystem`, `VermittlungsrechnerBetriebssystem`, `GatewayFirmware`, `Weiterleitungstabelle`, `Firewall`, `FirewallRule`, `DHCPServer`, `ModemFirmware`, `Dateisystem`, `Datei` | neu nach Java: SSID, Lernzeit, RIP, manuelle Routen, Router-Firewall (an allen Stellen, an denen die Datei sie erreicht), DHCP (ein kaputter statischer Eintrag fällt allein weg, Java verliert alle folgenden), statische NAT, Modem, Dateisystem (bei Router und Heimrouter das, was die Datei zu den Vorlagen des Konstruktors hinzufügt, oder eine eigene Wurzel, die sie ersetzt), installierte Programme von Rechner und Notebook; `Character.isWhitespace` am JDK gemessen; gegen Java geprüft |
|
||||||
| `src/javaIp.ts` | Java `IP.inetAton`/`ipCheck` | neu nach Java; an 46 Fällen mit Java gemessen |
|
| `src/javaIp.ts` | Java `IP.inetAton`/`ipCheck` | neu nach Java; an 46 Fällen mit Java gemessen |
|
||||||
| `src/dnsHosts.ts` | Java `DNSServer.leseRecordListe`, `ResourceRecord`, `Dateisystem.holeDatei`; Swift `State/TopologyDNSResolver.swift` (`TopologyDNSHostsFileCodec`) als Vergleich | neu nach Java: Felder nur an einzelnen Leerzeichen, keine Kommentare, ungültige TTL → 3600, Doppelte bleiben; ins Modell kommt nur, was Java beantwortet (Typ A/MX/NS, Name nicht leer); Javas Fehler nicht übernommen: Label mit Ziffer vorn erlaubt, kein Backslash, letztes Label nicht rein numerisch (RFC 1123/3696), Typ in jeder Schreibung (RFC 4343), negative TTL ungültig (RFC 2181); an 76 Fällen mit Java und Swift gemessen |
|
| `src/dnsHosts.ts` | Java `DNSServer.leseRecordListe`, `ResourceRecord`, `Dateisystem.holeDatei`; Swift `State/TopologyDNSResolver.swift` (`TopologyDNSHostsFileCodec`) als Vergleich | neu nach Java: Felder nur an einzelnen Leerzeichen, keine Kommentare, ungültige TTL → 3600, Doppelte bleiben; ins Modell kommt nur, was Java beantwortet (Typ A/MX/NS, Name nicht leer); Javas Fehler nicht übernommen: Label mit Ziffer vorn erlaubt, kein Backslash, letztes Label nicht rein numerisch (RFC 1123/3696), Typ in jeder Schreibung (RFC 4343), negative TTL ungültig (RFC 2181); an 76 Fällen mit Java und Swift gemessen |
|
||||||
| `src/topology.ts` | Java `SzenarioVerwaltung.netzwerkLaden`, Konstruktoren und Setter der Geräte; Swift `Persistence/TopologyProjectStore.swift` (Parser) als Vergleich | neu nach Java statt Übertragung: Geräteart aus der Klasse statt aus der Beschriftung, Geräte ohne Koordinaten bei 0,0 statt verworfen, Werte durch Javas Setter, die Zeichen-Enden eines Kabels |
|
| `src/topology.ts` | Java `SzenarioVerwaltung.netzwerkLaden`, Konstruktoren und Setter der Geräte; Swift `Persistence/TopologyProjectStore.swift` (Parser) als Vergleich | neu nach Java statt Übertragung: Geräteart aus der Klasse statt aus der Beschriftung, Geräte ohne Koordinaten bei 0,0 statt verworfen, Werte durch Javas Setter, die Zeichen-Enden eines Kabels, die Funk-Eigenschaft einer Netzwerkkarte (`wireless`, bis 30.09.2026 übersehen) |
|
||||||
| `test/javabeans.test.ts` | — | neu: je XMLDecoder-Regel ein Test; alle 23 Korpus-Dateien, Klasse und Position jedes Geräts wie Java |
|
| `test/javabeans.test.ts` | — | neu: je XMLDecoder-Regel ein Test; alle 23 Korpus-Dateien, Klasse und Position jedes Geräts wie Java |
|
||||||
| `test/topology.test.ts` | — | neu: alle 23 Korpus-Dateien Feld für Feld wie Java (Geräte, Schnittstellen, Kabel, Doku-Elemente), dazu die Regeln, die der Korpus nicht berührt |
|
| `test/topology.test.ts` | — | neu: alle 23 Korpus-Dateien Feld für Feld wie Java (Geräte, Schnittstellen, Kabel, Doku-Elemente), dazu die Regeln, die der Korpus nicht berührt |
|
||||||
| `test/javaIp.test.ts`, `test/ip-check.*` | — | neu: `IP.ipCheck`-Fälle, Ergebnis aus Java |
|
| `test/javaIp.test.ts`, `test/ip-check.*` | — | neu: `IP.ipCheck`-Fälle, Ergebnis aus Java |
|
||||||
|
|||||||
+440
-220
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,8 @@ export interface FlsInterface {
|
|||||||
mac: string | undefined;
|
mac: string | undefined;
|
||||||
gateway: string | null;
|
gateway: string | null;
|
||||||
dns: string | null;
|
dns: string | null;
|
||||||
|
/** A notebook's or PC's card joining a switch's wireless network (Betriebssystem.wireless). */
|
||||||
|
wireless: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FlsNode {
|
export interface FlsNode {
|
||||||
@@ -270,6 +272,7 @@ class Reader {
|
|||||||
mac: undefined,
|
mac: undefined,
|
||||||
gateway: '',
|
gateway: '',
|
||||||
dns: '',
|
dns: '',
|
||||||
|
wireless: false,
|
||||||
};
|
};
|
||||||
if (!isJavaObject(nic)) return result;
|
if (!isJavaObject(nic)) return result;
|
||||||
// Only the constructor's own interface gets the WAN address; one the file
|
// Only the constructor's own interface gets the WAN address; one the file
|
||||||
@@ -302,6 +305,9 @@ class Reader {
|
|||||||
if (typeof value === 'string' || value === null) result[field] = value;
|
if (typeof value === 'string' || value === null) result[field] = value;
|
||||||
else this.unexpected(at, property, value);
|
else this.unexpected(at, property, value);
|
||||||
}
|
}
|
||||||
|
const wireless = nic.properties.get('wireless');
|
||||||
|
if (typeof wireless === 'boolean') result.wireless = wireless;
|
||||||
|
else if (wireless !== undefined) this.unexpected(at, 'wireless', wireless);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -469,6 +469,7 @@ function interfaceStatements(nic: FlsInterface): BeanStatement[] {
|
|||||||
if (nic.mask !== null) statements.push({ set: 'subnetzMaske', value: nic.mask });
|
if (nic.mask !== null) statements.push({ set: 'subnetzMaske', value: nic.mask });
|
||||||
if (nic.mac !== undefined) statements.push({ set: 'mac', value: nic.mac });
|
if (nic.mac !== undefined) statements.push({ set: 'mac', value: nic.mac });
|
||||||
statements.push({ set: 'gateway', value: nic.gateway }, { set: 'dns', value: nic.dns });
|
statements.push({ set: 'gateway', value: nic.gateway }, { set: 'dns', value: nic.dns });
|
||||||
|
if (nic.wireless) statements.push({ set: 'wireless', value: true });
|
||||||
return statements;
|
return statements;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -526,7 +526,7 @@ function topology(fields: Partial<FlsTopology>): FlsTopology {
|
|||||||
return { versionLine: null, nodes: [], links: [], documentation: [], warnings: [], ...fields };
|
return { versionLine: null, nodes: [], links: [], documentation: [], warnings: [], ...fields };
|
||||||
}
|
}
|
||||||
|
|
||||||
const nic = (ip: string | null, mask: string | null = '255.255.255.0') => ({ ip, mask, mac: undefined, gateway: '', dns: '' });
|
const nic = (ip: string | null, mask: string | null = '255.255.255.0') => ({ ip, mask, mac: undefined, gateway: '', dns: '', wireless: false });
|
||||||
|
|
||||||
describe('importProject rules', () => {
|
describe('importProject rules', () => {
|
||||||
it('labels a gateway wan0, lan0, gw2 and gives a rejected address the default', () => {
|
it('labels a gateway wan0, lan0, gw2 and gives a rejected address the default', () => {
|
||||||
@@ -857,7 +857,7 @@ describe('importProject rules', () => {
|
|||||||
});
|
});
|
||||||
const host = (dns: string, recursive: boolean) =>
|
const host = (dns: string, recursive: boolean) =>
|
||||||
flsNode('Rechner', {
|
flsNode('Rechner', {
|
||||||
interfaces: [{ ip: '10.0.0.1', mask: '255.255.255.0', mac: undefined, gateway: '', dns }],
|
interfaces: [{ ip: '10.0.0.1', mask: '255.255.255.0', mac: undefined, gateway: '', dns, wireless: false }],
|
||||||
system: { applications: [application('filius.software.dns.DNSServer', { isActive: true, port: 53, recursiveResolutionEnabled: recursive })] },
|
system: { applications: [application('filius.software.dns.DNSServer', { isActive: true, port: 53, recursiveResolutionEnabled: recursive })] },
|
||||||
});
|
});
|
||||||
const project = importProject(
|
const project = importProject(
|
||||||
|
|||||||
@@ -292,8 +292,8 @@ describe('readTopology rules', () => {
|
|||||||
</void></object>`)}</object>`);
|
</void></object>`)}</object>`);
|
||||||
|
|
||||||
expect(nodes[0]!.interfaces).toEqual([
|
expect(nodes[0]!.interfaces).toEqual([
|
||||||
{ ip: '10.0.0.1', mask: null, mac: undefined, gateway: '', dns: '' },
|
{ ip: '10.0.0.1', mask: null, mac: undefined, gateway: '', dns: '', wireless: false },
|
||||||
{ ip: '192.168.0.10', mask: '255.255.255.0', mac: '0A:0B:0C:0D:0E:0F', gateway: '', dns: '' },
|
{ ip: '192.168.0.10', mask: '255.255.255.0', mac: '0A:0B:0C:0D:0E:0F', gateway: '', dns: '', wireless: false },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ const SYNTHETIC: TopologyToWrite = {
|
|||||||
y: 20,
|
y: 20,
|
||||||
useIpAsName: false,
|
useIpAsName: false,
|
||||||
useMacAsName: true,
|
useMacAsName: true,
|
||||||
interfaces: [{ ip: '10.0.0.1', mask: '255.0.0.0', mac: 'AA:BB:CC:DD:EE:01', gateway: null, dns: '10.0.0.53' }],
|
interfaces: [{ ip: '10.0.0.1', mask: '255.0.0.0', mac: 'AA:BB:CC:DD:EE:01', gateway: null, dns: '10.0.0.53', wireless: true }],
|
||||||
portCount: 1,
|
portCount: 1,
|
||||||
system: {
|
system: {
|
||||||
ssid: 'Lab',
|
ssid: 'Lab',
|
||||||
@@ -301,6 +301,7 @@ const SYNTHETIC: TopologyToWrite = {
|
|||||||
mac: `AA:BB:CC:DD:EE:1${octet}`,
|
mac: `AA:BB:CC:DD:EE:1${octet}`,
|
||||||
gateway: '',
|
gateway: '',
|
||||||
dns: '',
|
dns: '',
|
||||||
|
wireless: false,
|
||||||
})),
|
})),
|
||||||
portCount: 3,
|
portCount: 3,
|
||||||
system: {
|
system: {
|
||||||
@@ -346,6 +347,7 @@ const SYNTHETIC: TopologyToWrite = {
|
|||||||
mac: `AA:BB:CC:DD:EE:1${octet}`,
|
mac: `AA:BB:CC:DD:EE:1${octet}`,
|
||||||
gateway: '',
|
gateway: '',
|
||||||
dns: '',
|
dns: '',
|
||||||
|
wireless: false,
|
||||||
})),
|
})),
|
||||||
portCount: 2,
|
portCount: 2,
|
||||||
system: {
|
system: {
|
||||||
@@ -406,7 +408,7 @@ describe('a topology beyond the corpus, as Java loads it', () => {
|
|||||||
expect(java?.sha256, 'written.java.json is not about this output: UPDATE_WRITTEN=1, then npm run oracle:java').toBe(
|
expect(java?.sha256, 'written.java.json is not about this output: UPDATE_WRITTEN=1, then npm run oracle:java').toBe(
|
||||||
createHash('sha256').update(archive).digest('hex'),
|
createHash('sha256').update(archive).digest('hex'),
|
||||||
);
|
);
|
||||||
const plainInterface = (octet: string) => ({ ip: `10.0.${octet}.1`, mask: '255.255.255.0', mac: `AA:BB:CC:DD:EE:1${octet}`, gateway: '', dns: '' });
|
const plainInterface = (octet: string) => ({ ip: `10.0.${octet}.1`, mask: '255.255.255.0', mac: `AA:BB:CC:DD:EE:1${octet}`, gateway: '', dns: '', wireless: false });
|
||||||
expect(topologyOf(java!)).toEqual({
|
expect(topologyOf(java!)).toEqual({
|
||||||
success: true,
|
success: true,
|
||||||
nodes: [
|
nodes: [
|
||||||
@@ -416,7 +418,7 @@ describe('a topology beyond the corpus, as Java loads it', () => {
|
|||||||
position: [10, 20],
|
position: [10, 20],
|
||||||
useIpAsName: false,
|
useIpAsName: false,
|
||||||
useMacAsName: true,
|
useMacAsName: true,
|
||||||
ports: [{ ip: '10.0.0.1', mask: '255.0.0.0', mac: 'AA:BB:CC:DD:EE:01', gateway: null, dns: '10.0.0.53' }],
|
ports: [{ ip: '10.0.0.1', mask: '255.0.0.0', mac: 'AA:BB:CC:DD:EE:01', gateway: null, dns: '10.0.0.53', wireless: true }],
|
||||||
system: {
|
system: {
|
||||||
ssid: 'Lab',
|
ssid: 'Lab',
|
||||||
manualRoutes: [['10.1.0.0', '255.255.0.0', '10.0.0.254', '10.0.0.1']],
|
manualRoutes: [['10.1.0.0', '255.255.0.0', '10.0.0.254', '10.0.0.1']],
|
||||||
|
|||||||
+460
-234
File diff suppressed because it is too large
Load Diff
@@ -31,7 +31,7 @@ virtuellen Bildschirm statt „headless".
|
|||||||
29.09.2026 suchte es die MAC im Dateitext und hielt dabei acht
|
29.09.2026 suchte es die MAC im Dateitext und hielt dabei acht
|
||||||
kleingeschriebene für gewürfelt.)
|
kleingeschriebene für gewürfelt.)
|
||||||
* Bisher ausgelesen: Geräte (Klasse, Name, Beschriftung, Position,
|
* Bisher ausgelesen: Geräte (Klasse, Name, Beschriftung, Position,
|
||||||
Schnittstellen, bei Rechner/Notebook `useIPAsName`/`useMACAsName`), unter
|
Schnittstellen samt Funk-Eigenschaft `wireless`, bei Rechner/Notebook `useIPAsName`/`useMACAsName`), unter
|
||||||
`system` SSID, Lernzeit des Switches, RIP, manuelle Routen, die Firewall
|
`system` SSID, Lernzeit des Switches, RIP, manuelle Routen, die Firewall
|
||||||
von Router und Heimrouter, DHCP-Client und -Server, die statische
|
von Router und Heimrouter, DHCP-Client und -Server, die statische
|
||||||
NAT-Tabelle des Heimrouters, die Verbindung eines Modems und das
|
NAT-Tabelle des Heimrouters, die Verbindung eines Modems und das
|
||||||
|
|||||||
@@ -195,6 +195,7 @@ public class FlsOracle {
|
|||||||
port.put("mac", nic.getMac());
|
port.put("mac", nic.getMac());
|
||||||
port.put("gateway", nic.getGateway());
|
port.put("gateway", nic.getGateway());
|
||||||
port.put("dns", nic.getDns());
|
port.put("dns", nic.getDns());
|
||||||
|
port.put("wireless", nic.isWireless());
|
||||||
ports.add(port);
|
ports.add(port);
|
||||||
if (nic.getPort() != null) portOwners.put(nic.getPort(), new int[] { nodeIndex, index });
|
if (nic.getPort() != null) portOwners.put(nic.getPort(), new int[] { nodeIndex, index });
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user