diff --git b/.classpath a/.classpath
new file mode 100644
index 0000000..f0257c5
--- /dev/null
+++ a/.classpath
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git b/.gitignore a/.gitignore
new file mode 100644
index 0000000..b57e62e
--- /dev/null
+++ a/.gitignore
@@ -0,0 +1,3 @@
+/.vscode
+/.settings
+/target
\ No newline at end of file
diff --git b/.project a/.project
new file mode 100644
index 0000000..e0c919e
--- /dev/null
+++ a/.project
@@ -0,0 +1,23 @@
+
+
+ jester
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git b/pom.xml a/pom.xml
new file mode 100644
index 0000000..f65c9bb
--- /dev/null
+++ a/pom.xml
@@ -0,0 +1,93 @@
+
+ 4.0.0
+ mvd.jester
+ jester
+ jar
+ 1.0-SNAPSHOT
+ jester
+ http://maven.apache.org
+
+
+ UTF-8
+ 1.8
+ 1.8
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.4.0
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ 5.4.0
+ test
+
+
+ org.mockito
+ mockito-junit-jupiter
+ 2.21.0
+ test
+
+
+ com.google.code.gson
+ gson
+ 2.2.4
+
+
+ com.google.guava
+ guava
+ 28.0-jre
+
+
+
+
+
+
+
+
+ maven-clean-plugin
+ 3.1.0
+
+
+
+ maven-resources-plugin
+ 3.0.2
+
+
+ maven-compiler-plugin
+ 3.8.0
+
+
+ maven-surefire-plugin
+ 2.22.1
+
+
+ maven-jar-plugin
+ 3.0.2
+
+
+ maven-install-plugin
+ 2.5.2
+
+
+ maven-deploy-plugin
+ 2.8.2
+
+
+
+ maven-site-plugin
+ 3.7.1
+
+
+ maven-project-info-reports-plugin
+ 3.0.0
+
+
+
+
+
diff --git b/src/main/java/mvd/jester/App.java a/src/main/java/mvd/jester/App.java
new file mode 100644
index 0000000..0c8d099
--- /dev/null
+++ a/src/main/java/mvd/jester/App.java
@@ -0,0 +1,24 @@
+package mvd.jester;
+
+import mvd.jester.model.Task;
+import mvd.jester.model.SystemSetup;
+import mvd.jester.tests.MaiaBertogna;
+import mvd.jester.tests.SchmidMottok;
+import mvd.jester.tests.TestEnvironment;
+
+/**
+ * Hello world!
+ *
+ */
+public class App {
+ public static void main(String[] args) {
+
+ TestEnvironment te = new TestEnvironment(4000, 4);
+
+ te.registerTestInterface(SchmidMottok.class);
+ te.registerTestInterface(MaiaBertogna.class);
+
+ te.runTests();
+
+ }
+}
diff --git b/src/main/java/mvd/jester/model/Segment.java a/src/main/java/mvd/jester/model/Segment.java
new file mode 100644
index 0000000..492cdf3
--- /dev/null
+++ a/src/main/java/mvd/jester/model/Segment.java
@@ -0,0 +1,51 @@
+package mvd.jester.model;
+
+import com.google.common.math.LongMath;
+
+public class Segment {
+
+ private final long jobWcet;
+ private final long numberOfJobs;
+ private final long taskletWcet;
+ private final long numberOfTasklets;
+
+ public Segment(long jobWcet, long numberOfJobs) {
+ this.jobWcet = jobWcet;
+ this.numberOfJobs = numberOfJobs;
+ if (numberOfJobs == 1) {
+ this.taskletWcet = this.jobWcet;
+ this.numberOfTasklets = this.numberOfJobs;
+ } else {
+ this.taskletWcet = LongMath.gcd(jobWcet, numberOfJobs);
+ this.numberOfTasklets = this.jobWcet * this.numberOfJobs / this.taskletWcet;
+ }
+ }
+
+ /**
+ * @return the numberOfJobs
+ */
+ public long getNumberOfJobs() {
+ return numberOfJobs;
+ }
+
+ /**
+ * @return the jobWcet
+ */
+ public long getJobWcet() {
+ return jobWcet;
+ }
+
+ /**
+ * @return the numberOfTasklets
+ */
+ public long getNumberOfTasklets() {
+ return numberOfTasklets;
+ }
+
+ /**
+ * @return the taskletWcet
+ */
+ public long getTaskletWcet() {
+ return taskletWcet;
+ }
+}
diff --git b/src/main/java/mvd/jester/model/SortedTaskSet.java a/src/main/java/mvd/jester/model/SortedTaskSet.java
new file mode 100644
index 0000000..0c08913
--- /dev/null
+++ a/src/main/java/mvd/jester/model/SortedTaskSet.java
@@ -0,0 +1,16 @@
+package mvd.jester.model;
+
+import java.util.TreeSet;
+import mvd.jester.priority.PriorityManager;
+
+/**
+ * SortedTaskSet
+ */
+public class SortedTaskSet extends TreeSet {
+
+ private static final long serialVersionUID = 4808544133562675597L;
+
+ public SortedTaskSet(PriorityManager priorityMananger) {
+ super((t1, t2) -> priorityMananger.compare(t1, t2));
+ }
+}
diff --git b/src/main/java/mvd/jester/model/SystemSetup.java a/src/main/java/mvd/jester/model/SystemSetup.java
new file mode 100644
index 0000000..55572e9
--- /dev/null
+++ a/src/main/java/mvd/jester/model/SystemSetup.java
@@ -0,0 +1,164 @@
+package mvd.jester.model;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.concurrent.ThreadLocalRandom;
+import mvd.jester.priority.PriorityManager;
+import mvd.jester.priority.RateMonotonic;
+
+/**
+ * TaskSet
+ */
+public class SystemSetup {
+ private SortedTaskSet tasks;
+ private final long numberOfProcessors;
+
+ public SystemSetup(SortedTaskSet tasks, long numberOfProcessors) {
+ this.tasks = tasks;
+ this.numberOfProcessors = numberOfProcessors;
+ }
+
+ /**
+ * @return the tasks
+ */
+ public SortedTaskSet getTasks() {
+ return tasks;
+ }
+
+ public void setSortedTaskSet(SortedTaskSet tasks) {
+ this.tasks = tasks;
+ }
+
+ /**
+ * @return the numberOfProcessors
+ */
+ public long getNumberOfProcessors() {
+ return numberOfProcessors;
+ }
+
+ public double getUtilization() {
+ double utilization = 0;
+ for (Task t : tasks) {
+ utilization += (double) t.getMaximumWcet() / t.getPeriod();
+ }
+
+ return utilization;
+ }
+
+ public static class Generator {
+ private long numberOfProcessors = 4;
+ private long minPeriod = 100;
+ private long maxPeriod = 1000;
+ private long minNumberOfSegments = 3;
+ private long maxNumberOfSegments = 7;
+ private long minNumberOfJobs = 2;
+ private long maxNumberOfJobs = 3 * numberOfProcessors / 2;
+ private long minWcet = 1;
+ private long ratio = randomTaskRatio();
+ private PriorityManager priorityManager = new RateMonotonic();
+
+ public Generator() {
+
+ }
+
+ private long randomTaskPeriod() {
+ return ThreadLocalRandom.current().nextLong(minPeriod, maxPeriod);
+ }
+
+ private long randomTaskRatio() {
+ return ThreadLocalRandom.current().nextLong(0, 100);
+ }
+
+ private long randomNumberOfSegments() {
+ return ThreadLocalRandom.current().nextLong(minNumberOfSegments, maxNumberOfSegments);
+ }
+
+ private long randomNumberOfJobs() {
+ return ThreadLocalRandom.current().nextLong(minNumberOfJobs, maxNumberOfJobs);
+ }
+
+ private long randomWcet(long period, long numberOfSegments) {
+ long maxWcet = period / numberOfSegments;
+
+ return ThreadLocalRandom.current().nextLong(minWcet, maxWcet);
+ }
+
+ private Task generateTask() {
+ boolean serial = randomTaskRatio() > this.ratio;
+ long period = randomTaskPeriod();
+ long numberOfSegments = 1;
+ Set segments = new LinkedHashSet();
+ if (!serial) {
+ numberOfSegments = randomNumberOfSegments();
+ } else {
+ numberOfSegments = 1;
+ }
+ for (int i = 0; i < numberOfSegments; ++i) {
+ serial = i % 2 == 0;
+ long wcet = randomWcet(period, numberOfSegments);
+ long numberOfJobs = serial ? 1 : randomNumberOfJobs();
+ segments.add(new Segment(wcet, numberOfJobs));
+ }
+ return new Task(period, segments);
+ }
+
+ private SortedTaskSet generateTaskSet() {
+ SortedTaskSet taskSet = new SortedTaskSet(priorityManager);
+
+ for (int i = 0; i < 4; ++i) {
+ Task task = generateTask();
+ taskSet.add(task);
+ }
+
+ return taskSet;
+ }
+
+ public SystemSetup build() {
+ this.ratio = randomTaskRatio();
+ SortedTaskSet taskSet = generateTaskSet();
+ return new SystemSetup(taskSet, numberOfProcessors);
+ }
+
+ public void addTask(SystemSetup taskSet) {
+ taskSet.tasks.add(generateTask());
+ }
+
+ /**
+ * @param numberOfProcessors the numberOfProcessors to set
+ */
+ public void setNumberOfProcessors(long numberOfProcessors) {
+ this.numberOfProcessors = numberOfProcessors;
+ }
+
+
+ public Generator setNumberOfSegments(long minNumberOfSegments, long maxNumberOfSegments) {
+ this.minNumberOfSegments = minNumberOfSegments;
+ this.maxNumberOfSegments = maxNumberOfSegments;
+
+ return this;
+ }
+
+ public Generator setPeriods(long minPeriod, long maxPeriod) {
+ this.minPeriod = minPeriod;
+ this.maxPeriod = maxPeriod;
+
+ return this;
+ }
+
+ public Generator setPriorityManager(PriorityManager priorityManager) {
+ this.priorityManager = priorityManager;
+ return this;
+ }
+
+ /**
+ * @param maxNumberOfJobs the maxNumberOfJobs to set
+ */
+ public Generator setNumberOfJobs(long minNumberOfJobs, long maxNumberOfJobs) {
+ this.minNumberOfJobs = minNumberOfJobs;
+ this.maxNumberOfJobs = maxNumberOfJobs;
+ return this;
+ }
+
+ }
+
+}
diff --git b/src/main/java/mvd/jester/model/Task.java a/src/main/java/mvd/jester/model/Task.java
new file mode 100644
index 0000000..7a1fac7
--- /dev/null
+++ a/src/main/java/mvd/jester/model/Task.java
@@ -0,0 +1,73 @@
+package mvd.jester.model;
+
+import java.util.Set;
+
+/**
+ * Task
+ */
+public class Task {
+
+ private final long deadline;
+ private final long period;
+ private final Set segments;
+ private final long maximumWcet;
+ private final long maximumParallelism;
+
+ public Task(long period, long deadline, Set segments) {
+ this.deadline = deadline;
+ this.period = period;
+ this.segments = segments;
+
+ long maxWcet = 0;
+ long maxParallelism = 0;
+ for (Segment s : segments) {
+ maxWcet += s.getJobWcet() * s.getNumberOfJobs();
+ if (maxParallelism < s.getNumberOfJobs()) {
+ maxParallelism = s.getNumberOfJobs();
+ }
+ }
+
+ this.maximumParallelism = maxParallelism;
+ this.maximumWcet = maxWcet;
+ }
+
+ public Task(long period, Set segments) {
+ this(period, period, segments);
+ }
+
+
+ /**
+ * @return the deadline
+ */
+ public long getDeadline() {
+ return deadline;
+ }
+
+ /**
+ * @return the period
+ */
+ public long getPeriod() {
+ return period;
+ }
+
+ /**
+ * @return the segments
+ */
+ public Set getSegments() {
+ return segments;
+ }
+
+ /**
+ * @return the maximumWcet
+ */
+ public long getMaximumWcet() {
+ return maximumWcet;
+ }
+
+ /**
+ * @return the maximumParallelism
+ */
+ public long getMaximumParallelism() {
+ return maximumParallelism;
+ }
+}
diff --git b/src/main/java/mvd/jester/priority/PriorityManager.java a/src/main/java/mvd/jester/priority/PriorityManager.java
new file mode 100644
index 0000000..273b0ac
--- /dev/null
+++ a/src/main/java/mvd/jester/priority/PriorityManager.java
@@ -0,0 +1,12 @@
+package mvd.jester.priority;
+
+import java.util.Comparator;
+import mvd.jester.model.Task;
+
+/**
+ * PriorityManager
+ */
+public interface PriorityManager extends Comparator {
+
+}
+
diff --git b/src/main/java/mvd/jester/priority/RateMonotonic.java a/src/main/java/mvd/jester/priority/RateMonotonic.java
new file mode 100644
index 0000000..d650e1b
--- /dev/null
+++ a/src/main/java/mvd/jester/priority/RateMonotonic.java
@@ -0,0 +1,19 @@
+package mvd.jester.priority;
+
+import mvd.jester.model.Task;
+
+public class RateMonotonic implements PriorityManager {
+
+ /**
+ * Compare the priority of two tasks according to the Rate Monotonic policy
+ *
+ * @param t1 The first task
+ * @param t2 The second task
+ * @return 0 if both tasks have the same priority, positive number if the first task has a
+ * higher priority, negative number if the second task has a higher priority
+ */
+ @Override
+ public int compare(Task t1, Task t2) {
+ return Long.compare(t1.getPeriod(), t2.getPeriod());
+ }
+}
diff --git b/src/main/java/mvd/jester/tests/AbstractTest.java a/src/main/java/mvd/jester/tests/AbstractTest.java
new file mode 100644
index 0000000..1614be2
--- /dev/null
+++ a/src/main/java/mvd/jester/tests/AbstractTest.java
@@ -0,0 +1,17 @@
+package mvd.jester.tests;
+
+import java.util.HashMap;
+import java.util.Map;
+import mvd.jester.model.Task;
+
+/**
+ * AbstractTest
+ */
+public abstract class AbstractTest implements TestInterface {
+
+ protected Map responseTimes;
+
+ public AbstractTest() {
+ this.responseTimes = new HashMap();
+ }
+}
diff --git b/src/main/java/mvd/jester/tests/MaiaBertogna.java a/src/main/java/mvd/jester/tests/MaiaBertogna.java
new file mode 100644
index 0000000..a738e96
--- /dev/null
+++ a/src/main/java/mvd/jester/tests/MaiaBertogna.java
@@ -0,0 +1,121 @@
+package mvd.jester.tests;
+
+import java.math.RoundingMode;
+import java.util.Map.Entry;
+import com.google.common.math.LongMath;
+import mvd.jester.model.Segment;
+import mvd.jester.model.Task;
+import mvd.jester.model.SystemSetup;
+
+/**
+ * MaiaBertogna
+ */
+public class MaiaBertogna extends AbstractTest {
+
+ private SystemSetup systemSetup;
+
+ public MaiaBertogna() {
+ }
+
+ @Override
+ public boolean runSchedulabilityCheck(SystemSetup systemSetup) {
+ responseTimes.clear();
+ this.systemSetup = systemSetup;
+ for (Task t : systemSetup.getTasks()) {
+ responseTimes.put(t, calculateResponseTime(t));
+ }
+
+ for (Entry keyValuePair : responseTimes.entrySet()) {
+ if (keyValuePair.getKey().getDeadline() < keyValuePair.getValue().longValue()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return "MaiaBertogna";
+ }
+
+ private long calculateResponseTime(Task task) {
+ long minimumWcet = getMinimumWcet(task);
+ long responseTime = minimumWcet;
+ long previousResponseTime = 0;
+
+ do {
+ previousResponseTime = responseTime;
+ long interference = 0;
+
+ for (Task t : systemSetup.getTasks()) {
+ if (t.getPeriod() < task.getPeriod()) {
+ long maxNumberOfJobsOfT = t.getMaximumParallelism();
+ for (int p = 0; p < maxNumberOfJobsOfT; ++p) {
+ interference += Math.min(getTaskInterference(t, responseTime, p + 1),
+ responseTime - minimumWcet + 1);
+ }
+ }
+ }
+
+ double taskInterference = (double) interference / systemSetup.getNumberOfProcessors();
+ long selfInterference = 0;
+
+ long maxNumberOfJobs = task.getMaximumParallelism();
+ for (int p = 0; p < maxNumberOfJobs; ++p) {
+ selfInterference +=
+ Math.min(getSelfInterference(task, p + 1), responseTime - minimumWcet + 1);
+ }
+
+ long totalInterference = (long) Math.floor(taskInterference + selfInterference);
+
+ responseTime = minimumWcet + totalInterference;
+ } while (previousResponseTime != responseTime);
+
+
+ return responseTime;
+ }
+
+ private long getSelfInterference(Task task, long parallelism) {
+ long interference = 0;
+
+ for (Segment s : task.getSegments()) {
+ if (s.getNumberOfJobs() >= parallelism + 1) {
+ s.getJobWcet();
+ }
+ }
+
+ return interference;
+ }
+
+ private long getTaskInterference(Task task, long interval, long parallelism) {
+ long responseTime = responseTimes.get(task);
+ long minWcet = getMinimumWcet(task);
+ long period = task.getPeriod();
+ long numberOfJobs =
+ (LongMath.divide(interval + responseTime - minWcet, period, RoundingMode.FLOOR)
+ + 1);
+
+ long workload = 0;
+
+ for (Segment s : task.getSegments()) {
+ if (s.getNumberOfJobs() >= parallelism) {
+ workload += s.getJobWcet();
+ }
+ }
+
+ long interference = numberOfJobs * workload;
+
+ return interference;
+ }
+
+ private long getMinimumWcet(Task task) {
+ long minWcet = 0;
+ for (Segment s : task.getSegments()) {
+ minWcet += s.getJobWcet();
+ }
+
+ return minWcet;
+ }
+
+}
diff --git b/src/main/java/mvd/jester/tests/SchmidMottok.java a/src/main/java/mvd/jester/tests/SchmidMottok.java
new file mode 100644
index 0000000..44fc48f
--- /dev/null
+++ a/src/main/java/mvd/jester/tests/SchmidMottok.java
@@ -0,0 +1,112 @@
+package mvd.jester.tests;
+
+import java.math.RoundingMode;
+import java.util.Map.Entry;
+import com.google.common.math.LongMath;
+import mvd.jester.model.Segment;
+import mvd.jester.model.Task;
+import mvd.jester.model.SystemSetup;
+
+/**
+ * SchmidMottok
+ */
+public class SchmidMottok extends AbstractTest {
+
+ private SystemSetup systemSetup;
+
+ public SchmidMottok() {
+ }
+
+ @Override
+ public boolean runSchedulabilityCheck(SystemSetup systemSetup) {
+ responseTimes.clear();
+ this.systemSetup = systemSetup;
+ for (Task t : systemSetup.getTasks()) {
+ responseTimes.put(t, calculateResponseTime(t));
+ }
+
+ for (Entry taskResponsePair : responseTimes.entrySet()) {
+ if (taskResponsePair.getKey().getDeadline() < taskResponsePair.getValue().longValue()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return "SchmidMottok";
+ }
+
+ private long calculateResponseTime(Task task) {
+ long minimumWcet = getMinimumWcet(task);
+ long responseTime = minimumWcet;
+ long previousResponseTime = 0;
+
+
+ do {
+ previousResponseTime = responseTime;
+ long interference = 0;
+
+ for (Task t : systemSetup.getTasks()) {
+ if (t.getPeriod() < task.getPeriod()) {
+ interference += Math.min(getTaskInterference(t, responseTime),
+ responseTime - minimumWcet + 1);
+ }
+ }
+
+ double taskInterference = (double) interference / 4;
+ double selfInterference = getSelfInterference(task);
+
+ long totalInterference = (long) Math.floor(taskInterference + selfInterference);
+
+ responseTime = minimumWcet + totalInterference;
+ } while (previousResponseTime != responseTime);
+
+
+ return responseTime;
+ }
+
+
+ private double getSelfInterference(Task task) {
+ double interference = 0;
+
+ for (Segment s : task.getSegments()) {
+ long processingUnits = s.getNumberOfJobs() > 4 ? 4 : s.getNumberOfJobs();
+ interference +=
+ (double) (s.getNumberOfTasklets() - 1) * s.getTaskletWcet() / processingUnits;
+ }
+
+ return interference;
+ }
+
+ private long getTaskInterference(Task task, long interval) {
+ long responseTime = responseTimes.get(task);
+ long minWcet = getMinimumWcet(task);
+ long period = task.getPeriod();
+ long interference =
+ (LongMath.divide(interval + responseTime - minWcet, period, RoundingMode.FLOOR) + 1)
+ * getMaximumWcet(task);
+
+ return interference;
+ }
+
+ private long getMinimumWcet(Task task) {
+ long minWcet = 0;
+ for (Segment s : task.getSegments()) {
+ minWcet += s.getTaskletWcet();
+ }
+
+ return minWcet;
+ }
+
+ private long getMaximumWcet(Task task) {
+ long maxWcet = 0;
+ for (Segment s : task.getSegments()) {
+ maxWcet += s.getTaskletWcet() * s.getNumberOfTasklets();
+ }
+
+ return maxWcet;
+ }
+}
diff --git b/src/main/java/mvd/jester/tests/TestEnvironment.java a/src/main/java/mvd/jester/tests/TestEnvironment.java
new file mode 100644
index 0000000..8354b01
--- /dev/null
+++ a/src/main/java/mvd/jester/tests/TestEnvironment.java
@@ -0,0 +1,75 @@
+package mvd.jester.tests;
+
+import java.lang.reflect.Constructor;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import mvd.jester.model.SortedTaskSet;
+import mvd.jester.model.SystemSetup;
+
+/**
+ * TestEnvironment
+ */
+public class TestEnvironment {
+
+ private final long numberOfTaskSets;
+ private final long numberOfProcessors;
+ private final Set> abstractTests;
+
+ public TestEnvironment(long numberOfTaskSets, long numberOfProcessors) {
+ this.numberOfTaskSets = numberOfTaskSets;
+ this.numberOfProcessors = numberOfProcessors;
+ abstractTests = new HashSet<>();
+ }
+
+ public TestEnvironment registerTestInterface(Class extends AbstractTest> abstractTest) {
+ abstractTests.add(abstractTest);
+
+ return this;
+ }
+
+ public void runTests() {
+ Map testCases = new HashMap<>();
+
+ for (Class extends AbstractTest> t : abstractTests) {
+ try {
+ testCases.put(t.newInstance(), (long) 0);
+ } catch (Exception e) {
+ System.out.println("Ahhh SHIT!");
+ }
+ }
+
+
+ long checkedTasksets = 0;
+
+ while (checkedTasksets < 4000) {
+ SystemSetup.Generator generator = new SystemSetup.Generator();
+ SystemSetup systemSetup = generator.build();
+
+ double utilization = systemSetup.getUtilization();
+
+ while (utilization <= systemSetup.getNumberOfProcessors()
+ && checkedTasksets < numberOfTaskSets) {
+ checkedTasksets++;
+
+ for (AbstractTest t : testCases.keySet()) {
+ if (t.runSchedulabilityCheck(systemSetup)) {
+ testCases.computeIfPresent(t, (k, v) -> v + 1);
+ }
+ }
+ generator.addTask(systemSetup);
+
+ utilization = systemSetup.getUtilization();
+ }
+ }
+
+
+ for (AbstractTest t : testCases.keySet()) {
+ System.out.println("Testcase " + t.getName() + " scheduled " + testCases.get(t) + " of "
+ + numberOfTaskSets + " tasks!");
+ }
+
+
+ }
+}
diff --git b/src/main/java/mvd/jester/tests/TestInterface.java a/src/main/java/mvd/jester/tests/TestInterface.java
new file mode 100644
index 0000000..b92f13d
--- /dev/null
+++ a/src/main/java/mvd/jester/tests/TestInterface.java
@@ -0,0 +1,14 @@
+package mvd.jester.tests;
+
+import mvd.jester.model.SystemSetup;
+
+/**
+ * TestInterface
+ */
+public interface TestInterface {
+
+ public boolean runSchedulabilityCheck(SystemSetup systemSetup);
+
+ public String getName();
+
+}
diff --git b/src/main/java/mvd/jester/utils/TimeUnit.java a/src/main/java/mvd/jester/utils/TimeUnit.java
new file mode 100644
index 0000000..8f70a45
--- /dev/null
+++ a/src/main/java/mvd/jester/utils/TimeUnit.java
@@ -0,0 +1,40 @@
+package mvd.jester.utils;
+
+public class TimeUnit {
+ public static long Seconds(long seconds) {
+ return seconds*1_000_000_000;
+ }
+
+ public static long Seconds(double seconds) {
+ return Math.round(seconds*1_000_000_000);
+ }
+
+ public static long Milliseconds(long milliseconds) {
+ return milliseconds*1_000_000;
+ }
+
+ public static long Milliseconds(double milliseconds) {
+ return Math.round(milliseconds*1_000_000);
+ }
+
+ public static long Microseconds(long microseconds) {
+ return microseconds*1_000;
+ }
+
+ public static long Microseconds(double microseconds) {
+ return Math.round(microseconds*1_000);
+ }
+
+ public static long Nanoseconds(long nanoseconds) {
+ return nanoseconds;
+ }
+
+ public static long Nanoseconds(double nanoseconds) {
+ return Math.round(nanoseconds);
+ }
+
+ public static long RoundTo(long value, long round) {
+ return value / round * round;
+ }
+}
+
diff --git b/src/test/java/mvd/jester/model/TaskSetTest.java a/src/test/java/mvd/jester/model/TaskSetTest.java
new file mode 100644
index 0000000..4f23b0c
--- /dev/null
+++ a/src/test/java/mvd/jester/model/TaskSetTest.java
@@ -0,0 +1,41 @@
+package mvd.jester.model;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+
+public class TaskSetTest {
+
+ private static final int NUMBER_OF_SETS = 1000;
+
+ @Test
+ @DisplayName("Check if randomly generated task parameters lie within the specified ranges.")
+ public void testRandomTaskSetGeneration() {
+
+ for (int i = 0; i < NUMBER_OF_SETS; ++i) {
+ SystemSetup taskSet = new SystemSetup.Generator().build();
+
+ for (Task t : taskSet.getTasks()) {
+ assertTrue(t.getPeriod() >= 100);
+ assertTrue(t.getPeriod() <= 1000);
+ assertTrue(t.getDeadline() == t.getPeriod());
+
+ long maxJobWcet = t.getPeriod() / t.getSegments().size();
+
+ for (Segment s : t.getSegments()) {
+ assertTrue(s.getJobWcet() * s.getNumberOfJobs() == s.getTaskletWcet()
+ * s.getNumberOfTasklets());
+ assertTrue(s.getJobWcet() >= 1);
+ assertTrue(s.getJobWcet() <= maxJobWcet);
+ assertTrue(s.getNumberOfJobs() >= 1);
+ assertTrue(s.getNumberOfJobs() <= 6);
+ }
+
+ assertTrue(t.getSegments().size() >= 1);
+ assertTrue(t.getSegments().size() <= 5);
+ }
+ }
+
+ }
+}