summaryrefslogtreecommitdiff
path: root/src/test/java/testing/protocols/PingPongProtocolTest.java
blob: 3396e081e0f98d64ad9490ac58ab0431bdc42785 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package testing.protocols;

import testing.*;
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;

/**
 * JUnit test for Ping-Pong protocol using the headless testing framework.
 */
public class PingPongProtocolTest {
    private HeadlessSimulationRunner runner;
    
    @BeforeEach
    public void setup() {
        runner = new HeadlessSimulationRunner();
    }
    
    @AfterEach
    public void teardown() {
        runner.shutdown();
    }
    
    @Test
    @DisplayName("Test Ping-Pong protocol activation")
    public void testProtocolActivation() throws Exception {
        SimulationResult result = runner.runSimulation(
            "saved-simulations/ping-pong.dat", 
            1000
        );
        
        ProtocolVerifier verifier = new ProtocolVerifier()
            .expectLogExactly("Ping-Pong.*activated", 2)
            .expectLog("Ping-Pong Client activated")
            .expectLog("Ping-Pong Server activated");
            
        VerificationResult verification = verifier.verify(result.getAllLogs());
        
        assertTrue(verification.passed(), verification.getFailureMessage());
        assertEquals(2, result.getMetrics().getNumProcesses(), 
                    "Should have 2 processes");
    }
    
    @Test
    @DisplayName("Test Ping-Pong message exchange")
    public void testMessageExchange() throws Exception {
        SimulationResult result = runner.runSimulation(
            "saved-simulations/ping-pong.dat", 
            3000
        );
        
        ProtocolVerifier verifier = new ProtocolVerifier()
            .expectLog("Message sent")
            .expectLog("Message received")
            .expectLog("fromClient=true")
            .expectLog("fromServer=true")
            .expectSequence("fromClient=true", "fromServer=true");
            
        VerificationResult verification = verifier.verify(result.getAllLogs());
        assertTrue(verification.passed(), verification.getFailureMessage());
        
        // Check message balance
        int sent = result.countLogs("Message sent");
        int received = result.countLogs("Message received");
        assertTrue(Math.abs(sent - received) <= 1, 
                  "Sent/Received messages should be balanced");
    }
    
    @Test
    @DisplayName("Test Ping-Pong counter increments")
    public void testCounterIncrements() throws Exception {
        SimulationResult result = runner.runSimulation(
            "saved-simulations/ping-pong.dat", 
            5000
        );
        
        // Verify counter increments
        assertTrue(result.findFirst("counter=1").isPresent(), 
                  "Should have counter=1");
        assertTrue(result.findFirst("counter=2").isPresent(), 
                  "Should have counter=2");
        assertTrue(result.findFirst("counter=3").isPresent(), 
                  "Should have counter=3");
    }
    
    @Test
    @DisplayName("Test no errors occur during simulation")
    public void testNoErrors() throws Exception {
        SimulationResult result = runner.runSimulation(
            "saved-simulations/ping-pong.dat", 
            2000
        );
        
        ProtocolVerifier verifier = new ProtocolVerifier()
            .expectNoLog("ERROR")
            .expectNoLog("Exception")
            .expectNoLog("crashed")
            .expectNoLog("failed");
            
        VerificationResult verification = verifier.verify(result.getAllLogs());
        assertTrue(verification.passed(), "No errors should occur");
    }
    
    @Test
    @DisplayName("Test message timing and ordering")
    public void testMessageTiming() throws Exception {
        SimulationResult result = runner.runSimulation(
            "saved-simulations/ping-pong.dat", 
            3000
        );
        
        // Get all sent messages
        var sentMessages = result.findAll("Message sent");
        assertTrue(sentMessages.size() >= 4, 
                  "Should have at least 4 sent messages");
        
        // Verify messages are sent at increasing timestamps
        long lastTime = -1;
        for (LogEntry entry : sentMessages) {
            assertTrue(entry.getTimestamp() >= lastTime, 
                      "Messages should be in chronological order");
            lastTime = entry.getTimestamp();
        }
        
        // Verify Lamport time increases
        var allLogs = result.getAllLogs();
        for (LogEntry log : allLogs) {
            String msg = log.getMessage();
            if (msg.contains("Lamport time:")) {
                int start = msg.indexOf("Lamport time: ") + 14;
                int end = msg.indexOf(";", start);
                if (end == -1) end = msg.length();
                try {
                    int lamport = Integer.parseInt(msg.substring(start, end));
                    assertTrue(lamport >= 0, "Lamport time should be non-negative");
                } catch (NumberFormatException e) {
                    // Skip if format is different
                }
            }
        }
    }
}