From decd597dbf4491f3b387f5f041e0bc932c63cc4d Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Mon, 14 Oct 2024 19:05:28 +0530 Subject: [PATCH 1/9] feat: Add `SpeculativeExecutionScheduling` new algorithm with Junit tests --- .../SpeculativeExecutionScheduling.java | 57 +++++++++++++++++++ .../SpeculativeExecutionSchedulingTest.java | 45 +++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java create mode 100644 src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java diff --git a/src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java b/src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java new file mode 100644 index 000000000000..085b43ed90c4 --- /dev/null +++ b/src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java @@ -0,0 +1,57 @@ +package com.thealgorithms.scheduling; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * SpeculativeExecutionScheduling runs multiple copies of the same task in parallel, + * picking the first one that finishes successfully. It is used to mitigate the + * impact of stragglers (slow tasks). + * + * Use Case: Big data systems like Hadoop and Spark, where it helps improve job completion time. + * + * @author Hardvan + */ +public final class SpeculativeExecutionScheduling { + + static class Task { + String name; + boolean completed; + + Task(String name) { + this.name = name; + this.completed = false; + } + + void complete() { + this.completed = true; + } + } + + private final Map> taskGroups; + + public SpeculativeExecutionScheduling() { + taskGroups = new HashMap<>(); + } + + public void addTask(String groupName, String taskName) { + taskGroups.putIfAbsent(groupName, new ArrayList<>()); + taskGroups.get(groupName).add(new Task(taskName)); + } + + public String executeTasks(String groupName) { + List tasks = taskGroups.get(groupName); + if (tasks == null) { + return null; + } + for (Task task : tasks) { + if (!task.completed) { + task.complete(); + return task.name; + } + } + return null; + } +} diff --git a/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java b/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java new file mode 100644 index 000000000000..673ac4caa7a1 --- /dev/null +++ b/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java @@ -0,0 +1,45 @@ +package com.thealgorithms.scheduling; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class SpeculativeExecutionSchedulingTest { + + private SpeculativeExecutionScheduling scheduler; + + @BeforeEach + public void setup() { + scheduler = new SpeculativeExecutionScheduling(); + } + + @Test + public void testAddAndExecuteTask() { + scheduler.addTask("Group1", "Task1"); + assertEquals("Task1", scheduler.executeTasks("Group1")); + } + + @Test + public void testMultipleTasksInGroup() { + scheduler.addTask("Group1", "Task1"); + scheduler.addTask("Group1", "Task2"); + assertEquals("Task1", scheduler.executeTasks("Group1")); + assertEquals("Task2", scheduler.executeTasks("Group1")); + } + + @Test + public void testExecuteAllTasks() { + scheduler.addTask("Group1", "Task1"); + scheduler.addTask("Group1", "Task2"); + scheduler.executeTasks("Group1"); + scheduler.executeTasks("Group1"); + assertNull(scheduler.executeTasks("Group1")); + } + + @Test + public void testEmptyTaskGroup() { + assertNull(scheduler.executeTasks("Group2")); + } +} From aae156bda175721ed34afc3db12ebf1f56bcb647 Mon Sep 17 00:00:00 2001 From: Hardvan Date: Mon, 14 Oct 2024 13:35:46 +0000 Subject: [PATCH 2/9] Update directory --- DIRECTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 4c454088088b..471a3d64ef8c 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -521,6 +521,7 @@ * [PreemptivePriorityScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java) * [RRScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/RRScheduling.java) * [SJFScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java) + * [SpeculativeExecutionScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java) * [SRTFScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java) * searches * [BinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/BinarySearch.java) @@ -1072,6 +1073,7 @@ * [PreemptivePrioritySchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java) * [RRSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java) * [SJFSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java) + * [SpeculativeExecutionSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java) * [SRTFSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java) * searches * [BinarySearch2dArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/BinarySearch2dArrayTest.java) From 7ddbe07e40ca7fa95f6d35bd186e26ba1dfef013 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Mon, 14 Oct 2024 19:06:23 +0530 Subject: [PATCH 3/9] Fix --- .../scheduling/SpeculativeExecutionScheduling.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java b/src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java index 085b43ed90c4..77e231b0234a 100644 --- a/src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java +++ b/src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java @@ -36,11 +36,23 @@ public SpeculativeExecutionScheduling() { taskGroups = new HashMap<>(); } + /** + * Adds a task to the specified group. + * + * @param groupName the name of the group + * @param taskName the name of the task + */ public void addTask(String groupName, String taskName) { taskGroups.putIfAbsent(groupName, new ArrayList<>()); taskGroups.get(groupName).add(new Task(taskName)); } + /** + * Executes the tasks in the specified group. + * + * @param groupName the name of the group + * @return the name of the task that completed successfully + */ public String executeTasks(String groupName) { List tasks = taskGroups.get(groupName); if (tasks == null) { From 7777f535a3e599b0c0302318e1c9d09f3ffc08e1 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Mon, 14 Oct 2024 19:12:57 +0530 Subject: [PATCH 4/9] Fix --- .../scheduling/SpeculativeExecutionScheduling.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java b/src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java index 77e231b0234a..48fb786b1a6c 100644 --- a/src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java +++ b/src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java @@ -43,8 +43,8 @@ public SpeculativeExecutionScheduling() { * @param taskName the name of the task */ public void addTask(String groupName, String taskName) { - taskGroups.putIfAbsent(groupName, new ArrayList<>()); - taskGroups.get(groupName).add(new Task(taskName)); + List tasks = taskGroups.computeIfAbsent(groupName, k -> new ArrayList<>()); + tasks.add(new Task(taskName)); } /** From 0ac38e2d8d01f99ab4e1ae9c02cf931f42e2a4a9 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Tue, 29 Oct 2024 10:10:13 +0530 Subject: [PATCH 5/9] Fix --- .../SpeculativeExecutionScheduling.java | 17 ++++++++++-- .../SpeculativeExecutionSchedulingTest.java | 27 ++++++++++++++++--- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java b/src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java index 48fb786b1a6c..3959a847a494 100644 --- a/src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java +++ b/src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java @@ -19,15 +19,25 @@ public final class SpeculativeExecutionScheduling { static class Task { String name; boolean completed; + long startTime; Task(String name) { this.name = name; this.completed = false; + this.startTime = -1; + } + + void start() { + this.startTime = System.currentTimeMillis(); } void complete() { this.completed = true; } + + boolean hasStarted() { + return this.startTime != -1; + } } private final Map> taskGroups; @@ -48,7 +58,7 @@ public void addTask(String groupName, String taskName) { } /** - * Executes the tasks in the specified group. + * Executes the tasks in the specified group by assigning a start time. * * @param groupName the name of the group * @return the name of the task that completed successfully @@ -60,8 +70,11 @@ public String executeTasks(String groupName) { } for (Task task : tasks) { if (!task.completed) { + if (!task.hasStarted()) { + task.start(); + } task.complete(); - return task.name; + return task.name + " started at " + task.startTime; } } return null; diff --git a/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java b/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java index 673ac4caa7a1..d5a4e011e2d1 100644 --- a/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java +++ b/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -18,28 +19,48 @@ public void setup() { @Test public void testAddAndExecuteTask() { scheduler.addTask("Group1", "Task1"); - assertEquals("Task1", scheduler.executeTasks("Group1")); + + String result = scheduler.executeTasks("Group1"); + String[] parts = result.split(" started at "); + + // Validate task name and ensure start time is a valid timestamp + assertEquals("Task1", parts[0]); + assertTrue(Long.parseLong(parts[1]) > 0, "Start time should be greater than 0"); } @Test public void testMultipleTasksInGroup() { scheduler.addTask("Group1", "Task1"); scheduler.addTask("Group1", "Task2"); - assertEquals("Task1", scheduler.executeTasks("Group1")); - assertEquals("Task2", scheduler.executeTasks("Group1")); + + // Execute the first task + String result1 = scheduler.executeTasks("Group1"); + String[] parts1 = result1.split(" started at "); + assertEquals("Task1", parts1[0]); + assertTrue(Long.parseLong(parts1[1]) > 0, "Start time should be greater than 0"); + + // Execute the second task + String result2 = scheduler.executeTasks("Group1"); + String[] parts2 = result2.split(" started at "); + assertEquals("Task2", parts2[0]); + assertTrue(Long.parseLong(parts2[1]) > 0, "Start time should be greater than 0"); } @Test public void testExecuteAllTasks() { scheduler.addTask("Group1", "Task1"); scheduler.addTask("Group1", "Task2"); + scheduler.executeTasks("Group1"); scheduler.executeTasks("Group1"); + + // Confirm no tasks remain assertNull(scheduler.executeTasks("Group1")); } @Test public void testEmptyTaskGroup() { + // Confirm executing tasks on an empty group returns null assertNull(scheduler.executeTasks("Group2")); } } From 2ecbfba451ea540aabde085f3e3754803cfc343d Mon Sep 17 00:00:00 2001 From: Hardvan Date: Tue, 29 Oct 2024 04:41:19 +0000 Subject: [PATCH 6/9] Update directory --- DIRECTORY.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index b98faac2faf3..4afb2a60a623 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -562,6 +562,7 @@ * [RRScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/RRScheduling.java) * [SelfAdjustingScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SelfAdjustingScheduling.java) * [SJFScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java) + * [SlackTimeScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SlackTimeScheduling.java) * [SpeculativeExecutionScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java) * [SRTFScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java) * searches @@ -597,6 +598,7 @@ * [UnionFind](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/UnionFind.java) * [UpperBound](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/UpperBound.java) * slidingwindow + * [LongestSubarrayWithSumLessOrEqualToK](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/slidingwindow/LongestSubarrayWithSumLessOrEqualToK.java) * [LongestSubstringWithoutRepeatingCharacters](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharacters.java) * [MaxSumKSizeSubarray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarray.java) * [MinSumKSizeSubarray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/slidingwindow/MinSumKSizeSubarray.java) @@ -1192,6 +1194,7 @@ * [RRSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java) * [SelfAdjustingSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SelfAdjustingSchedulingTest.java) * [SJFSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java) + * [SlackTimeSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SlackTimeSchedulingTest.java) * [SpeculativeExecutionSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java) * [SRTFSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java) * searches @@ -1228,6 +1231,7 @@ * [UnionFindTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/UnionFindTest.java) * [UpperBoundTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/UpperBoundTest.java) * slidingwindow + * [LongestSubarrayWithSumLessOrEqualToKTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/slidingwindow/LongestSubarrayWithSumLessOrEqualToKTest.java) * [LongestSubstringWithoutRepeatingCharactersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharactersTest.java) * [MaxSumKSizeSubarrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarrayTest.java) * [MinSumKSizeSubarrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/slidingwindow/MinSumKSizeSubarrayTest.java) From 33c7c029ad07962431befa6d8e3c03e4711dd212 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Tue, 29 Oct 2024 10:12:39 +0530 Subject: [PATCH 7/9] Fix --- .../scheduling/SpeculativeExecutionSchedulingTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java b/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java index d5a4e011e2d1..7b3a42704e13 100644 --- a/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java +++ b/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java @@ -54,7 +54,6 @@ public void testExecuteAllTasks() { scheduler.executeTasks("Group1"); scheduler.executeTasks("Group1"); - // Confirm no tasks remain assertNull(scheduler.executeTasks("Group1")); } From 54266260140f7af675f90b1dbc21cf1f04ff5b37 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Tue, 29 Oct 2024 10:21:59 +0530 Subject: [PATCH 8/9] Fix --- .../SpeculativeExecutionSchedulingTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java b/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java index 7b3a42704e13..d9d575111b3e 100644 --- a/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java +++ b/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java @@ -21,6 +21,10 @@ public void testAddAndExecuteTask() { scheduler.addTask("Group1", "Task1"); String result = scheduler.executeTasks("Group1"); + + // Check for null before splitting + assertTrue(result != null, "The result should not be null after executing the task."); + String[] parts = result.split(" started at "); // Validate task name and ensure start time is a valid timestamp @@ -35,12 +39,20 @@ public void testMultipleTasksInGroup() { // Execute the first task String result1 = scheduler.executeTasks("Group1"); + + // Check for null before splitting + assertTrue(result1 != null, "The result for Task1 should not be null."); + String[] parts1 = result1.split(" started at "); assertEquals("Task1", parts1[0]); assertTrue(Long.parseLong(parts1[1]) > 0, "Start time should be greater than 0"); // Execute the second task String result2 = scheduler.executeTasks("Group1"); + + // Check for null before splitting + assertTrue(result2 != null, "The result for Task2 should not be null."); + String[] parts2 = result2.split(" started at "); assertEquals("Task2", parts2[0]); assertTrue(Long.parseLong(parts2[1]) > 0, "Start time should be greater than 0"); @@ -54,6 +66,7 @@ public void testExecuteAllTasks() { scheduler.executeTasks("Group1"); scheduler.executeTasks("Group1"); + // Confirm executing tasks again returns null assertNull(scheduler.executeTasks("Group1")); } From 91390191fb8af2f9f9b4c34b381ea6af29d1f6dd Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Tue, 29 Oct 2024 10:27:30 +0530 Subject: [PATCH 9/9] Fix --- .../SpeculativeExecutionSchedulingTest.java | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java b/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java index d9d575111b3e..5a6c95f37c28 100644 --- a/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java +++ b/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java @@ -23,13 +23,16 @@ public void testAddAndExecuteTask() { String result = scheduler.executeTasks("Group1"); // Check for null before splitting - assertTrue(result != null, "The result should not be null after executing the task."); - - String[] parts = result.split(" started at "); - - // Validate task name and ensure start time is a valid timestamp - assertEquals("Task1", parts[0]); - assertTrue(Long.parseLong(parts[1]) > 0, "Start time should be greater than 0"); + if (result != null) { + String[] parts = result.split(" started at "); + + // Validate task name and ensure start time is a valid timestamp + assertEquals("Task1", parts[0]); + assertTrue(Long.parseLong(parts[1]) > 0, "Start time should be greater than 0"); + } else { + // Handle the case where result is null + assertTrue(false, "The result should not be null after executing the task."); + } } @Test @@ -41,21 +44,27 @@ public void testMultipleTasksInGroup() { String result1 = scheduler.executeTasks("Group1"); // Check for null before splitting - assertTrue(result1 != null, "The result for Task1 should not be null."); - - String[] parts1 = result1.split(" started at "); - assertEquals("Task1", parts1[0]); - assertTrue(Long.parseLong(parts1[1]) > 0, "Start time should be greater than 0"); + if (result1 != null) { + String[] parts1 = result1.split(" started at "); + assertEquals("Task1", parts1[0]); + assertTrue(Long.parseLong(parts1[1]) > 0, "Start time should be greater than 0"); + } else { + // Handle the case where result1 is null + assertTrue(false, "The result for Task1 should not be null."); + } // Execute the second task String result2 = scheduler.executeTasks("Group1"); // Check for null before splitting - assertTrue(result2 != null, "The result for Task2 should not be null."); - - String[] parts2 = result2.split(" started at "); - assertEquals("Task2", parts2[0]); - assertTrue(Long.parseLong(parts2[1]) > 0, "Start time should be greater than 0"); + if (result2 != null) { + String[] parts2 = result2.split(" started at "); + assertEquals("Task2", parts2[0]); + assertTrue(Long.parseLong(parts2[1]) > 0, "Start time should be greater than 0"); + } else { + // Handle the case where result2 is null + assertTrue(false, "The result for Task2 should not be null."); + } } @Test