// Uses FILIUS' own echo server and generic client windows // (GUIApplicationServerBausteinWindow, GUIApplicationClientBausteinWindow on // their GUIDesktopPanels) on mail-lan's network as a person does: the // server's port field and start button, the client's address and port // fields, "Verbinden"/"Trennen", the message field and "Senden" — a port // that is no number too, an empty message, the server stopped while the // client is connected, a port nobody listens on, a name nobody knows. After // each step it writes what both windows show: the buttons' texts, the // fields (and whether they can be typed into), the lines. The reference for // the editor's echo windows (packages/sim/test/echoWindow.test.ts). // // Usage: java -cp filius.jar:lib/*:classes EchoWindowRun import filius.gui.anwendungssicht.GUIApplicationClientBausteinWindow; import filius.gui.anwendungssicht.GUIApplicationServerBausteinWindow; import filius.gui.anwendungssicht.GUIDesktopPanel; import filius.software.system.Betriebssystem; import java.awt.FlowLayout; import java.io.FileOutputStream; import java.lang.reflect.Field; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.SwingUtilities; public class EchoWindowRun { static final String CLIENT = "00000000-0000-0000-0000-000000000201"; static final String SERVER = "00000000-0000-0000-0000-000000000203"; static final List steps = new ArrayList<>(); static GUIApplicationServerBausteinWindow server; static GUIApplicationClientBausteinWindow client; /** Exceptions the windows' buttons threw on the event thread since the last step. */ static final List thrown = new ArrayList<>(); static Object field(Class owner, Object object, String name) throws Exception { Field field = owner.getDeclaredField(name); field.setAccessible(true); return field.get(object); } static void onEdt(Runnable action) throws Exception { SwingUtilities.invokeLater(() -> { try { action.run(); } catch (RuntimeException error) { synchronized (thrown) { thrown.add(error.getClass().getSimpleName() + ": " + error.getMessage()); } } }); Thread.sleep(400); } static Map textField(JTextField field) { Map shown = new LinkedHashMap<>(); shown.put("text", field.getText()); shown.put("editable", field.isEditable()); return shown; } static void step(String name) throws Exception { Class s = GUIApplicationServerBausteinWindow.class; Class c = GUIApplicationClientBausteinWindow.class; Map result = new LinkedHashMap<>(); result.put("step", name); Map serverShown = new LinkedHashMap<>(); serverShown.put("button", ((JButton) field(s, server, "bStartStop")).getText()); serverShown.put("port", textField((JTextField) field(s, server, "tfPort"))); serverShown.put("log", ((JTextArea) field(s, server, "taLog")).getText()); result.put("server", serverShown); Map clientShown = new LinkedHashMap<>(); clientShown.put("connect", ((JButton) field(c, client, "btVerbinden")).getText()); clientShown.put("sendEnabled", ((JButton) field(c, client, "btSenden")).isEnabled()); clientShown.put("address", textField((JTextField) field(c, client, "tfServerAdresse"))); clientShown.put("port", textField((JTextField) field(c, client, "tfServerPort"))); clientShown.put("message", ((JTextArea) field(c, client, "taSenden")).getText()); clientShown.put("output", ((JTextArea) field(c, client, "taAusgabe")).getText()); result.put("client", clientShown); synchronized (thrown) { result.put("thrown", new ArrayList<>(thrown)); thrown.clear(); } steps.add(result); } static void type(Class owner, Object window, String name, String text) throws Exception { Object component = field(owner, window, name); onEdt(() -> ((javax.swing.text.JTextComponent) component).setText(text)); } static void press(Class owner, Object window, String name, long wait) throws Exception { JButton button = (JButton) field(owner, window, name); onEdt(button::doClick); Thread.sleep(wait); } 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 { ScenarioNetwork network = ScenarioNetwork.read(args[0]); Betriebssystem serverSystem = (Betriebssystem) network.nodes.get(SERVER).getSystemSoftware(); Betriebssystem clientSystem = (Betriebssystem) network.nodes.get(CLIENT).getSystemSoftware(); serverSystem.installApp("filius.software.clientserver.ServerBaustein", false); clientSystem.installApp("filius.software.clientserver.ClientBaustein", false); network.start(); Thread.sleep(500); JFrame frame = new JFrame(); GUIDesktopPanel serverDesktop = new GUIDesktopPanel(serverSystem); GUIDesktopPanel clientDesktop = new GUIDesktopPanel(clientSystem); frame.getContentPane().setLayout(new FlowLayout()); frame.getContentPane().add(serverDesktop); frame.getContentPane().add(clientDesktop); server = (GUIApplicationServerBausteinWindow) serverDesktop.starteAnwendung("filius.software.clientserver.ServerBaustein"); client = (GUIApplicationClientBausteinWindow) clientDesktop.starteAnwendung("filius.software.clientserver.ClientBaustein"); SwingUtilities.invokeAndWait(() -> { frame.pack(); frame.setVisible(true); }); Thread.sleep(500); Class s = GUIApplicationServerBausteinWindow.class; Class c = GUIApplicationClientBausteinWindow.class; step("open"); type(s, server, "tfPort", "abc"); press(s, server, "bStartStop", 500); step("server: start with port abc"); type(s, server, "tfPort", "55555"); press(s, server, "bStartStop", 1000); step("server: start with port 55555"); type(c, client, "tfServerAdresse", "192.168.0.30"); type(c, client, "tfServerPort", "x"); press(c, client, "btVerbinden", 500); step("client: connect with port x"); type(c, client, "tfServerAdresse", "192.168.0.30"); type(c, client, "tfServerPort", "55555"); press(c, client, "btVerbinden", 6000); step("client: connect to 192.168.0.30:55555"); type(c, client, "taSenden", "Hallo Echo"); press(c, client, "btSenden", 4000); step("client: send Hallo Echo"); type(c, client, "taSenden", ""); press(c, client, "btSenden", 4000); step("client: send nothing"); type(c, client, "taSenden", "Zeile 1\nZeile 2"); press(c, client, "btSenden", 4000); step("client: send two lines"); press(s, server, "bStartStop", 4000); step("server: stop while connected"); type(c, client, "taSenden", "noch da?"); press(c, client, "btSenden", 8000); step("client: send after the server stopped"); press(c, client, "btVerbinden", 3000); step("client: Trennen"); press(s, server, "bStartStop", 1000); step("server: start again"); press(c, client, "btVerbinden", 6000); step("client: connect again"); press(c, client, "btVerbinden", 3000); step("client: Trennen again"); type(c, client, "tfServerPort", "4711"); press(c, client, "btVerbinden", 12000); step("client: connect to a port nobody listens on"); type(c, client, "tfServerAdresse", "gibtsnicht"); type(c, client, "tfServerPort", "55555"); press(c, client, "btVerbinden", 12000); step("client: connect to a name nobody knows"); Map output = new LinkedHashMap<>(); output.put("steps", steps); try (FileOutputStream out = new FileOutputStream(args[1])) { out.write((FlsOracle.Json.write(output, "") + "\n").getBytes(StandardCharsets.UTF_8)); } network.stop(); System.out.println("echo window steps: " + steps.size()); } }