summaryrefslogtreecommitdiff
path: root/src/main/java/testing/HeadlessSimulationRunner.java
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-06-21 20:10:38 +0300
committerPaul Buetow <paul@buetow.org>2025-06-21 20:10:38 +0300
commit695adc1f6bfb0a0eeef4dd6c035475ea2826871f (patch)
tree945fc0552d4f7f1ef1f468f6030e9925970fa72b /src/main/java/testing/HeadlessSimulationRunner.java
parentd3b697218773eaa5a3dd368705184726dbc0fa38 (diff)
Complete GUI decoupling implementation for headless testing
- Implement MessageHandler pattern to decouple message sending from visualization - Add HeadlessLoader to load simulations without GUI components - Create HeadlessProtocolRunner for clean protocol test execution - Update VSInternalProcess to use MessageHandler for message routing - Add null checks in VSSimulator for headless mode compatibility - Update VSSimulatorVisualization paint() to check for headless mode - Remove obsolete test scripts and documentation - Update test-protocols.sh to remove GUI error suppression options - Consolidate testing documentation in docs/testing-guide.md All protocol tests now run cleanly in headless mode without GUI errors, enabling proper CI/CD integration and automated testing. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Diffstat (limited to 'src/main/java/testing/HeadlessSimulationRunner.java')
-rw-r--r--src/main/java/testing/HeadlessSimulationRunner.java52
1 files changed, 51 insertions, 1 deletions
diff --git a/src/main/java/testing/HeadlessSimulationRunner.java b/src/main/java/testing/HeadlessSimulationRunner.java
index c3b699e..0b19a40 100644
--- a/src/main/java/testing/HeadlessSimulationRunner.java
+++ b/src/main/java/testing/HeadlessSimulationRunner.java
@@ -1,6 +1,8 @@
package testing;
import simulator.*;
+import simulator.engine.*;
+import simulator.messaging.*;
import core.*;
import prefs.*;
import events.*;
@@ -48,11 +50,18 @@ public class HeadlessSimulationRunner {
System.out.println("Loading simulation: " + simulationFile);
try {
- // Use the new headless loader
+ // Use HeadlessLoader to avoid any GUI initialization
HeadlessLoader.LoadedSimulation loaded = HeadlessLoader.load(simulationFile, prefs);
simulator = loaded.getSimulator();
viz = loaded.getVisualization();
+ if (simulator == null || viz == null) {
+ throw new IllegalStateException("Failed to load simulation");
+ }
+
+ // Set up headless message handlers for all processes
+ setupHeadlessMessageHandlers(viz);
+
// Install log capture
logCapture = new LogCapture();
logCapture.setPrintLogs(printLogs);
@@ -185,4 +194,45 @@ public class HeadlessSimulationRunner {
executor.shutdownNow();
}
}
+
+ /**
+ * Sets up headless message handlers for all processes to avoid GUI dependencies.
+ */
+ private void setupHeadlessMessageHandlers(VSSimulatorVisualization viz) {
+ // Create a headless simulation engine
+ HeadlessSimulationEngine engine = new HeadlessSimulationEngine(prefs, logCapture);
+
+ // Copy processes to engine
+ for (int i = 0; i < viz.getNumProcesses(); i++) {
+ VSInternalProcess process = viz.getProcess(i);
+ if (process != null) {
+ engine.addProcess(process);
+
+ // Create and set headless message handler
+ MessageHandler handler = new HeadlessMessageHandler(engine);
+ process.setMessageHandler(handler);
+ }
+ }
+
+ // Copy task manager state
+ try {
+ VSTaskManager vizTaskManager = viz.getTaskManager();
+ VSTaskManager engineTaskManager = engine.getTaskManager();
+
+ // Use reflection to copy task queues
+ Field globalTasksField = VSTaskManager.class.getDeclaredField("globalTasks");
+ globalTasksField.setAccessible(true);
+ Field localTasksField = VSTaskManager.class.getDeclaredField("localTasks");
+ localTasksField.setAccessible(true);
+
+ Object globalTasks = globalTasksField.get(vizTaskManager);
+ Object localTasks = localTasksField.get(vizTaskManager);
+
+ globalTasksField.set(engineTaskManager, globalTasks);
+ localTasksField.set(engineTaskManager, localTasks);
+ } catch (Exception e) {
+ // Log but don't fail - task manager state might not be critical
+ System.err.println("Warning: Could not copy task manager state: " + e.getMessage());
+ }
+ }
} \ No newline at end of file