summaryrefslogtreecommitdiff
path: root/src/test/java/protocols
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/protocols')
-rw-r--r--src/test/java/protocols/VSAbstractProtocolTest.java368
-rw-r--r--src/test/java/protocols/implementations/VSPingPongProtocolTest.java262
2 files changed, 630 insertions, 0 deletions
diff --git a/src/test/java/protocols/VSAbstractProtocolTest.java b/src/test/java/protocols/VSAbstractProtocolTest.java
new file mode 100644
index 0000000..28b2fc2
--- /dev/null
+++ b/src/test/java/protocols/VSAbstractProtocolTest.java
@@ -0,0 +1,368 @@
+package protocols;
+
+import core.VSInternalProcess;
+import core.VSMessage;
+import core.VSMessageStub;
+import core.VSTask;
+import events.internal.VSProtocolScheduleEvent;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import prefs.VSPrefs;
+import simulator.VSSimulatorVisualization;
+import core.VSTaskManager;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+/**
+ * Unit tests for VSAbstractProtocol.
+ */
+class VSAbstractProtocolTest {
+
+ @Mock
+ private VSInternalProcess mockProcess;
+
+ @Mock
+ private VSSimulatorVisualization mockCanvas;
+
+ @Mock
+ private VSTaskManager mockTaskManager;
+
+ @Mock
+ private VSMessage mockMessage;
+
+ @Mock
+ private VSMessageStub mockMessageStub;
+
+ @Mock
+ private VSPrefs mockPrefs;
+
+ @Mock
+ private ObjectOutputStream mockOutputStream;
+
+ @Mock
+ private ObjectInputStream mockInputStream;
+
+ private TestProtocol testProtocol;
+
+ /**
+ * Test implementation of VSAbstractProtocol.
+ */
+ private static class TestProtocol extends VSAbstractProtocol {
+ boolean clientInitCalled = false;
+ boolean serverInitCalled = false;
+ boolean clientResetCalled = false;
+ boolean serverResetCalled = false;
+ boolean clientScheduleCalled = false;
+ boolean serverScheduleCalled = false;
+ boolean clientRecvCalled = false;
+ boolean serverRecvCalled = false;
+ VSMessage lastClientMessage = null;
+ VSMessage lastServerMessage = null;
+
+ TestProtocol(boolean hasOnServerStart) {
+ super(hasOnServerStart);
+ }
+
+ @Override
+ public void onClientInit() {
+ clientInitCalled = true;
+ }
+
+ @Override
+ public void onClientReset() {
+ clientResetCalled = true;
+ }
+
+ @Override
+ public void onClientSchedule() {
+ clientScheduleCalled = true;
+ }
+
+ @Override
+ public void onClientRecv(VSMessage message) {
+ clientRecvCalled = true;
+ lastClientMessage = message;
+ }
+
+ @Override
+ public void onServerInit() {
+ serverInitCalled = true;
+ }
+
+ @Override
+ public void onServerReset() {
+ serverResetCalled = true;
+ }
+
+ @Override
+ public void onServerRecv(VSMessage message) {
+ serverRecvCalled = true;
+ lastServerMessage = message;
+ }
+
+ @Override
+ public void onServerSchedule() {
+ serverScheduleCalled = true;
+ }
+ }
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ testProtocol = new TestProtocol(true);
+
+ // Setup mock chain
+ when(mockProcess.getSimulatorCanvas()).thenReturn(mockCanvas);
+ when(mockCanvas.getTaskManager()).thenReturn(mockTaskManager);
+ when(mockCanvas.getNumProcesses()).thenReturn(5);
+ when(mockPrefs.getString(anyString())).thenReturn("TestString");
+
+ testProtocol.prefs = mockPrefs;
+ }
+
+ @Test
+ void testConstructor() {
+ TestProtocol serverStartProtocol = new TestProtocol(true);
+ assertTrue(serverStartProtocol.hasOnServerStart());
+
+ TestProtocol clientStartProtocol = new TestProtocol(false);
+ assertFalse(clientStartProtocol.hasOnServerStart());
+ }
+
+ @Test
+ void testServerClientFlags() {
+ assertFalse(testProtocol.isServer());
+ assertFalse(testProtocol.isClient());
+
+ testProtocol.isServer(true);
+ assertTrue(testProtocol.isServer());
+
+ testProtocol.isClient(true);
+ assertTrue(testProtocol.isClient());
+ }
+
+ @Test
+ void testSendMessage() {
+ testProtocol.process = mockProcess;
+ testProtocol.currentContextIsServer(true);
+
+ testProtocol.sendMessage(mockMessage);
+
+ verify(mockProcess).increaseLamportTime();
+ verify(mockProcess).increaseVectorTime();
+ verify(mockProcess).sendMessage(mockMessage);
+ }
+
+ @Test
+ void testSendMessageWithNullProcess() {
+ testProtocol.process = null;
+
+ // Should not throw exception
+ assertDoesNotThrow(() -> testProtocol.sendMessage(mockMessage));
+
+ // Should not interact with anything
+ verifyNoInteractions(mockProcess);
+ }
+
+ @Test
+ void testOnStartWithServerMode() {
+ testProtocol = new TestProtocol(true); // Has server start
+ testProtocol.process = mockProcess;
+ testProtocol.isServer(true);
+ testProtocol.prefs = mockPrefs;
+
+ testProtocol.onStart();
+
+ assertTrue(testProtocol.serverInitCalled);
+ assertFalse(testProtocol.clientInitCalled);
+ }
+
+ @Test
+ void testOnStartWithClientMode() {
+ testProtocol = new TestProtocol(false); // Has client start
+ testProtocol.process = mockProcess;
+ testProtocol.isClient(true);
+ testProtocol.prefs = mockPrefs;
+
+ testProtocol.onStart();
+
+ assertTrue(testProtocol.clientInitCalled);
+ assertFalse(testProtocol.serverInitCalled);
+ }
+
+ @Test
+ void testOnInit() {
+ testProtocol.process = mockProcess;
+ testProtocol.isServer(true);
+ testProtocol.isClient(true);
+
+ testProtocol.onInit();
+
+ assertTrue(testProtocol.serverInitCalled);
+ assertTrue(testProtocol.clientInitCalled);
+ }
+
+ @Test
+ void testOnMessageRecvWithCorrectProtocol() {
+ when(mockMessage.getProtocolClassname()).thenReturn(testProtocol.getClassname());
+ when(mockMessage.isServerMessage()).thenReturn(false); // Client message
+
+ testProtocol.process = mockProcess;
+ testProtocol.isServer(true);
+
+ testProtocol.onMessageRecvStart(mockMessage);
+
+ assertTrue(testProtocol.serverRecvCalled);
+ assertEquals(mockMessage, testProtocol.lastServerMessage);
+ }
+
+ @Test
+ void testOnMessageRecvWithIncorrectProtocol() {
+ when(mockMessage.getProtocolClassname()).thenReturn("DifferentProtocol");
+
+ testProtocol.process = mockProcess;
+ testProtocol.isServer(true);
+
+ testProtocol.onMessageRecvStart(mockMessage);
+
+ assertFalse(testProtocol.serverRecvCalled);
+ assertNull(testProtocol.lastServerMessage);
+ }
+
+ @Test
+ void testIsRelevantMessage() {
+ when(mockMessage.getProtocolClassname()).thenReturn(testProtocol.getClassname());
+
+ // Server receiving client message - should be relevant
+ when(mockMessage.isServerMessage()).thenReturn(false);
+ testProtocol.isServer(true);
+ testProtocol.isClient(false);
+ assertTrue(testProtocol.isRelevantMessage(mockMessage));
+
+ // Client receiving server message - should be relevant
+ when(mockMessage.isServerMessage()).thenReturn(true);
+ testProtocol.isServer(false);
+ testProtocol.isClient(true);
+ assertTrue(testProtocol.isRelevantMessage(mockMessage));
+
+ // Server receiving server message - should NOT be relevant
+ when(mockMessage.isServerMessage()).thenReturn(true);
+ testProtocol.isServer(true);
+ testProtocol.isClient(false);
+ assertFalse(testProtocol.isRelevantMessage(mockMessage));
+ }
+
+ @Test
+ void testScheduleAt() {
+ testProtocol.process = mockProcess;
+ testProtocol.currentContextIsServer(true);
+
+ long scheduleTime = 100L;
+ testProtocol.scheduleAt(scheduleTime);
+
+ ArgumentCaptor<VSTask> taskCaptor = ArgumentCaptor.forClass(VSTask.class);
+ verify(mockTaskManager).addTask(taskCaptor.capture());
+
+ VSTask capturedTask = taskCaptor.getValue();
+ assertNotNull(capturedTask);
+ assertEquals(mockProcess, capturedTask.getProcess());
+ }
+
+ @Test
+ void testRemoveSchedules() {
+ testProtocol.process = mockProcess;
+ testProtocol.currentContextIsServer(true);
+
+ // First add a schedule
+ testProtocol.scheduleAt(100L);
+
+ // Then remove it
+ testProtocol.removeSchedules();
+
+ verify(mockTaskManager).removeAllTasks(any());
+ }
+
+ @Test
+ void testReset() {
+ testProtocol.isServer(true);
+ testProtocol.isClient(true);
+
+ testProtocol.reset();
+
+ assertFalse(testProtocol.isServer());
+ assertFalse(testProtocol.isClient());
+ assertTrue(testProtocol.serverResetCalled);
+ assertTrue(testProtocol.clientResetCalled);
+ }
+
+ @Test
+ void testGetNumProcesses() {
+ testProtocol.process = mockProcess;
+
+ assertEquals(5, testProtocol.getNumProcesses());
+
+ testProtocol.process = null;
+ assertEquals(0, testProtocol.getNumProcesses());
+ }
+
+ @Test
+ void testToString() {
+ testProtocol.process = mockProcess;
+ testProtocol.currentContextIsServer(true);
+
+ String result = testProtocol.toString();
+
+ assertNotNull(result);
+ assertTrue(result.contains("TestString"));
+
+ // Test with null process
+ testProtocol.process = null;
+ assertEquals("", testProtocol.toString());
+ }
+
+ @Test
+ void testOnClientScheduleStart() {
+ testProtocol.isClient(true);
+
+ testProtocol.onClientScheduleStart();
+
+ assertTrue(testProtocol.clientScheduleCalled);
+ assertFalse(testProtocol.serverScheduleCalled);
+ }
+
+ @Test
+ void testOnServerScheduleStart() {
+ testProtocol.isServer(true);
+
+ testProtocol.onServerScheduleStart();
+
+ assertTrue(testProtocol.serverScheduleCalled);
+ assertFalse(testProtocol.clientScheduleCalled);
+ }
+
+ @Test
+ void testSerialization() throws IOException, ClassNotFoundException {
+ testProtocol.serialize(null, mockOutputStream);
+
+ verify(mockOutputStream, times(2)).writeObject(Boolean.FALSE);
+ verify(mockOutputStream).writeObject(Boolean.TRUE); // hasOnServerStart
+ }
+
+ @Test
+ void testDeserialization() throws IOException, ClassNotFoundException {
+ when(mockInputStream.readObject()).thenReturn(Boolean.FALSE, Boolean.TRUE, Boolean.FALSE);
+
+ testProtocol.deserialize(null, mockInputStream);
+
+ verify(mockInputStream, times(3)).readObject();
+ }
+} \ No newline at end of file
diff --git a/src/test/java/protocols/implementations/VSPingPongProtocolTest.java b/src/test/java/protocols/implementations/VSPingPongProtocolTest.java
new file mode 100644
index 0000000..9735a01
--- /dev/null
+++ b/src/test/java/protocols/implementations/VSPingPongProtocolTest.java
@@ -0,0 +1,262 @@
+package protocols.implementations;
+
+import core.VSInternalProcess;
+import core.VSMessage;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import prefs.VSPrefs;
+import simulator.VSSimulatorVisualization;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.*;
+
+/**
+ * Unit tests for VSPingPongProtocol.
+ */
+class VSPingPongProtocolTest {
+
+ @Mock
+ private VSInternalProcess mockProcess;
+
+ @Mock
+ private VSSimulatorVisualization mockCanvas;
+
+ @Mock
+ private VSPrefs mockPrefs;
+
+ private VSPingPongProtocol protocol;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ protocol = new VSPingPongProtocol();
+ protocol.process = mockProcess;
+ protocol.prefs = mockPrefs;
+
+ // Setup mock chain
+ when(mockProcess.getSimulatorCanvas()).thenReturn(mockCanvas);
+ when(mockPrefs.getString(anyString())).thenReturn("TestString");
+ }
+
+ @Test
+ void testConstructor() {
+ VSPingPongProtocol newProtocol = new VSPingPongProtocol();
+ assertFalse(newProtocol.hasOnServerStart()); // Should use client start
+ assertNotNull(newProtocol.getClassname());
+ assertTrue(newProtocol.getClassname().contains("VSPingPongProtocol"));
+ }
+
+ @Test
+ void testClientInit() {
+ // Should do nothing but not throw exception
+ assertDoesNotThrow(() -> protocol.onClientInit());
+ }
+
+ @Test
+ void testServerInit() {
+ // Should do nothing but not throw exception
+ assertDoesNotThrow(() -> protocol.onServerInit());
+ }
+
+ @Test
+ void testClientReset() {
+ // First send some messages to increment counter
+ protocol.isClient(true);
+ protocol.onClientStart();
+ protocol.onClientStart();
+
+ // Reset should clear counter
+ protocol.onClientReset();
+
+ // Verify counter was reset by checking next message
+ ArgumentCaptor<VSMessage> messageCaptor = ArgumentCaptor.forClass(VSMessage.class);
+ protocol.onClientStart();
+
+ verify(mockProcess, atLeast(1)).sendMessage(messageCaptor.capture());
+ VSMessage lastMessage = messageCaptor.getValue();
+ assertEquals(1, lastMessage.getInteger("counter"));
+ }
+
+ @Test
+ void testServerReset() {
+ // Set up server mode
+ protocol.isServer(true);
+ protocol.currentContextIsServer(true);
+
+ // Create a mock client message
+ VSMessage clientMessage = new VSMessage();
+ clientMessage.setBoolean("fromClient", true);
+ clientMessage.setInteger("counter", 1);
+
+ // Process some messages to increment counter
+ protocol.onServerRecv(clientMessage);
+ protocol.onServerRecv(clientMessage);
+
+ // Reset should clear counter
+ protocol.onServerReset();
+
+ // Verify counter was reset by checking next message
+ ArgumentCaptor<VSMessage> messageCaptor = ArgumentCaptor.forClass(VSMessage.class);
+ protocol.onServerRecv(clientMessage);
+
+ verify(mockProcess, atLeast(1)).sendMessage(messageCaptor.capture());
+ VSMessage lastMessage = messageCaptor.getValue();
+ assertEquals(1, lastMessage.getInteger("counter"));
+ }
+
+ @Test
+ void testClientStart() {
+ protocol.isClient(true);
+
+ ArgumentCaptor<VSMessage> messageCaptor = ArgumentCaptor.forClass(VSMessage.class);
+
+ protocol.onClientStart();
+
+ verify(mockProcess).sendMessage(messageCaptor.capture());
+
+ VSMessage sentMessage = messageCaptor.getValue();
+ assertTrue(sentMessage.getBoolean("fromClient"));
+ assertEquals(1, sentMessage.getInteger("counter"));
+
+ // Test counter increment
+ protocol.onClientStart();
+
+ verify(mockProcess, times(2)).sendMessage(messageCaptor.capture());
+ sentMessage = messageCaptor.getValue();
+ assertEquals(2, sentMessage.getInteger("counter"));
+ }
+
+ @Test
+ void testClientRecv() {
+ protocol.isClient(true);
+
+ // Create a valid server message
+ VSMessage serverMessage = new VSMessage();
+ serverMessage.setBoolean("fromServer", true);
+ serverMessage.setInteger("counter", 5);
+
+ ArgumentCaptor<VSMessage> messageCaptor = ArgumentCaptor.forClass(VSMessage.class);
+
+ protocol.onClientRecv(serverMessage);
+
+ verify(mockProcess).sendMessage(messageCaptor.capture());
+
+ VSMessage sentMessage = messageCaptor.getValue();
+ assertTrue(sentMessage.getBoolean("fromClient"));
+ assertEquals(1, sentMessage.getInteger("counter"));
+ }
+
+ @Test
+ void testClientRecvIgnoresNonServerMessage() {
+ protocol.isClient(true);
+
+ // Create an invalid message (not from server)
+ VSMessage invalidMessage = new VSMessage();
+ invalidMessage.setBoolean("fromServer", false);
+ invalidMessage.setInteger("counter", 5);
+
+ protocol.onClientRecv(invalidMessage);
+
+ // Should not send any message
+ verify(mockProcess, never()).sendMessage(any());
+ }
+
+ @Test
+ void testServerRecv() {
+ protocol.isServer(true);
+ protocol.currentContextIsServer(true);
+
+ // Create a valid client message
+ VSMessage clientMessage = new VSMessage();
+ clientMessage.setBoolean("fromClient", true);
+ clientMessage.setInteger("counter", 3);
+
+ ArgumentCaptor<VSMessage> messageCaptor = ArgumentCaptor.forClass(VSMessage.class);
+
+ protocol.onServerRecv(clientMessage);
+
+ verify(mockProcess).sendMessage(messageCaptor.capture());
+
+ VSMessage sentMessage = messageCaptor.getValue();
+ assertTrue(sentMessage.getBoolean("fromServer"));
+ assertEquals(1, sentMessage.getInteger("counter"));
+ }
+
+ @Test
+ void testServerRecvIgnoresNonClientMessage() {
+ protocol.isServer(true);
+ protocol.currentContextIsServer(true);
+
+ // Create an invalid message (not from client)
+ VSMessage invalidMessage = new VSMessage();
+ invalidMessage.setBoolean("fromClient", false);
+ invalidMessage.setInteger("counter", 5);
+
+ protocol.onServerRecv(invalidMessage);
+
+ // Should not send any message
+ verify(mockProcess, never()).sendMessage(any());
+ }
+
+ @Test
+ void testClientSchedule() {
+ // Should do nothing but not throw exception
+ assertDoesNotThrow(() -> protocol.onClientSchedule());
+ }
+
+ @Test
+ void testServerSchedule() {
+ // Should do nothing but not throw exception
+ assertDoesNotThrow(() -> protocol.onServerSchedule());
+ }
+
+ @Test
+ void testToString() {
+ String result = protocol.toString();
+
+ assertNotNull(result);
+ assertTrue(result.contains("New message afterwards"));
+ assertTrue(result.contains("TestString"));
+ }
+
+ @Test
+ void testPingPongInteraction() {
+ // Test a full ping-pong interaction
+ protocol.isClient(true);
+ protocol.isServer(true);
+
+ ArgumentCaptor<VSMessage> messageCaptor = ArgumentCaptor.forClass(VSMessage.class);
+
+ // Client starts the ping
+ protocol.currentContextIsServer(false);
+ protocol.onClientStart();
+
+ verify(mockProcess, times(1)).sendMessage(messageCaptor.capture());
+ VSMessage ping = messageCaptor.getValue();
+ assertTrue(ping.getBoolean("fromClient"));
+ assertEquals(1, ping.getInteger("counter"));
+
+ // Server receives ping and sends pong
+ protocol.currentContextIsServer(true);
+ protocol.onServerRecv(ping);
+
+ verify(mockProcess, times(2)).sendMessage(messageCaptor.capture());
+ VSMessage pong = messageCaptor.getValue();
+ assertTrue(pong.getBoolean("fromServer"));
+ assertEquals(1, pong.getInteger("counter"));
+
+ // Client receives pong and sends another ping
+ protocol.currentContextIsServer(false);
+ protocol.onClientRecv(pong);
+
+ verify(mockProcess, times(3)).sendMessage(messageCaptor.capture());
+ VSMessage ping2 = messageCaptor.getValue();
+ assertTrue(ping2.getBoolean("fromClient"));
+ assertEquals(2, ping2.getInteger("counter"));
+ }
+} \ No newline at end of file