feat(sim): F4.6f1 what a run leaves goes back into the document
The oracle SaveAfterRunRun saves Java's project after a run. The room writes what a run leaves that Java keeps - files, running servers, virtual hosts, mail servers' domains and accounts, mail programs' accounts and folders, firewalls, DHCP clients' addresses - into the document as origin 'sim', at most once a second, after each action and at the stop; writeRunState writes only what differs. The command line now goes on in a folder made before a restart, as Java's does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1368,3 +1368,28 @@ Gemessen (03.10.2026):
|
||||
* Löschen löscht in Javas Fenster die Zeile der zuletzt **angeklickten**
|
||||
Liste: War zuvor eine gesendete Mail gewählt und ist im Posteingang schon
|
||||
eine markiert, geht die gesendete.
|
||||
|
||||
### Was ein Lauf im Projekt hinterlässt (F4.6f1)
|
||||
|
||||
`SaveAfterRunRun` öffnet ein Beispiel, wie FILIUS es öffnet, startet es,
|
||||
spielt eine Geschichte über die Programme (wie ihre Fenster sie aufrufen),
|
||||
stoppt wie der Entwurfsmodus (`stopSimulation`: `beenden` jedes Knotens) und
|
||||
speichert (`SzenarioVerwaltung.speichern`; Java speichert nur im Entwurf):
|
||||
`packages/sim/test/fixtures/after-run-email.fls` (email_komplett: Ordner
|
||||
und Datei aus der Befehlszeile, Konten gesetzt, eine Mail gesendet und
|
||||
abgerufen, ein neues Konto, Webserver aus und virtuelle Hosts an, ein
|
||||
E-Mail-Server aus mit neuer Domain) und `after-run-dhcp.fls`
|
||||
(einfaches_rechnernetz_komplett, 10 s DHCP).
|
||||
|
||||
Gemessen (03.10.2026):
|
||||
|
||||
* Java speichert die Dateien, wie die Programme sie hinterließen (auch
|
||||
`/www.conf/vhosts`, die Kontendateien), ob jeder Server läuft, das
|
||||
Kästchen der virtuellen Hosts (nach jedem Start an, wenn die Datei da
|
||||
ist), Domain und Konten der E-Mail-Server, Konto, Posteingang und
|
||||
Gesendete der E-Mail-Programme (eine abgerufene Mail mit „\n“ am Ende).
|
||||
* Die Adressen, die DHCP-Clients bekamen, stehen danach in ihren Karten,
|
||||
mit Gateway „0.0.0.0“, wo der Server keines vergibt.
|
||||
* Die Konten der Programme in email_komplett liegen nur in der alten
|
||||
`kontoListe`, die FILIUS 2.14 nicht liest; das Orakel setzt sie, wie man
|
||||
sie in den Dialog tippt (`setzeKonto`, `speichern`).
|
||||
|
||||
@@ -21,7 +21,7 @@ if [ ! -f "$upstream/target/filius.jar" ]; then
|
||||
fi
|
||||
classpath="$upstream/target/filius.jar:$upstream/target/lib/*"
|
||||
mkdir -p "$here/.build"
|
||||
javac -encoding UTF-8 -d "$here/.build" -cp "$classpath" "$here/src/FlsOracle.java" "$here/src/GetterDefaults.java" "$here/src/IpCheckCases.java" "$here/src/DnsHostsCases.java" "$here/src/EmailFileCases.java" "$here/src/BeansDump.java" "$here/src/Base64Cases.java" "$here/src/ScenarioNetwork.java" "$here/src/DhcpRun.java" "$here/src/TcpRun.java" "$here/src/DnsRun.java" "$here/src/ArpRun.java" "$here/src/RipRun.java" "$here/src/NatRun.java" "$here/src/WlanRun.java" "$here/src/ExampleRun.java" "$here/src/EchoRun.java" "$here/src/WebRun.java" "$here/src/RouterWebRun.java" "$here/src/KonfigCases.java" "$here/src/EmailRun.java" "$here/src/MailCases.java" "$here/src/EmailClientRun.java" "$here/src/TerminalCases.java" "$here/src/TerminalRun.java" "$here/src/FileCases.java" "$here/src/GnutellaRun.java" "$here/src/NewDeviceRun.java" "$here/src/SheetRun.java" "$here/src/TerminalWindowRun.java" "$here/src/InstallRun.java" "$here/src/BrowserWindowRun.java" "$here/src/MailWindowRun.java"
|
||||
javac -encoding UTF-8 -d "$here/.build" -cp "$classpath" "$here/src/FlsOracle.java" "$here/src/GetterDefaults.java" "$here/src/IpCheckCases.java" "$here/src/DnsHostsCases.java" "$here/src/EmailFileCases.java" "$here/src/BeansDump.java" "$here/src/Base64Cases.java" "$here/src/ScenarioNetwork.java" "$here/src/DhcpRun.java" "$here/src/TcpRun.java" "$here/src/DnsRun.java" "$here/src/ArpRun.java" "$here/src/RipRun.java" "$here/src/NatRun.java" "$here/src/WlanRun.java" "$here/src/ExampleRun.java" "$here/src/EchoRun.java" "$here/src/WebRun.java" "$here/src/RouterWebRun.java" "$here/src/KonfigCases.java" "$here/src/EmailRun.java" "$here/src/MailCases.java" "$here/src/EmailClientRun.java" "$here/src/TerminalCases.java" "$here/src/TerminalRun.java" "$here/src/FileCases.java" "$here/src/GnutellaRun.java" "$here/src/NewDeviceRun.java" "$here/src/SheetRun.java" "$here/src/TerminalWindowRun.java" "$here/src/InstallRun.java" "$here/src/BrowserWindowRun.java" "$here/src/MailWindowRun.java" "$here/src/SaveAfterRunRun.java"
|
||||
# FILIUS writes its settings below $HOME; keep them out of the real one.
|
||||
mkdir -p "$here/.build/home"
|
||||
# Removed first: a crashed run must not leave the previous result standing.
|
||||
@@ -389,6 +389,18 @@ HOME="$here/.build/home" xvfb-run -a java -Duser.language=de -Duser.country=DE -
|
||||
"$root/packages/core/test/scenarios/mail-lan.scenario.json" "$output" 2>&1 | grep -v 'logback\|^$\|^\s*at \|AWT-EventQueue' || true
|
||||
test -s "$output"
|
||||
|
||||
# What a run leaves in FILIUS' project: an example started, a story played,
|
||||
# stopped as the design mode stops it and saved (SaveAfterRunRun): the room's
|
||||
# write-back into the document (packages/sim/test/writeBack.test.ts).
|
||||
for run in email:email_komplett dhcp:einfaches_rechnernetz_komplett; do
|
||||
story="${run%%:*}"
|
||||
output="$root/packages/sim/test/fixtures/after-run-$story.fls"
|
||||
rm -f "$output"
|
||||
HOME="$here/.build/home" xvfb-run -a java -Duser.language=de -Duser.country=DE -cp "$classpath:$here/.build" SaveAfterRunRun \
|
||||
"$root/corpus/java-examples/${run##*:}.fls" "$story" "$output" 2>&1 | grep -v 'logback\|^$\|^\s*at ' || true
|
||||
test -s "$output"
|
||||
done
|
||||
|
||||
# FILIUS' own examples as Java FILIUS runs them, opened and started as FILIUS
|
||||
# does (ExampleRun): the acceptance of F2 (packages/fls/test/examplesJava.test.ts)
|
||||
# and the classics of F3 (web, email, gnutella; packages/fls/test/classicsJava.test.ts).
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
// What a run leaves in FILIUS' project: an example opened and started as
|
||||
// FILIUS does (ScenarioNetwork.fromFile), a story played through the
|
||||
// programs as their windows call them, the simulation stopped as the design
|
||||
// mode stops it (GUIMainMenu.stopSimulation: every node's beenden) and the
|
||||
// project saved (SzenarioVerwaltung.speichern; Java saves only in the design
|
||||
// mode). The reference for the room's write-back into the document
|
||||
// (packages/sim/test/writeBack.test.ts).
|
||||
//
|
||||
// SaveAfterRunRun <file.fls> <story> <out.fls>
|
||||
//
|
||||
// email email_komplett, with FILIUS' command line installed on Rechner 1
|
||||
// before the start: Rechner 1 and 2 set their accounts (as typed
|
||||
// into the program's dialog), Rechner 1 types "mkdir ordner" and
|
||||
// "touch ordner/notiz.txt", writes to rechner2@filius.de; Rechner 2
|
||||
// fetches; Mail-Server (filius.de) gets the account "neu"; the
|
||||
// Web-Server is switched off, its virtual hosts on with the row
|
||||
// a.de → ordner; Mail-Server (senior.de) is switched off and its
|
||||
// domain set to senior.org
|
||||
// dhcp einfaches_rechnernetz_komplett: the notebooks get their
|
||||
// addresses from the server (10 s)
|
||||
|
||||
import filius.gui.GUIContainer;
|
||||
import filius.gui.netzwerksicht.GUIKnotenItem;
|
||||
import filius.hardware.knoten.Knoten;
|
||||
import filius.rahmenprogramm.SzenarioVerwaltung;
|
||||
import filius.software.email.Email;
|
||||
import filius.software.email.EmailAnwendung;
|
||||
import filius.software.email.EmailKonto;
|
||||
import filius.software.email.EmailServer;
|
||||
import filius.software.email.EmailUtils;
|
||||
import filius.software.lokal.Terminal;
|
||||
import filius.software.system.Betriebssystem;
|
||||
import filius.software.system.InternetKnotenBetriebssystem;
|
||||
import filius.software.www.WebServer;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public class SaveAfterRunRun {
|
||||
static ScenarioNetwork network;
|
||||
|
||||
static InternetKnotenBetriebssystem system(String name) {
|
||||
Knoten knoten = network.nodes.get(name);
|
||||
if (knoten == null) throw new IllegalStateException("no node " + name);
|
||||
return (InternetKnotenBetriebssystem) knoten.getSystemSoftware();
|
||||
}
|
||||
|
||||
/** GUIApplicationTerminalWindow on Enter: the line handed to the program. */
|
||||
static void type(Terminal terminal, String line) throws Exception {
|
||||
StringTokenizer tokens = new StringTokenizer(line, " ");
|
||||
String command = tokens.nextToken();
|
||||
String[] parameters = new String[3 + tokens.countTokens()];
|
||||
Arrays.fill(parameters, "");
|
||||
for (int index = 0; tokens.hasMoreTokens(); index++) parameters[index] = tokens.nextToken();
|
||||
terminal.terminalEingabeAuswerten(command, parameters);
|
||||
Thread.sleep(500);
|
||||
}
|
||||
|
||||
/**
|
||||
* The account as one types it into the program's dialog and saves it
|
||||
* (kontoSpeichern: setzeKonto, speichern): the file keeps it only in the
|
||||
* older kontoListe, which FILIUS 2.14 no longer reads.
|
||||
*/
|
||||
static EmailKonto account(EmailAnwendung program, String user, String server, String domain, String lastName) {
|
||||
EmailKonto account = new EmailKonto();
|
||||
account.setVorname("Rechner");
|
||||
account.setNachname(lastName);
|
||||
account.setBenutzername(user);
|
||||
account.setPasswort(user);
|
||||
account.setPop3port("110");
|
||||
account.setPop3server(server);
|
||||
account.setSmtpport("25");
|
||||
account.setSmtpserver(server);
|
||||
account.setEmailAdresse(user + "@" + domain);
|
||||
program.setzeKonto(account);
|
||||
program.speichern();
|
||||
return account;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
try {
|
||||
run(args);
|
||||
} catch (Throwable error) {
|
||||
error.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
static void run(String[] args) throws Exception {
|
||||
network = ScenarioNetwork.fromFile(args[0]);
|
||||
String story = args[1];
|
||||
if (story.equals("email")) {
|
||||
((Betriebssystem) system("Rechner 1")).installAndStartAppIfAvailable("filius.software.lokal.Terminal");
|
||||
}
|
||||
network.start();
|
||||
Thread.sleep(2000);
|
||||
switch (story) {
|
||||
case "email": {
|
||||
Terminal terminal = (Terminal) system("Rechner 1").holeSoftware("filius.software.lokal.Terminal");
|
||||
type(terminal, "mkdir ordner");
|
||||
type(terminal, "touch ordner/notiz.txt");
|
||||
EmailAnwendung one = (EmailAnwendung) system("Rechner 1").holeSoftware("filius.software.email.EmailAnwendung");
|
||||
EmailKonto account = account(one, "rechner1", "141.99.50.232", "filius.de", "1");
|
||||
Email mail = new Email();
|
||||
mail.setAbsender(account.getVorname() + (!account.getNachname().isEmpty() ? (" " + account.getNachname()) : "") + " <" + account.getEmailAdresse() + ">");
|
||||
mail.setEmpfaenger(EmailUtils.stringToAddressEntryList("rechner2@filius.de"));
|
||||
mail.setCc(EmailUtils.stringToAddressEntryList(""));
|
||||
mail.setBcc(EmailUtils.stringToAddressEntryList(""));
|
||||
mail.setBetreff("Nach dem Lauf");
|
||||
mail.setText("Erste Zeile\nZweite Zeile");
|
||||
one.versendeEmail(account.getSmtpserver(), mail, account.getEmailAdresse());
|
||||
Thread.sleep(8000);
|
||||
EmailAnwendung two = (EmailAnwendung) system("Rechner 2").holeSoftware("filius.software.email.EmailAnwendung");
|
||||
EmailKonto other = account(two, "rechner2", "141.99.50.232", "filius.de", "2");
|
||||
two.emailsAbholenEmails(other.getBenutzername(), other.getPasswort(), other.getPop3port(), other.getPop3server());
|
||||
Thread.sleep(8000);
|
||||
((EmailServer) system("Mail-Server (filius.de)").holeSoftware("filius.software.email.EmailServer")).benutzerHinzufuegen("neu", "pw", "Nachname", "Vorname");
|
||||
WebServer web = (WebServer) system("Web-Server").holeSoftware("filius.software.www.WebServer");
|
||||
web.setAktiv(false);
|
||||
web.setUseVHost(true);
|
||||
web.changeVHostTable(0, 0, "a.de");
|
||||
web.changeVHostTable(0, 1, "ordner");
|
||||
EmailServer senior = (EmailServer) system("Mail-Server (senior.de)").holeSoftware("filius.software.email.EmailServer");
|
||||
senior.setAktiv(false);
|
||||
senior.setMailDomain("senior.org");
|
||||
Thread.sleep(1000);
|
||||
break;
|
||||
}
|
||||
case "dhcp":
|
||||
Thread.sleep(10000);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("unknown story " + story);
|
||||
}
|
||||
// GUIMainMenu.stopSimulation, then the design mode's save.
|
||||
for (GUIKnotenItem item : GUIContainer.getGUIContainer().getKnotenItems()) {
|
||||
try {
|
||||
item.getKnoten().getSystemSoftware().beenden();
|
||||
} catch (Exception error) {}
|
||||
}
|
||||
Thread.sleep(1000);
|
||||
GUIContainer gui = GUIContainer.getGUIContainer();
|
||||
if (!SzenarioVerwaltung.getInstance().speichern(args[2], gui.getKnotenItems(), gui.getCableItems(), gui.getDocuItems())) {
|
||||
throw new IllegalStateException("FILIUS could not save " + args[2]);
|
||||
}
|
||||
System.out.println("saved after the run: " + story);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user