From 0b5afe8839241dec66ba832cf42860ec69b87df8 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sun, 22 Jun 2025 11:58:00 +0300 Subject: Fix message delivery in headless test environment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fixed HeadlessSimulationEngine to use correct task manager from receiving process - Reduced message delays for testing (10-50ms instead of 500-2000ms) - Fixed process ID method call (getProcessID not getProcessId) - Improved message delivery scheduling to ensure tasks go to the right task manager This resolves message delivery issues where messages were sent but not received. BasicMulticast test now passes, but 12 protocol tests still failing. 🤖 Generated with Claude Code https://claude.ai/code Co-Authored-By: Claude --- .../simulator/builder/SimulationBuilderTest.java | 147 +++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 src/test/java/simulator/builder/SimulationBuilderTest.java (limited to 'src/test/java/simulator') diff --git a/src/test/java/simulator/builder/SimulationBuilderTest.java b/src/test/java/simulator/builder/SimulationBuilderTest.java new file mode 100644 index 0000000..82860f0 --- /dev/null +++ b/src/test/java/simulator/builder/SimulationBuilderTest.java @@ -0,0 +1,147 @@ +package simulator.builder; + +import org.junit.jupiter.api.*; +import static org.junit.jupiter.api.Assertions.*; +import java.io.File; +import java.nio.file.*; + +/** + * Tests for the SimulationBuilder framework + */ +class SimulationBuilderTest { + + private static final String TEST_DIR = "target/test-simulations/"; + + @BeforeEach + void setUp() throws Exception { + // Create test directory + Files.createDirectories(Paths.get(TEST_DIR)); + } + + @AfterEach + void tearDown() throws Exception { + // Clean up test files + File dir = new File(TEST_DIR); + if (dir.exists()) { + for (File file : dir.listFiles()) { + file.delete(); + } + } + } + + @Test + void testCreateBasicRaftSimulation() throws Exception { + String filename = TEST_DIR + "test-raft.dat"; + + // Create a basic Raft simulation + new SimulationBuilder() + .withProcesses(3) + .withProtocol(SimulationBuilder.Protocols.RAFT) + .activateServers(0, 1, 2) + .save(filename); + + // Verify file was created + File file = new File(filename); + assertTrue(file.exists(), "Simulation file should be created"); + assertTrue(file.length() > 1000, "File should have content"); + + // Verify it contains Raft protocol + String content = Files.readString(file.toPath()); + assertTrue(content.contains("VSRaftProtocol"), "Should contain Raft protocol classname"); + } + + @Test + void testCreateRaftWithClients() throws Exception { + String filename = TEST_DIR + "test-raft-clients.dat"; + + // Use factory method + SimulationFactory.createRaftSimulation(3, 2) + .save(filename); + + // Verify file was created + File file = new File(filename); + assertTrue(file.exists(), "Simulation file should be created"); + + // Should have 5 processes (3 servers + 2 clients) + String content = Files.readString(file.toPath()); + assertTrue(content.contains("VSRaftProtocol"), "Should contain Raft protocol"); + } + + @Test + void testCreatePingPongSimulation() throws Exception { + String filename = TEST_DIR + "test-pingpong.dat"; + + SimulationFactory.createPingPongSimulation(2) + .save(filename); + + File file = new File(filename); + assertTrue(file.exists(), "Simulation file should be created"); + + String content = Files.readString(file.toPath()); + assertTrue(content.contains("VSPingPongProtocol"), "Should contain PingPong protocol"); + } + + @Test + void testCreateComplexSimulation() throws Exception { + String filename = TEST_DIR + "test-complex.dat"; + + // Create a complex simulation with events + new SimulationBuilder() + .withProcesses(5) + .withProtocol(SimulationBuilder.Protocols.RAFT) + .withDuration(30000) + .activateServers(0, 1, 2) + .activateClients(1000, 3, 4) + .addCrashEvent(0, 5000) + .addRecoveryEvent(0, 10000) + .save(filename); + + File file = new File(filename); + assertTrue(file.exists(), "Simulation file should be created"); + assertTrue(file.length() > 5000, "Complex simulation should be larger"); + + String content = Files.readString(file.toPath()); + assertTrue(content.contains("VSProcessCrashEvent"), "Should contain crash event"); + assertTrue(content.contains("VSProcessRecoverEvent"), "Should contain recovery event"); + } + + @Test + void testAllProtocolTypes() throws Exception { + // Test that all protocol constants work + String[] protocols = { + SimulationBuilder.Protocols.RAFT, + SimulationBuilder.Protocols.PING_PONG, + SimulationBuilder.Protocols.BERKLEY_TIME, + SimulationBuilder.Protocols.BROADCAST, + SimulationBuilder.Protocols.ONE_PHASE_COMMIT, + SimulationBuilder.Protocols.TWO_PHASE_COMMIT, + SimulationBuilder.Protocols.RELIABLE_MULTICAST + }; + + for (String protocol : protocols) { + String filename = TEST_DIR + "test-" + protocol.substring(protocol.lastIndexOf('.') + 1) + ".dat"; + + new SimulationBuilder() + .withProcesses(3) + .withProtocol(protocol) + .activateServers(0, 1, 2) + .save(filename); + + File file = new File(filename); + assertTrue(file.exists(), "Should create file for " + protocol); + assertTrue(file.length() > 1000, "File should have content for " + protocol); + } + } + + @Test + void testInvalidConfiguration() { + // Test that invalid configurations throw exceptions + assertThrows(IllegalArgumentException.class, () -> { + SimulationFactory.createRaftSimulation(2, 0); // Too few servers + }); + + assertThrows(IllegalArgumentException.class, () -> { + SimulationFactory.createBerkeleyTimeSimulation(1); // Too few processes + }); + } +} \ No newline at end of file -- cgit v1.2.3