diff --git a/src/main/java/mvd/jester/App.java b/src/main/java/mvd/jester/App.java index 7c51665..5524c6e 100644 --- a/src/main/java/mvd/jester/App.java +++ b/src/main/java/mvd/jester/App.java @@ -12,7 +12,7 @@ import mvd.jester.priority.RateMonotonic; public class App { public static void main(String[] args) { SystemSetup.Builder builder = new SystemSetup.Builder().setNumberOfProcessors(8); - TestEnvironment te = new TestEnvironment(builder, 4000); + TestEnvironment te = new TestEnvironment(builder, 40000); te.registerSchedulingAlgorithm(new RateMonotonic()); te.registerSchedulingAlgorithm(new EarliestDeadlineFirst()); @@ -24,44 +24,5 @@ public class App { mvd.jester.simulator.SchmidMottok.class); te.runTests(); - - // boolean mbWorked = false; - // boolean smWorked = false; - - // SystemSetup thisOne = null; - // EventPrinter.enablePrinter(); - - // do { - // SystemSetup.Builder builder = new SystemSetup.Builder().setNumberOfProcessors(8); - // SystemSetup systemSetup = builder.build(); - - // SchmidMottok sm = new SchmidMottok(systemSetup); - // MaiaBertogna mb = new MaiaBertogna(systemSetup); - - - // smWorked = sm.runSimulation(); - // mbWorked = mb.runSimulation(); - - - // thisOne = systemSetup; - // } while (smWorked == mbWorked); - - - // try (PrintWriter out = new PrintWriter("./results/manCheck.txt")) { - // out.println(thisOne); - // } catch (Exception e) { - // System.out.println("Ähm something went horribly wrong!"); - // } - // SchmidMottok sm = new SchmidMottok(thisOne); - // MaiaBertogna mb = new MaiaBertogna(thisOne); - - // mb.runSimulation(); - // sm.runSimulation(); - - // SystemSetup systemSetup = SystemSetup.fromFile("results/manCheck.txt"); - // EventPrinter.enablePrinter(); - // SchmidMottok sm = new SchmidMottok(systemSetup); - // sm.runSimulation(); - } } diff --git a/src/main/java/mvd/jester/TestEnvironment.java b/src/main/java/mvd/jester/TestEnvironment.java index ceac175..3875f08 100644 --- a/src/main/java/mvd/jester/TestEnvironment.java +++ b/src/main/java/mvd/jester/TestEnvironment.java @@ -6,6 +6,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import com.google.common.collect.HashBasedTable; import com.google.common.collect.Table; import mvd.jester.model.SystemSetup; import mvd.jester.priority.PriorityManager; @@ -81,11 +82,11 @@ public class TestEnvironment { Set abstractTestInstances = new HashSet<>(); Set abstractSimulatorInstances = new HashSet<>(); - Map> testResults = new HashMap<>(); - Map> simulatorResults = new HashMap<>(); - // Map> testResults = new HashMap<>(); - // Map> simulatorResults = - // new HashMap<>(); + Map totalNumberOfTasks = new HashMap<>(); + + Map> testResults = new HashMap<>(); + Map> simulatorResults = + new HashMap<>(); for (Constructor c : abstractTests) { try { @@ -120,24 +121,34 @@ public class TestEnvironment { long roundedUtilization = (long) (utilization * 10); + totalNumberOfTasks.compute(roundedUtilization, (k, v) -> v == null ? 1 : v + 1); + for (PriorityManager priorityManager : schedulingAlgorithms) { for (AbstractTest test : abstractTestInstances) { + Table table = testResults + .computeIfAbsent(roundedUtilization, k -> HashBasedTable.create()); if (priorityManager.hasTest(test) && test.runSchedulabilityCheck(priorityManager)) { - testResults - .computeIfAbsent(roundedUtilization, - k -> new HashMap()) - .compute(test, (k, v) -> (v == null) ? 1 : v + 1); + Long val = table.get(priorityManager, test); + if (val == null) { + table.put(priorityManager, test, (long) 1); + } else { + table.put(priorityManager, test, val + 1); + } } } for (AbstractSimulator simulator : abstractSimulatorInstances) { + Table table = simulatorResults + .computeIfAbsent(roundedUtilization, k -> HashBasedTable.create()); if (priorityManager.hasSimulator(simulator) && simulator.runSimulation(priorityManager)) { - simulatorResults - .computeIfAbsent(roundedUtilization, - k -> new HashMap()) - .compute(simulator, (k, v) -> (v == null) ? 1 : v + 1); + Long val = table.get(priorityManager, simulator); + if (val == null) { + table.put(priorityManager, simulator, (long) 1); + } else { + table.put(priorityManager, simulator, val + 1); + } } } @@ -148,65 +159,83 @@ public class TestEnvironment { } } - logTestResults(abstractTestInstances, testResults); - logSimulationResults(abstractSimulatorInstances, simulatorResults); + logTestResults(testResults, totalNumberOfTasks); + logSimulationResults(simulatorResults, totalNumberOfTasks); } - private void logTestResults(Set testCases, - Map> results) { + private void logTestResults(Map> results, + Map totalNumberOfTasks) { LocalTime date = LocalTime.now(); Logger log = new Logger("./results/results_" + systemSetup.getNumberOfProcessors() + "_" + date.getHour() + ":" + date.getMinute() + ".txt"); String firstLine = new String("Utilization"); - for (AbstractTest t : testCases) { - firstLine = firstLine + "\t" + t.getName(); - } + if (!results.isEmpty()) { + Long first = results.keySet().iterator().next(); + + for (PriorityManager p : results.get(first).rowKeySet()) { + for (AbstractTest t : results.get(first).columnKeySet()) { + firstLine = firstLine + "\t" + t.getName() + "_" + p.getName(); + } + } - log.log(firstLine); + log.log(firstLine); - for (Long util : results.keySet()) { - String line = String.valueOf((double) util / 10); - Map tests = results.get(util); + for (Long util : results.keySet()) { + String line = String.valueOf((double) util / 10); + Table tests = results.get(util); - for (AbstractTest t : testCases) { - if (tests.containsKey(t)) { - line += "\t" + tests.get(t); - } else { - line += "\t" + "0"; + for (PriorityManager p : tests.rowKeySet()) { + for (AbstractTest t : tests.columnKeySet()) { + if (tests.contains(p, t)) { + line += "\t" + tests.get(p, t); + } else { + line += "\t" + "0"; + } + } } + log.log(line); } - log.log(line); } log.finalize(); } - private void logSimulationResults(Set testCases, - Map> results) { + private void logSimulationResults( + Map> results, + Map totalNumberOfTasks) { LocalTime date = LocalTime.now(); Logger log = new Logger("./results/results_sim_" + systemSetup.getNumberOfProcessors() + "_" + date.getHour() + ":" + date.getMinute() + ".txt"); - String firstLine = new String("Utilization"); + String firstLine = new String("Utilization\tTotal"); - for (AbstractSimulator t : testCases) { - firstLine = firstLine + "\t" + t.getName(); - } + if (!results.isEmpty()) { + Long first = results.keySet().iterator().next(); - log.log(firstLine); + for (PriorityManager p : results.get(first).rowKeySet()) { + for (AbstractSimulator s : results.get(first).columnKeySet()) { + firstLine = firstLine + "\t" + s.getName() + "_" + p.getName(); + } + } - for (Long util : results.keySet()) { - String line = String.valueOf((double) util / 10); - Map tests = results.get(util); + log.log(firstLine); - for (AbstractSimulator t : testCases) { - if (tests.containsKey(t)) { - line += "\t" + tests.get(t); - } else { - line += "\t" + "0"; + for (Long util : totalNumberOfTasks.keySet()) { + String line = String.valueOf((double) util / 10); + line += "\t" + totalNumberOfTasks.get(util); + Table tests = results.get(util); + + for (PriorityManager p : tests.rowKeySet()) { + for (AbstractSimulator s : tests.columnKeySet()) { + if (tests.contains(p, s)) { + line += "\t" + tests.get(p, s); + } else { + line += "\t" + "0"; + } + } } + log.log(line); } - log.log(line); } log.finalize(); diff --git a/src/main/java/mvd/jester/priority/EarliestDeadlineFirst.java b/src/main/java/mvd/jester/priority/EarliestDeadlineFirst.java index 96d4f5f..4cb4116 100644 --- a/src/main/java/mvd/jester/priority/EarliestDeadlineFirst.java +++ b/src/main/java/mvd/jester/priority/EarliestDeadlineFirst.java @@ -6,6 +6,7 @@ import java.util.Set; import mvd.jester.model.Task; import mvd.jester.simulator.AbstractSimulator; import mvd.jester.simulator.MaiaBertogna; +import mvd.jester.simulator.SchmidMottok; import mvd.jester.simulator.internals.TaskContextInterface; import mvd.jester.tests.AbstractTest; @@ -16,7 +17,7 @@ public class EarliestDeadlineFirst implements PriorityManager { final static Set> abstractTests = new HashSet<>(); final static Set> abstractSimulators = - new HashSet<>(Arrays.asList(MaiaBertogna.class)); + new HashSet<>(Arrays.asList(MaiaBertogna.class, SchmidMottok.class)); /** * Compare the priority of two tasks according to the Rate Monotonic policy diff --git a/src/main/java/mvd/jester/simulator/AbstractSimulator.java b/src/main/java/mvd/jester/simulator/AbstractSimulator.java index 0a8266d..76847ff 100644 --- a/src/main/java/mvd/jester/simulator/AbstractSimulator.java +++ b/src/main/java/mvd/jester/simulator/AbstractSimulator.java @@ -91,7 +91,7 @@ public abstract class AbstractSimulator implements SimulatorInterface { private long getHyperPeriod() { return systemSetup.getTasks().stream().max(Comparator.comparing(Task::getPeriod)).get() - .getPeriod() * 2; /* * 10 */ + .getPeriod() * 10; } private class ProcessorComparator implements Comparator { diff --git a/src/main/java/mvd/jester/simulator/internals/maiabertogna/SegmentContext.java b/src/main/java/mvd/jester/simulator/internals/maiabertogna/SegmentContext.java index 5109612..d35deda 100644 --- a/src/main/java/mvd/jester/simulator/internals/maiabertogna/SegmentContext.java +++ b/src/main/java/mvd/jester/simulator/internals/maiabertogna/SegmentContext.java @@ -30,7 +30,7 @@ public class SegmentContext { return segment; } - Optional getNextJob() { + public Optional getNextJob() { return jobs.stream() .filter(j -> !j.getCurrentProcessor().isPresent() && j.checkExecutionTime()) .findFirst(); diff --git a/src/main/java/mvd/jester/simulator/internals/maiabertogna/TaskContext.java b/src/main/java/mvd/jester/simulator/internals/maiabertogna/TaskContext.java index b063aab..81b5766 100644 --- a/src/main/java/mvd/jester/simulator/internals/maiabertogna/TaskContext.java +++ b/src/main/java/mvd/jester/simulator/internals/maiabertogna/TaskContext.java @@ -64,10 +64,7 @@ public class TaskContext implements TaskContextInterface { public Optional getNextJob() { if (currentSegment < segments.size()) { - Optional optionalJob = segments.get(currentSegment).getNextJob(); - if (optionalJob.isPresent()) { - return optionalJob; - } + return segments.get(currentSegment).getNextJob(); } return Optional.empty(); diff --git a/src/main/java/mvd/jester/simulator/internals/schmidmottok/SegmentContext.java b/src/main/java/mvd/jester/simulator/internals/schmidmottok/SegmentContext.java index d48ba65..884de1e 100644 --- a/src/main/java/mvd/jester/simulator/internals/schmidmottok/SegmentContext.java +++ b/src/main/java/mvd/jester/simulator/internals/schmidmottok/SegmentContext.java @@ -43,7 +43,7 @@ public class SegmentContext { return jobs.size(); } - Optional getNextJob() { + public Optional getNextJob() { boolean taskletAvailable = tasklets.stream() .anyMatch(t -> !t.getCurrentJob().isPresent() && t.checkExecutionTime()); @@ -63,7 +63,7 @@ public class SegmentContext { } } - Optional getNextTasklet() { + public Optional getNextTasklet() { return tasklets.stream() .filter(t -> !t.getCurrentJob().isPresent() && t.checkExecutionTime()).findFirst(); } diff --git a/src/main/java/mvd/jester/simulator/internals/schmidmottok/TaskContext.java b/src/main/java/mvd/jester/simulator/internals/schmidmottok/TaskContext.java index f8fbda8..035aeb0 100644 --- a/src/main/java/mvd/jester/simulator/internals/schmidmottok/TaskContext.java +++ b/src/main/java/mvd/jester/simulator/internals/schmidmottok/TaskContext.java @@ -64,10 +64,7 @@ public class TaskContext implements TaskContextInterface { public Optional getNextJob() { if (currentSegment < segments.size()) { - Optional optionalJob = segments.get(currentSegment).getNextJob(); - if (optionalJob.isPresent()) { - return optionalJob; - } + return segments.get(currentSegment).getNextJob(); } return Optional.empty(); diff --git a/src/test/java/mvd/jester/model/TestSegment.java b/src/test/java/mvd/jester/model/TestSegment.java new file mode 100644 index 0000000..d455a38 --- /dev/null +++ b/src/test/java/mvd/jester/model/TestSegment.java @@ -0,0 +1,30 @@ +package mvd.jester.model; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import com.google.common.math.LongMath; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +/** + * SegmentTest + */ +public class TestSegment { + + @Test + @DisplayName("Test if dynamic segments are constructed correctly.") + public void testSegmentConstruction() { + Segment s1 = new Segment(100, 10); + Segment s2 = new Segment(9, 10); + + assertTrue(s1.getJobWcet() == 100); + assertTrue(s1.getNumberOfJobs() == 10); + assertTrue(s1.getNumberOfTasklets() == 100); + assertTrue(s1.getTaskletWcet() == 10); + + assertTrue(s2.getJobWcet() == 9); + assertTrue(s2.getNumberOfJobs() == 10); + assertTrue(s2.getNumberOfTasklets() == 9 * 10 / LongMath.gcd(9, 10)); + assertTrue(s2.getTaskletWcet() == LongMath.gcd(9, 10)); + + } +} diff --git a/src/test/java/mvd/jester/model/TaskSetTest.java b/src/test/java/mvd/jester/model/TestSystemSetup.java similarity index 85% rename from src/test/java/mvd/jester/model/TaskSetTest.java rename to src/test/java/mvd/jester/model/TestSystemSetup.java index 7245c94..f525d78 100644 --- a/src/test/java/mvd/jester/model/TaskSetTest.java +++ b/src/test/java/mvd/jester/model/TestSystemSetup.java @@ -5,7 +5,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -public class TaskSetTest { +public class TestSystemSetup { private static final int NUMBER_OF_SETS = 1000; @@ -14,7 +14,8 @@ public class TaskSetTest { public void testRandomTaskSetGeneration() { for (int i = 0; i < NUMBER_OF_SETS; ++i) { - SystemSetup taskSet = new SystemSetup.Builder().build(); + SystemSetup taskSet = new SystemSetup.Builder().setNumberOfSegments(1, 7) + .setNumberOfJobs(2, 10).setPeriods(100, 1000).build(); for (Task t : taskSet.getTasks()) { assertTrue(t.getPeriod() >= 100); @@ -29,11 +30,11 @@ public class TaskSetTest { assertTrue(s.getJobWcet() >= 1); assertTrue(s.getJobWcet() <= maxJobWcet); assertTrue(s.getNumberOfJobs() >= 1); - assertTrue(s.getNumberOfJobs() <= 6); + assertTrue(s.getNumberOfJobs() <= 10); } assertTrue(t.getSegments().size() >= 1); - assertTrue(t.getSegments().size() <= 5); + assertTrue(t.getSegments().size() <= 7); } } diff --git a/src/test/java/mvd/jester/priority/TestEarliestDeadlineFirst.java b/src/test/java/mvd/jester/priority/TestEarliestDeadlineFirst.java new file mode 100644 index 0000000..7dd23d7 --- /dev/null +++ b/src/test/java/mvd/jester/priority/TestEarliestDeadlineFirst.java @@ -0,0 +1,29 @@ +package mvd.jester.priority; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.HashSet; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import mvd.jester.model.Task; +import mvd.jester.simulator.internals.maiabertogna.TaskContext; + +/** + * TestEarliestDeadlineFirst + */ +public class TestEarliestDeadlineFirst { + + @Test + @DisplayName("Test if priority manager returns the correct priority.") + public void testPriority() { + EarliestDeadlineFirst edf = new EarliestDeadlineFirst(); + Task t1 = new Task(100, new HashSet<>()); + Task t2 = new Task(200, new HashSet<>()); + + TaskContext tc1 = new TaskContext(t1, 0); + TaskContext tc2 = new TaskContext(t2, 0); + + assertThrows(RuntimeException.class, () -> edf.compare(t1, t2)); + assertTrue(edf.compare(tc1, tc2) < 0); + } +} diff --git a/src/test/java/mvd/jester/priority/TestRateMonotonic.java b/src/test/java/mvd/jester/priority/TestRateMonotonic.java new file mode 100644 index 0000000..685039f --- /dev/null +++ b/src/test/java/mvd/jester/priority/TestRateMonotonic.java @@ -0,0 +1,29 @@ +package mvd.jester.priority; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.HashSet; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import mvd.jester.model.Segment; +import mvd.jester.model.Task; +import mvd.jester.simulator.internals.maiabertogna.TaskContext; + +/** + * TestRateMonotonic + */ +public class TestRateMonotonic { + + @Test + @DisplayName("Test if priority manager returns the correct priority.") + public void testPriority() { + RateMonotonic rm = new RateMonotonic(); + Task t1 = new Task(100, new HashSet()); + Task t2 = new Task(200, new HashSet()); + + TaskContext tc1 = new TaskContext(t1, 0); + TaskContext tc2 = new TaskContext(t2, 0); + + assertTrue(rm.compare(t1, t2) < 0); + assertTrue(rm.compare(tc1, tc2) < 0); + } +} diff --git a/src/test/java/mvd/jester/simulator/maiabertogna/TestJobContext.java b/src/test/java/mvd/jester/simulator/maiabertogna/TestJobContext.java new file mode 100644 index 0000000..446864f --- /dev/null +++ b/src/test/java/mvd/jester/simulator/maiabertogna/TestJobContext.java @@ -0,0 +1,56 @@ +package mvd.jester.simulator.maiabertogna; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import java.util.Optional; +import java.util.concurrent.ThreadLocalRandom; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import mvd.jester.model.Segment; +import mvd.jester.simulator.internals.ProcessorContext; +import mvd.jester.simulator.internals.TaskContextInterface; +import mvd.jester.simulator.internals.maiabertogna.JobContext; +import mvd.jester.simulator.internals.maiabertogna.SegmentContext; +import mvd.jester.simulator.internals.maiabertogna.TaskContext; + +/** + * TestJobContext + */ +public class TestJobContext { + + @Test + @DisplayName("Check if execution of Job is updated correctly.") + public void testUpdateExecution() { + for (int run = 0; run < 100; ++run) { + long numberOfJobs = ThreadLocalRandom.current().nextLong(1, 10); + long jobWcet = ThreadLocalRandom.current().nextLong(20, 50); + Segment s = new Segment(jobWcet, numberOfJobs); + SegmentContext sc = mock(SegmentContext.class); + when(sc.getSegment()).thenReturn(s); + + TaskContext tc = mock(TaskContext.class); + when(tc.acceptNotification(anyLong())).thenReturn(Optional.of(tc)); + + JobContext job = new JobContext(tc, sc); + ProcessorContext p = new ProcessorContext(0); + job.setCurrentProcessor(p); + p.setJob(job); + + assertTrue(job.checkExecutionTime()); + + for (int i = 0; i < jobWcet - 1; ++i) { + assertFalse(job.updateExecution(i).isPresent()); + } + + Optional otc = job.updateExecution(0); + assertTrue(otc.isPresent()); + assertTrue(tc.equals(otc.get())); + assertFalse(p.getJob().isPresent()); + assertFalse(job.getCurrentProcessor().isPresent()); + assertFalse(job.checkExecutionTime()); + } + } +} diff --git a/src/test/java/mvd/jester/simulator/maiabertogna/TestSegmentContext.java b/src/test/java/mvd/jester/simulator/maiabertogna/TestSegmentContext.java new file mode 100644 index 0000000..f93e707 --- /dev/null +++ b/src/test/java/mvd/jester/simulator/maiabertogna/TestSegmentContext.java @@ -0,0 +1,57 @@ +package mvd.jester.simulator.maiabertogna; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import java.util.Optional; +import java.util.concurrent.ThreadLocalRandom; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import mvd.jester.model.Segment; +import mvd.jester.simulator.internals.JobContextInterface; +import mvd.jester.simulator.internals.maiabertogna.SegmentContext; +import mvd.jester.simulator.internals.maiabertogna.TaskContext; +import mvd.jester.simulator.internals.ProcessorContext; + +/** + * TestSegmentContext + */ +public class TestSegmentContext { + + @Test + @DisplayName("Check if segment returns the jobs correctly.") + void testGetNextJob() { + for (int run = 0; run < 100; ++run) { + long numberOfJobs = ThreadLocalRandom.current().nextLong(1, 10); + long jobWcet = ThreadLocalRandom.current().nextLong(20, 50); + Segment s = new Segment(jobWcet, numberOfJobs); + TaskContext tc = mock(TaskContext.class); + when(tc.acceptNotification(jobWcet - 1)).thenReturn(Optional.empty()); + + SegmentContext sc = new SegmentContext(tc, s); + + Optional job = Optional.empty(); + for (int i = 0; i < numberOfJobs; ++i) { + job = sc.getNextJob(); + assertTrue(job.isPresent()); + job.get().setCurrentProcessor(new ProcessorContext(i)); + } + + assertFalse(sc.getNextJob().isPresent()); + + sc = new SegmentContext(tc, s); + + for (int i = 0; i < numberOfJobs; ++i) { + job = sc.getNextJob(); + assertTrue(job.isPresent()); + job.get().setCurrentProcessor(new ProcessorContext(i)); + for (int j = 0; j < jobWcet; ++j) { + job.get().updateExecution(i); + } + } + + assertFalse(sc.getNextJob().isPresent()); + } + } +} diff --git a/src/test/java/mvd/jester/simulator/maiabertogna/TestTaskContext.java b/src/test/java/mvd/jester/simulator/maiabertogna/TestTaskContext.java new file mode 100644 index 0000000..1d04a6f --- /dev/null +++ b/src/test/java/mvd/jester/simulator/maiabertogna/TestTaskContext.java @@ -0,0 +1,96 @@ +package mvd.jester.simulator.maiabertogna; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ThreadLocalRandom; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import mvd.jester.model.Segment; +import mvd.jester.model.Task; +import mvd.jester.simulator.internals.JobContextInterface; +import mvd.jester.simulator.internals.ProcessorContext; +import mvd.jester.simulator.internals.TaskContextInterface; +import mvd.jester.simulator.internals.maiabertogna.TaskContext; + +/** + * TestTaskContext + */ +public class TestTaskContext { + + @Test + @DisplayName("Check if TaskContext accepts its notification correctly.") + public void testAcceptNotification() { + for (int run = 0; run < 100; ++run) { + long numberOfJobs = ThreadLocalRandom.current().nextLong(1, 10); + long numberOfSegments = ThreadLocalRandom.current().nextLong(3, 10); + ArrayList segments = new ArrayList<>(); + + for (int i = 0; i < numberOfSegments; ++i) { + long numJobs = i % 2 == 0 ? 1 : numberOfJobs; + segments.add(new Segment(10, numJobs)); + } + + Task t = new Task(100, new LinkedHashSet<>(segments)); + TaskContext tc = new TaskContext(t, 0); + + for (int i = 0; i < segments.size() - 1; ++i) { + Segment s = segments.get(i); + for (int j = 0; j < s.getNumberOfJobs(); ++j) { + assertFalse(tc.acceptNotification(0).isPresent()); + } + } + + for (int i = 0; i < segments.get(segments.size() - 1).getNumberOfJobs() - 1; ++i) { + assertFalse(tc.acceptNotification(0).isPresent()); + } + + Optional tci = tc.acceptNotification(0); + + assertTrue(tci.isPresent()); + assertTrue(tci.get().equals(tc)); + } + } + + @Test + @DisplayName("Check if the next job is returned correctly.") + public void testGetNextJob() { + for (int run = 0; run < 100; ++run) { + // long numberOfJobs = ThreadLocalRandom.current().nextLong(1, 10); + // long numberOfSegments = ThreadLocalRandom.current().nextLong(3, 10); + + Set segments = new LinkedHashSet<>(); + segments.add(new Segment(5, 1)); + segments.add(new Segment(10, 10)); + segments.add(new Segment(15, 1)); + Task t = new Task(100, segments); + + TaskContext tc = new TaskContext(t, 0); + + Optional job = tc.getNextJob(); + assertTrue(job.isPresent()); + job.get().setCurrentProcessor(new ProcessorContext(0)); + assertFalse(tc.getNextJob().isPresent()); + + tc.acceptNotification(0); + + for (int i = 0; i < 9; ++i) { + job = tc.getNextJob(); + assertTrue(job.isPresent()); + job.get().setCurrentProcessor(new ProcessorContext(i)); + tc.acceptNotification(0); + } + job = tc.getNextJob(); + assertTrue(job.isPresent()); + job.get().setCurrentProcessor(new ProcessorContext(20)); + assertFalse(tc.getNextJob().isPresent()); + + tc.acceptNotification(0); + + assertTrue(tc.getNextJob().isPresent()); + } + } +} diff --git a/src/test/java/mvd/jester/simulator/schmidmottok/TestJobContext.java b/src/test/java/mvd/jester/simulator/schmidmottok/TestJobContext.java new file mode 100644 index 0000000..1c832bb --- /dev/null +++ b/src/test/java/mvd/jester/simulator/schmidmottok/TestJobContext.java @@ -0,0 +1,18 @@ +package mvd.jester.simulator.schmidmottok; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +/** + * TestJobContext + */ +public class TestJobContext { + + @Test + @DisplayName("Check if the job is prepared correctly.") + public void testPrepareJob() { + assertTrue(true); + } + +} diff --git a/src/test/java/mvd/jester/simulator/schmidmottok/TestSegmentContext.java b/src/test/java/mvd/jester/simulator/schmidmottok/TestSegmentContext.java new file mode 100644 index 0000000..8e4a7a3 --- /dev/null +++ b/src/test/java/mvd/jester/simulator/schmidmottok/TestSegmentContext.java @@ -0,0 +1,106 @@ +package mvd.jester.simulator.schmidmottok; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import java.util.Optional; +import java.util.concurrent.ThreadLocalRandom; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import mvd.jester.model.Segment; +import mvd.jester.simulator.internals.JobContextInterface; +import mvd.jester.simulator.internals.ProcessorContext; +import mvd.jester.simulator.internals.schmidmottok.JobContext; +import mvd.jester.simulator.internals.schmidmottok.SegmentContext; +import mvd.jester.simulator.internals.schmidmottok.TaskContext; +import mvd.jester.simulator.internals.schmidmottok.TaskletContext; + +/** + * TestSegmentContext + */ +public class TestSegmentContext { + + @Test + @DisplayName("Check if segment returns the jobs correctly.") + void testGetNextJob() { + for (int run = 0; run < 100; ++run) { + long numberOfJobs = ThreadLocalRandom.current().nextLong(1, 10); + long jobWcet = ThreadLocalRandom.current().nextLong(20, 50); + + Segment s = mock(Segment.class); + when(s.getNumberOfJobs()).thenReturn(numberOfJobs); + when(s.getJobWcet()).thenReturn(jobWcet); + when(s.getNumberOfTasklets()).thenReturn(jobWcet); + when(s.getTaskletWcet()).thenReturn(numberOfJobs); + TaskContext tc = mock(TaskContext.class); + + SegmentContext sc = new SegmentContext(tc, s, 4); + Optional job = Optional.empty(); + + when(tc.acceptNotification(jobWcet - 1)).thenReturn(Optional.empty()); + + long numJobs = numberOfJobs > 4 ? 4 : numberOfJobs; + for (int i = 0; i < numJobs; ++i) { + job = sc.getNextJob(); + assertTrue(job.isPresent()); + job.get().setCurrentProcessor(new ProcessorContext(i)); + } + + assertFalse(sc.getNextJob().isPresent()); + + sc = new SegmentContext(tc, s, 4); + + job = sc.getNextJob(); + assertTrue(job.isPresent()); + job.get().setCurrentProcessor(new ProcessorContext(0)); + for (int i = 0; i < jobWcet * numberOfJobs; ++i) { + job.get().updateExecution(i); + } + + assertFalse(sc.getNextJob().isPresent()); + } + } + + @Test + @DisplayName("Check if SegmentContext returns the correct amount of tasklets.") + void testGetNextTasklet() { + for (int run = 0; run < 100; ++run) { + long numberOfJobs = ThreadLocalRandom.current().nextLong(1, 10); + long jobWcet = ThreadLocalRandom.current().nextLong(20, 50); + + Segment s = mock(Segment.class); + when(s.getNumberOfJobs()).thenReturn(numberOfJobs); + when(s.getJobWcet()).thenReturn(jobWcet); + when(s.getNumberOfTasklets()).thenReturn(jobWcet); + when(s.getTaskletWcet()).thenReturn(numberOfJobs); + TaskContext tc = mock(TaskContext.class); + when(tc.acceptNotification(jobWcet - 1)).thenReturn(Optional.empty()); + + SegmentContext sc = new SegmentContext(tc, s, 4); + + for (int i = 0; i < jobWcet; ++i) { + + Optional tci = sc.getNextTasklet(); + assertTrue(tci.isPresent()); + tci.get().setCurrentJob(new JobContext(tc, sc)); + } + + assertFalse(sc.getNextTasklet().isPresent()); + + sc = new SegmentContext(tc, s, 4); + + for (int i = 0; i < jobWcet; ++i) { + Optional tasklet = sc.getNextTasklet(); + assertTrue(tasklet.isPresent()); + tasklet.get().setCurrentJob(new JobContext(tc, sc)); + for (int j = 0; j < numberOfJobs; ++j) { + tasklet.get().updateExecution(j); + } + } + + assertFalse(sc.getNextTasklet().isPresent()); + } + } + +} diff --git a/src/test/java/mvd/jester/simulator/schmidmottok/TestTaskContext.java b/src/test/java/mvd/jester/simulator/schmidmottok/TestTaskContext.java new file mode 100644 index 0000000..88210a6 --- /dev/null +++ b/src/test/java/mvd/jester/simulator/schmidmottok/TestTaskContext.java @@ -0,0 +1,96 @@ +package mvd.jester.simulator.schmidmottok; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ThreadLocalRandom; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import mvd.jester.model.Segment; +import mvd.jester.model.Task; +import mvd.jester.simulator.internals.JobContextInterface; +import mvd.jester.simulator.internals.ProcessorContext; +import mvd.jester.simulator.internals.TaskContextInterface; +import mvd.jester.simulator.internals.schmidmottok.TaskContext; + +/** + * TestTaskContext + */ +public class TestTaskContext { + @Test + @DisplayName("Check if TaskContext accepts its notification correctly.") + public void testAcceptNotification() { + for (int run = 0; run < 100; ++run) { + long numberOfJobs = ThreadLocalRandom.current().nextLong(1, 10); + long numberOfSegments = ThreadLocalRandom.current().nextLong(3, 10); + ArrayList segments = new ArrayList<>(); + + for (int i = 0; i < numberOfSegments; ++i) { + long numJobs = i % 2 == 0 ? 1 : numberOfJobs; + segments.add(new Segment(10, numJobs)); + } + + Task t = new Task(100, new LinkedHashSet<>(segments)); + TaskContext tc = new TaskContext(t, 1, 0); + + for (int i = 0; i < segments.size() - 1; ++i) { + Segment s = segments.get(i); + for (int j = 0; j < s.getNumberOfTasklets(); ++j) { + assertFalse(tc.acceptNotification(0).isPresent()); + } + } + + for (int i = 0; i < segments.get(segments.size() - 1).getNumberOfTasklets() - 1; ++i) { + assertFalse(tc.acceptNotification(0).isPresent()); + } + + Optional tci = tc.acceptNotification(0); + + assertTrue(tci.isPresent()); + assertTrue(tci.get().equals(tc)); + } + } + + @Test + @DisplayName("Check if the next job is returned correctly.") + public void testGetNextJob() { + for (int run = 0; run < 100; ++run) { + // long numberOfJobs = ThreadLocalRandom.current().nextLong(1, 10); + // long numberOfSegments = ThreadLocalRandom.current().nextLong(3, 10); + + Set segments = new LinkedHashSet<>(); + segments.add(new Segment(5, 1)); + segments.add(new Segment(10, 10)); + segments.add(new Segment(15, 1)); + Task t = new Task(100, segments); + + TaskContext tc = new TaskContext(t, 1, 0); + + Optional job = tc.getNextJob(); + assertTrue(job.isPresent()); + job.get().setCurrentProcessor(new ProcessorContext(0)); + assertFalse(tc.getNextJob().isPresent()); + + tc.acceptNotification(0); + + for (int i = 0; i < 9; ++i) { + job = tc.getNextJob(); + assertTrue(job.isPresent()); + job.get().setCurrentProcessor(new ProcessorContext(i)); + tc.acceptNotification(0); + } + job = tc.getNextJob(); + assertTrue(job.isPresent()); + job.get().setCurrentProcessor(new ProcessorContext(20)); + assertFalse(tc.getNextJob().isPresent()); + + tc.acceptNotification(0); + + assertTrue(tc.getNextJob().isPresent()); + } + } + +}