feat(fls): write the system software of a .fls, loaded by Java as the original

topologyWriter.ts now sets the system software each device's constructor
makes, through its setters: a switch's SSID and learning time, a host's
SSID, RIP, manual routes, DHCP client and server with static assignments,
static NAT, the modem, and a router's or home router's firewall. The
firewall is reached as XMLEncoder reaches it, through the web server's
`konfig` plug-in: the constructor hangs the same object there and among
the applications, where its key differs (Firewall on a router, NatGateway
on a home router). A switch's SSID the file lacked stays unwritten, so Java
rolls one as it did. Files and applications are later layers.

javaBeansWriter.ts: a call can carry statements on its result (a map's
value changed through get(key)), checked by Java's XMLDecoder in a new
case; a short() helper for Java's short values.

Checked by Java against Java: every corpus file, read and written again,
loads with the same system software (without files and applications) as
the original. The synthetic topology adds what the corpus lacks: a router
firewall switched on with rules of every protocol (one with a null
address), every flag away from its default, a modem with its own port and
target, and a PC's SSID, routes and DHCP server. 16 mutation probes, each
rewritten and loaded by Java, were all caught.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-30 08:18:52 +00:00
co-authored by Claude Opus 5.5
parent 314f696515
commit facad5843e
8 changed files with 749 additions and 227 deletions
+12
View File
@@ -82,6 +82,18 @@ const CASES: Record<string, { values: BeanValue[]; expected: unknown[] }> = {
{ class: 'java.util.HashMap', entries: [[text('key'), { int: 8 }]] },
],
},
// A method's result changed by the statements inside its call: a map's
// value reached through get(key), as XMLEncoder reaches what a
// constructor put into a map.
results: {
values: [
object('java.util.HashMap', [
{ call: 'put', args: ['key', list('java.util.ArrayList', ['first'])] },
{ call: 'get', args: ['key'], statements: [{ call: 'add', args: ['second'] }] },
]),
],
expected: [{ class: 'java.util.HashMap', entries: [[text('key'), items('java.util.ArrayList', [text('first'), text('second')])]] }],
},
shared: {
values: [list('java.util.LinkedList', [inner, other, inner, other]), file, file],
expected: [