feat(core): the command line with its local commands after Java, measured against Java
The terminal splits a line as Java's window does and runs ls, cd, pwd, mkdir, touch, cp, mv, rm, cat, test, help, ipconfig and route on the node's files, which are the project's own. Its texts are generated from the bundle Java loads. TerminalCases feeds Java's Terminal without a network (16 cases, de and en); eight cases name Java bugs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,8 @@
|
||||
// A DNS server runs only when it is switched on (Java: DNSServer.aktiv); an
|
||||
// echo, web or e-mail server is there either way, switched on or off (it can be
|
||||
// switched at run time). The programs read the nodes' files (a web server its
|
||||
// pages).
|
||||
// pages); the command line changes them, and as they are the project's own,
|
||||
// a project saved after the run holds the change, as in Java.
|
||||
//
|
||||
// Back the other way: what the simulation changes that Java keeps in the
|
||||
// project (its objects are the project's), so a project saved after it holds
|
||||
@@ -38,6 +39,7 @@ export function projectSnapshot(project: ImportedProject): TopologySnapshot {
|
||||
emailServers.set(nodeId, { domain: configuration.domain, accounts: configuration.accounts, isActive: project.activePrograms.get(nodeId)?.has('emailServer') === true });
|
||||
}
|
||||
const emailClients = new Map([...project.emailClientConfigurations].filter(([nodeId]) => project.installedPrograms.get(nodeId)?.has('emailClient') === true));
|
||||
const terminals = new Set([...project.installedPrograms].filter(([, programs]) => programs.has('commandPrompt')).map(([nodeId]) => nodeId));
|
||||
const webBrowsers = new Set([...project.installedPrograms].filter(([, programs]) => programs.has('webBrowser')).map(([nodeId]) => nodeId));
|
||||
return topologySnapshot({
|
||||
nodes: project.graph.nodes.map((node) => ({
|
||||
@@ -63,6 +65,7 @@ export function projectSnapshot(project: ImportedProject): TopologySnapshot {
|
||||
webBrowserNodeIds: webBrowsers,
|
||||
emailServersByNodeId: emailServers,
|
||||
emailClientsByNodeId: emailClients,
|
||||
terminalNodeIds: terminals,
|
||||
fileSystemsByNodeId: project.virtualFileSystems,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -857,6 +857,22 @@ describe('importProject rules', () => {
|
||||
expect(client('Rechner 3').account).toEqual(project.emailClientConfigurations.get(receiver)!.account);
|
||||
});
|
||||
|
||||
it("keeps what the command line did to a node's files in the project saved after the run", () => {
|
||||
const name = 'java-examples/Internet_Komplett_mit_eMail_Webserver_Intranet_Portforwarding_Firewall_DHCP_DE.fls';
|
||||
const project = openProjectArchive(new Uint8Array(readFileSync(join(corpusRoot, name))), counter());
|
||||
const notebook = project.graph.nodes.find((each) => each.displayName === 'Notebook' && project.deviceConfigurations.get(each.id)?.ipAddress === '10.10.20.11')!.id;
|
||||
const snapshot = projectSnapshot(project);
|
||||
expect(snapshot.terminalNodeIds.has(notebook)).toBe(true);
|
||||
const engine = new NetworkRuntimeEngine(14);
|
||||
engine.handle({ type: 'start', snapshot, seed: 14, initialTimeMilliseconds: 0 });
|
||||
for (const line of ['mkdir Projekt', 'cd Projekt', 'touch plan.txt']) engine.terminal(notebook)!.enter(line);
|
||||
engine.handle({ type: 'advance', toMilliseconds: 1_000 });
|
||||
|
||||
const reopened = openProjectArchive(saveProjectArchive(projectWithSimulationChanges(project, engine.state.topologySnapshot)).archive, counter());
|
||||
const reopenedNotebook = reopened.graph.nodes.find((each) => each.displayName === 'Notebook' && reopened.deviceConfigurations.get(each.id)?.ipAddress === '10.10.20.11')!.id;
|
||||
expect(reopened.virtualFileSystems.get(reopenedNotebook)!.entry('/Projekt/plan.txt').content).toEqual({ kind: 'text', text: '' });
|
||||
});
|
||||
|
||||
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(
|
||||
|
||||
Reference in New Issue
Block a user