feat(core): the firewall settings page of routers after Java, measured against Java

The page konfig changes the firewall at run time (into the snapshot, back
into the project through projectWithSimulationChanges). KonfigCases feeds
Java's plug-in directly (25 cases, de and en); RouterWebRun plays two
stories over the network. Ten Java bugs named, not adopted. The web server
answers a method not written GET or POST with 501, as Java does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-01 18:13:31 +00:00
co-authored by Claude Opus 5.5
parent 7dac57cbbe
commit 8438b42018
23 changed files with 13229 additions and 24 deletions
+28
View File
@@ -12,6 +12,7 @@ import {
defaultDisplayName,
defaultSwitchConfiguration,
firewallConfiguration,
firewallRule,
FIREWALL_PROTOCOL,
interfaceKey,
deepEqual,
@@ -28,8 +29,11 @@ import {
import {
decodeJavaBeans,
importProject,
openProjectArchive,
projectSnapshot,
projectWithSimulationChanges,
readFlsArchive,
saveProjectArchive,
readTopology,
type FlsApplication,
type JavaEmail,
@@ -773,6 +777,30 @@ describe('importProject rules', () => {
expect(snapshot.fileSystemsByNodeId).toBe(project.virtualFileSystems);
});
it("keeps a router's firewall set on its page konfig in the project saved after the run (projectWithSimulationChanges)", () => {
const project = openProjectArchive(new Uint8Array(readFileSync(join(corpusRoot, 'java-examples/internetwork_komplett.fls'))), counter());
const node = (name: string) => project.graph.nodes.find((each) => each.displayName === name)!.id;
const router = project.graph.nodes.find((each) => each.kind === 'router' && project.deviceConfigurations.get(each.id)?.ipAddress === '141.99.1.1')!.id;
const notebook = node('Notebook 1.10');
const engine = new NetworkRuntimeEngine(14);
engine.handle({ type: 'start', snapshot: { ...projectSnapshot(project), webBrowserNodeIds: new Set([notebook]) }, seed: 14, initialTimeMilliseconds: 0 });
const form = 'srcIP=&srcMask=&destIP=&destMask=&protocol=UDP&port=53&action=accept';
// Added first: once switched on, the firewall drops the browser too (by default).
engine.webBrowser(notebook)!.open('141.99.1.1/konfig', `onlySYN=1&defaultPolicy=drop&${form}&addrule=hinzuf%C3%BCgen`);
engine.handle({ type: 'advance', toMilliseconds: 5_000 });
engine.webBrowser(notebook)!.open('141.99.1.1/konfig', `firewallActivate=1&onlySYN=1&btnSave=speichern&defaultPolicy=drop&${form}`);
engine.handle({ type: 'advance', toMilliseconds: 10_000 });
const expected = firewallConfiguration({ isActive: true, rules: [firewallRule({ port: 53, protocol: 'udp', action: 'accept' })] });
expect(engine.firewallConfiguration(router)).toEqual(expected);
// The project itself is as it was opened, until the run's changes go back into it.
expect(project.firewallConfigurationsByNodeId.get(router)).toEqual(firewallConfiguration());
const saved = saveProjectArchive(projectWithSimulationChanges(project, engine.state.topologySnapshot)).archive;
const reopened = openProjectArchive(saved, counter());
const reopenedRouter = reopened.graph.nodes.find((each) => each.kind === 'router' && reopened.deviceConfigurations.get(each.id)?.ipAddress === '141.99.1.1')!.id;
expect(reopened.firewallConfigurationsByNodeId.get(reopenedRouter)).toEqual(expected);
});
it("keeps a node's IP forwarding where it differs from its kind's: a host that forwards, a router that does not", () => {
const system = (ipForwardingEnabled: boolean) => ({ manualRoutes: [], ipForwardingEnabled });
const project = importProject(