summaryrefslogtreecommitdiff
path: root/src/test/java/core/VSTaskTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/core/VSTaskTest.java')
-rw-r--r--src/test/java/core/VSTaskTest.java510
1 files changed, 510 insertions, 0 deletions
diff --git a/src/test/java/core/VSTaskTest.java b/src/test/java/core/VSTaskTest.java
new file mode 100644
index 0000000..3fbec3c
--- /dev/null
+++ b/src/test/java/core/VSTaskTest.java
@@ -0,0 +1,510 @@
+package core;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.DisplayName;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import events.VSAbstractEvent;
+import events.implementations.VSProcessCrashEvent;
+import events.implementations.VSProcessRecoverEvent;
+import events.internal.VSMessageReceiveEvent;
+import events.internal.VSProtocolEvent;
+import exceptions.VSEventNotCopyableException;
+import prefs.VSPrefs;
+import protocols.VSAbstractProtocol;
+import serialize.VSSerialize;
+
+/**
+ * Unit tests for VSTask class.
+ * Tests task creation, execution, comparison, and serialization functionality.
+ *
+ * @author Test Suite
+ */
+class VSTaskTest {
+
+ @Mock
+ private VSInternalProcess mockProcess;
+
+ @Mock
+ private VSAbstractEvent mockEvent;
+
+ @Mock
+ private VSPrefs mockPrefs;
+
+ @Mock
+ private VSAbstractProtocol mockProtocol;
+
+ private VSTask task;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ when(mockProcess.getPrefs()).thenReturn(mockPrefs);
+ when(mockPrefs.getString("lang.task")).thenReturn("Task");
+ when(mockProcess.getProcessID()).thenReturn(1);
+ }
+
+ @Test
+ @DisplayName("Test VSTask constructor with local timing")
+ void testConstructorLocalTiming() {
+ // Given
+ long taskTime = 1000L;
+
+ // When
+ task = new VSTask(taskTime, mockProcess, mockEvent, VSTask.LOCAL);
+
+ // Then
+ assertEquals(taskTime, task.getTaskTime());
+ assertEquals(mockProcess, task.getProcess());
+ assertEquals(mockEvent, task.getEvent());
+ assertFalse(task.isGlobalTimed());
+ assertTrue(task.getTaskNum() > 0);
+ }
+
+ @Test
+ @DisplayName("Test VSTask constructor with global timing")
+ void testConstructorGlobalTiming() {
+ // Given
+ long taskTime = 2000L;
+
+ // When
+ task = new VSTask(taskTime, mockProcess, mockEvent, VSTask.GLOBAL);
+
+ // Then
+ assertEquals(taskTime, task.getTaskTime());
+ assertTrue(task.isGlobalTimed());
+ }
+
+ @Test
+ @DisplayName("Test VSTask constructor with negative time")
+ void testConstructorNegativeTime() {
+ // Given
+ long negativeTime = -100L;
+
+ // When
+ task = new VSTask(negativeTime, mockProcess, mockEvent, VSTask.LOCAL);
+
+ // Then
+ assertEquals(0L, task.getTaskTime()); // Should be set to 0
+ }
+
+ @Test
+ @DisplayName("Test VSTask copy constructor with copyable event")
+ void testCopyConstructorWithCopyableEvent() throws VSEventNotCopyableException {
+ // Given
+ VSTask originalTask = new VSTask(1000L, mockProcess, mockEvent, VSTask.LOCAL);
+ VSAbstractEvent mockCopyEvent = mock(VSAbstractEvent.class);
+ when(mockEvent.getCopy()).thenReturn(mockCopyEvent);
+
+ // When
+ VSTask copiedTask = new VSTask(originalTask);
+
+ // Then
+ assertEquals(originalTask.getTaskTime(), copiedTask.getTaskTime());
+ assertEquals(originalTask.getProcess(), copiedTask.getProcess());
+ assertEquals(mockCopyEvent, copiedTask.getEvent());
+ assertEquals(originalTask.isGlobalTimed(), copiedTask.isGlobalTimed());
+ }
+
+ @Test
+ @DisplayName("Test VSTask copy constructor with non-copyable event")
+ void testCopyConstructorWithNonCopyableEvent() throws VSEventNotCopyableException {
+ // Given
+ VSTask originalTask = new VSTask(1000L, mockProcess, mockEvent, VSTask.LOCAL);
+ when(mockEvent.getCopy()).thenThrow(new VSEventNotCopyableException("Not copyable"));
+
+ // When
+ VSTask copiedTask = new VSTask(originalTask);
+
+ // Then
+ assertEquals(originalTask.getEvent(), copiedTask.getEvent()); // Should use original event
+ }
+
+ @Test
+ @DisplayName("Test isProgrammed getter and setter")
+ void testIsProgrammedGetterSetter() {
+ // Given
+ task = new VSTask(1000L, mockProcess, mockEvent, VSTask.LOCAL);
+
+ // When/Then
+ assertFalse(task.isProgrammed()); // Default value
+
+ task.isProgrammed(true);
+ assertTrue(task.isProgrammed());
+
+ task.isProgrammed(false);
+ assertFalse(task.isProgrammed());
+ }
+
+ @Test
+ @DisplayName("Test hasInternalEvent method")
+ void testHasInternalEvent() {
+ // Given
+ VSAbstractEvent normalEvent = mock(VSAbstractEvent.class);
+ VSMessageReceiveEvent internalEvent = mock(VSMessageReceiveEvent.class);
+
+ // When/Then
+ task = new VSTask(1000L, mockProcess, normalEvent, VSTask.LOCAL);
+ assertFalse(task.hasInternalEvent());
+
+ task = new VSTask(1000L, mockProcess, internalEvent, VSTask.LOCAL);
+ assertTrue(task.hasInternalEvent());
+ }
+
+ @Test
+ @DisplayName("Test hasMessageReceiveEvent method")
+ void testHasMessageReceiveEvent() {
+ // Given
+ VSMessageReceiveEvent messageEvent = mock(VSMessageReceiveEvent.class);
+
+ // When
+ task = new VSTask(1000L, mockProcess, messageEvent, VSTask.LOCAL);
+
+ // Then
+ assertTrue(task.hasMessageReceiveEvent());
+ }
+
+ @Test
+ @DisplayName("Test hasProcessRecoverEvent method")
+ void testHasProcessRecoverEvent() {
+ // Given
+ VSProcessRecoverEvent recoverEvent = mock(VSProcessRecoverEvent.class);
+
+ // When
+ task = new VSTask(1000L, mockProcess, recoverEvent, VSTask.LOCAL);
+
+ // Then
+ assertTrue(task.hasProcessRecoverEvent());
+ }
+
+ @Test
+ @DisplayName("Test isProtocol method")
+ void testIsProtocol() {
+ // Given
+ when(mockProtocol.equals(mockProtocol)).thenReturn(true);
+
+ // When
+ task = new VSTask(1000L, mockProcess, mockProtocol, VSTask.LOCAL);
+
+ // Then
+ assertTrue(task.isProtocol(mockProtocol));
+
+ VSAbstractProtocol otherProtocol = mock(VSAbstractProtocol.class);
+ assertFalse(task.isProtocol(otherProtocol));
+ }
+
+ @Test
+ @DisplayName("Test timeOver method for local timed task")
+ void testTimeOverLocalTimed() {
+ // Given
+ task = new VSTask(1000L, mockProcess, mockEvent, VSTask.LOCAL);
+
+ // When/Then
+ when(mockProcess.getTime()).thenReturn(500L);
+ assertFalse(task.timeOver());
+
+ when(mockProcess.getTime()).thenReturn(1001L);
+ assertTrue(task.timeOver());
+ }
+
+ @Test
+ @DisplayName("Test timeOver method for global timed task")
+ void testTimeOverGlobalTimed() {
+ // Given
+ task = new VSTask(1000L, mockProcess, mockEvent, VSTask.GLOBAL);
+
+ // When/Then
+ when(mockProcess.getGlobalTime()).thenReturn(500L);
+ assertFalse(task.timeOver());
+
+ when(mockProcess.getGlobalTime()).thenReturn(1001L);
+ assertTrue(task.timeOver());
+ }
+
+ @Test
+ @DisplayName("Test equals method")
+ void testEquals() {
+ // Given
+ VSTask task1 = new VSTask(1000L, mockProcess, mockEvent, VSTask.LOCAL);
+ VSTask task2 = new VSTask(2000L, mockProcess, mockEvent, VSTask.GLOBAL);
+ VSTask task3 = new VSTask(task1); // Copy constructor ensures different taskNum
+
+ // When/Then
+ assertTrue(task1.equals(task1)); // Same object
+ assertFalse(task1.equals(task2)); // Different task nums
+ assertFalse(task1.equals(task3)); // Different task nums even though copied
+ }
+
+ @Test
+ @DisplayName("Test isProcess method")
+ void testIsProcess() {
+ // Given
+ task = new VSTask(1000L, mockProcess, mockEvent, VSTask.LOCAL);
+ VSInternalProcess otherProcess = mock(VSInternalProcess.class);
+
+ when(mockProcess.equals(mockProcess)).thenReturn(true);
+ when(mockProcess.equals(otherProcess)).thenReturn(false);
+
+ // When/Then
+ assertTrue(task.isProcess(mockProcess));
+ assertFalse(task.isProcess(otherProcess));
+ }
+
+ @Test
+ @DisplayName("Test run method initializes event and calls onStart")
+ void testRunMethod() {
+ // Given
+ task = new VSTask(1000L, mockProcess, mockEvent, VSTask.LOCAL);
+ when(mockEvent.getProcess()).thenReturn(null);
+
+ // When
+ task.run();
+
+ // Then
+ verify(mockEvent).init(mockProcess);
+ verify(mockProcess).increaseVectorAndLamportTimeIfAll();
+ verify(mockEvent).onStart();
+ }
+
+ @Test
+ @DisplayName("Test run method with MessageReceiveEvent does not increase time")
+ void testRunMethodWithMessageReceiveEvent() {
+ // Given
+ VSMessageReceiveEvent messageEvent = mock(VSMessageReceiveEvent.class);
+ task = new VSTask(1000L, mockProcess, messageEvent, VSTask.LOCAL);
+ when(messageEvent.getProcess()).thenReturn(mockProcess);
+
+ // When
+ task.run();
+
+ // Then
+ verify(mockProcess, never()).increaseVectorAndLamportTimeIfAll();
+ verify(messageEvent).onStart();
+ }
+
+ @Test
+ @DisplayName("Test run method with Protocol does not increase time")
+ void testRunMethodWithProtocol() {
+ // Given
+ task = new VSTask(1000L, mockProcess, mockProtocol, VSTask.LOCAL);
+ when(mockProtocol.getProcess()).thenReturn(mockProcess);
+
+ // When
+ task.run();
+
+ // Then
+ verify(mockProcess, never()).increaseVectorAndLamportTimeIfAll();
+ verify(mockProtocol).onStart();
+ }
+
+ @Test
+ @DisplayName("Test setTaskTime method")
+ void testSetTaskTime() {
+ // Given
+ task = new VSTask(1000L, mockProcess, mockEvent, VSTask.LOCAL);
+
+ // When
+ task.setTaskTime(2000L);
+
+ // Then
+ assertEquals(2000L, task.getTaskTime());
+ }
+
+ @Test
+ @DisplayName("Test setProcess method with different process")
+ void testSetProcessWithDifferentProcess() throws VSEventNotCopyableException {
+ // Given
+ task = new VSTask(1000L, mockProcess, mockEvent, VSTask.LOCAL);
+ VSInternalProcess newProcess = mock(VSInternalProcess.class);
+ VSAbstractEvent copiedEvent = mock(VSAbstractEvent.class);
+
+ when(mockProcess.equals(newProcess)).thenReturn(false);
+ when(mockEvent.getCopy(newProcess)).thenReturn(copiedEvent);
+
+ // When
+ task.setProcess(newProcess);
+
+ // Then
+ assertEquals(newProcess, task.getProcess());
+ assertEquals(copiedEvent, task.getEvent());
+ }
+
+ @Test
+ @DisplayName("Test setProcess method with same process")
+ void testSetProcessWithSameProcess() throws VSEventNotCopyableException {
+ // Given
+ task = new VSTask(1000L, mockProcess, mockEvent, VSTask.LOCAL);
+ when(mockProcess.equals(mockProcess)).thenReturn(true);
+
+ // When
+ task.setProcess(mockProcess);
+
+ // Then
+ verify(mockEvent, never()).getCopy(any());
+ }
+
+ @Test
+ @DisplayName("Test setProcess method with non-copyable protocol")
+ void testSetProcessWithNonCopyableProtocol() throws VSEventNotCopyableException {
+ // Given
+ task = new VSTask(1000L, mockProcess, mockProtocol, VSTask.LOCAL);
+ VSInternalProcess newProcess = mock(VSInternalProcess.class);
+ VSAbstractProtocol newProtocol = mock(VSAbstractProtocol.class);
+
+ when(mockProcess.equals(newProcess)).thenReturn(false);
+ when(mockProtocol.getCopy(newProcess)).thenThrow(new VSEventNotCopyableException("Not copyable"));
+ when(mockProtocol.getClassname()).thenReturn("test.Protocol");
+ when(mockProtocol.getShortname()).thenReturn("TEST");
+ when(newProcess.getProtocolObject("test.Protocol")).thenReturn(newProtocol);
+
+ // When
+ task.setProcess(newProcess);
+
+ // Then
+ assertEquals(newProcess, task.getProcess());
+ assertEquals(newProtocol, task.getEvent());
+ verify(newProtocol).setShortname("TEST");
+ }
+
+ @Test
+ @DisplayName("Test toString method")
+ void testToString() {
+ // Given
+ task = new VSTask(1000L, mockProcess, mockEvent, VSTask.LOCAL);
+ when(mockEvent.toString()).thenReturn("TestEvent");
+ when(mockProcess.getProcessID()).thenReturn(42);
+
+ // When
+ String result = task.toString();
+
+ // Then
+ assertTrue(result.contains("Task"));
+ assertTrue(result.contains("1000"));
+ assertTrue(result.contains("TestEvent"));
+ assertTrue(result.contains("PID: 42"));
+ }
+
+ @Test
+ @DisplayName("Test compareTo method with different task times")
+ void testCompareToWithDifferentTimes() {
+ // Given
+ VSTask task1 = new VSTask(1000L, mockProcess, mockEvent, VSTask.LOCAL);
+ VSTask task2 = new VSTask(2000L, mockProcess, mockEvent, VSTask.LOCAL);
+
+ // When/Then
+ assertTrue(task1.compareTo(task2) < 0);
+ assertTrue(task2.compareTo(task1) > 0);
+ assertEquals(0, task1.compareTo(task1));
+ }
+
+ @Test
+ @DisplayName("Test compareTo method prioritizes ProcessRecoverEvent")
+ void testCompareToProcessRecoverEventPriority() {
+ // Given
+ VSProcessRecoverEvent recoverEvent = mock(VSProcessRecoverEvent.class);
+ VSTask recoverTask = new VSTask(1000L, mockProcess, recoverEvent, VSTask.LOCAL);
+ VSTask normalTask = new VSTask(1000L, mockProcess, mockEvent, VSTask.LOCAL);
+
+ // When/Then
+ assertTrue(recoverTask.compareTo(normalTask) < 0);
+ assertTrue(normalTask.compareTo(recoverTask) > 0);
+ }
+
+ @Test
+ @DisplayName("Test compareTo method prioritizes ProcessCrashEvent second")
+ void testCompareToProcessCrashEventPriority() {
+ // Given
+ VSProcessCrashEvent crashEvent = mock(VSProcessCrashEvent.class);
+ VSTask crashTask = new VSTask(1000L, mockProcess, crashEvent, VSTask.LOCAL);
+ VSTask normalTask = new VSTask(1000L, mockProcess, mockEvent, VSTask.LOCAL);
+
+ // When/Then
+ assertTrue(crashTask.compareTo(normalTask) < 0);
+ assertTrue(normalTask.compareTo(crashTask) > 0);
+ }
+
+ @Test
+ @DisplayName("Test compareTo method prioritizes ProtocolEvent third")
+ void testCompareToProtocolEventPriority() {
+ // Given
+ VSProtocolEvent protocolEvent = mock(VSProtocolEvent.class);
+ VSTask protocolTask = new VSTask(1000L, mockProcess, protocolEvent, VSTask.LOCAL);
+ VSTask normalTask = new VSTask(1000L, mockProcess, mockEvent, VSTask.LOCAL);
+
+ // When/Then
+ assertTrue(protocolTask.compareTo(normalTask) < 0);
+ assertTrue(normalTask.compareTo(protocolTask) > 0);
+ }
+
+ @Test
+ @DisplayName("Test compareTo method with null shortnames")
+ void testCompareToWithNullShortnames() {
+ // Given
+ VSTask task1 = new VSTask(1000L, mockProcess, mockEvent, VSTask.LOCAL);
+ VSTask task2 = new VSTask(1000L, mockProcess, mockEvent, VSTask.LOCAL);
+
+ when(mockEvent.getShortname()).thenReturn(null);
+
+ // When/Then
+ assertEquals(0, task1.compareTo(task2));
+ }
+
+ @Test
+ @DisplayName("Test compareTo method with non-VSTask object")
+ void testCompareToWithNonTaskObject() {
+ // Given
+ task = new VSTask(1000L, mockProcess, mockEvent, VSTask.LOCAL);
+ Object notATask = new Object();
+
+ // When/Then
+ assertEquals(0, task.compareTo(notATask));
+ }
+
+ @Test
+ @DisplayName("Test serialization and deserialization")
+ void testSerializationDeserialization() throws Exception {
+ // Given
+ task = new VSTask(1500L, mockProcess, mockEvent, VSTask.GLOBAL);
+ task.isProgrammed(true);
+
+ when(mockEvent.getClassname()).thenReturn("test.Event");
+ when(mockEvent.getID()).thenReturn(123);
+ when(mockProcess.getProcessNum()).thenReturn(5);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ VSSerialize serialize = mock(VSSerialize.class);
+
+ // When - Serialize
+ task.serialize(serialize, oos);
+ oos.flush();
+
+ // Then - Verify serialization calls
+ verify(mockEvent).serialize(serialize, oos);
+
+ // When - Deserialize
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectInputStream ois = new ObjectInputStream(bais);
+
+ // Mock the deserialization environment
+ when(serialize.getObject(5, "process")).thenReturn(mockProcess);
+ when(serialize.objectExists(123, "event")).thenReturn(true);
+ when(serialize.getObject(123, "event")).thenReturn(mockEvent);
+
+ VSTask deserializedTask = new VSTask(serialize, ois);
+
+ // Then - Verify deserialization
+ assertNotNull(deserializedTask);
+ verify(mockEvent).deserialize(serialize, ois);
+ }
+} \ No newline at end of file