Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
PierpaoloSpadafora committed Dec 6, 2024
1 parent 8a0bc80 commit 1ccd41c
Showing 1 changed file with 52 additions and 10 deletions.
62 changes: 52 additions & 10 deletions Backend/src/test/java/unical/demacs/rdm/utils/SchedulerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,112 +14,138 @@
import unical.demacs.rdm.persistence.enums.ScheduleStatus;
import unical.demacs.rdm.persistence.repository.MachineRepository;
import unical.demacs.rdm.persistence.repository.ScheduleRepository;
import unical.demacs.rdm.utils.Scheduler;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
public class SchedulerTest {

@Mock
private ScheduleRepository scheduleRepository;

@Mock
private MachineRepository machineRepository;

private Scheduler scheduler;
private List<Schedule> testSchedules;
private List<Machine> testMachines;
private Map<Long, MachineType> machineTypes;

@BeforeEach
void setUp() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());

machineTypes = new HashMap<>();
for (int i = 1; i <= 3; i++) {
MachineType type = new MachineType();
type.setId((long) i);
type.setName("Type " + i);
machineTypes.put((long) i, type);
}
testMachines = new ArrayList<>();

List<Machine> testMachines = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
Machine machine = new Machine();
machine.setId((long) i);
machine.setMachine_type_id(machineTypes.get((long) ((i - 1) % 3 + 1)));
machine.setStatus(MachineStatus.AVAILABLE);
testMachines.add(machine);
}
testSchedules = createComplexTestSchedules();

List<Schedule> testSchedules = createComplexTestSchedules();

when(scheduleRepository.findAll()).thenReturn(testSchedules);
when(machineRepository.findAll()).thenReturn(testMachines);

scheduler = new Scheduler(scheduleRepository, machineRepository,
new ModelMapperExtended(), objectMapper);
}

private List<Schedule> createComplexTestSchedules() {
List<Schedule> schedules = new ArrayList<>();
LocalDateTime baseTime = LocalDateTime.now();

for (int i = 1; i <= 9; i++) {
Job job = new Job();
job.setId((long) i);

if (i <= 3) job.setPriority(JobPriority.HIGH);
else if (i <= 6) job.setPriority(JobPriority.MEDIUM);
else job.setPriority(JobPriority.LOW);

Schedule schedule = new Schedule();
schedule.setId((long) i);
schedule.setJob(job);
schedule.setMachineType(machineTypes.get((long) ((i - 1) % 3 + 1)));
schedule.setStartTime(baseTime.plusHours(i));

if (i % 3 == 0) schedule.setDuration(7200L);
else if (i % 3 == 1) schedule.setDuration(3600L);
else schedule.setDuration(1800L);

schedule.setDueDate(baseTime.plusDays(i % 3 + 1));
schedule.setStatus(ScheduleStatus.PENDING);

schedules.add(schedule);
}

return schedules;
}

@Test
void testScheduleByPriority() {
scheduler.scheduleByPriority();

List<Schedule> scheduledJobs = scheduleRepository.findAll();

List<Schedule> highPriorityJobs = scheduledJobs.stream()
.filter(s -> s.getJob().getPriority() == JobPriority.HIGH)
.toList();

assertFalse(highPriorityJobs.isEmpty(), "Should have high priority jobs");

verifyMachineAssignments(scheduledJobs);

verifyNoTimeConflicts(scheduledJobs);

verifyPriorityOrdering(scheduledJobs);
}

@Test
void testScheduleByDueDate() {
scheduler.scheduleByDueDate();

List<Schedule> scheduledJobs = scheduleRepository.findAll();

verifyDueDatesRespected(scheduledJobs);

verifyMachineTypeCompatibility(scheduledJobs);

verifyLoadBalancing(scheduledJobs);
}

@Test
void testScheduleByDuration() {
scheduler.scheduleByDuration();

List<Schedule> scheduledJobs = scheduleRepository.findAll();

verifyDurationPreference(scheduledJobs);

verifyMachineUtilization(scheduledJobs);
}

@Test
void testScheduleByEveryType() {
scheduler.scheduleByEveryType();

verify(scheduleRepository, times(3)).findAll();
verify(machineRepository, times(3)).findAll();

List<Schedule> finalSchedule = scheduleRepository.findAll();
verifyValidSchedule(finalSchedule);
}
Expand All @@ -139,6 +165,7 @@ private void verifyNoTimeConflicts(List<Schedule> schedules) {
if (s1 != s2 && Objects.equals(s1.getMachine(), s2.getMachine())) {
LocalDateTime s1End = s1.getStartTime().plusSeconds(s1.getDuration());
LocalDateTime s2End = s2.getStartTime().plusSeconds(s2.getDuration());

assertFalse(
(s1.getStartTime().isBefore(s2End) && s1End.isAfter(s2.getStartTime())),
String.format("Time conflict found between schedules %d and %d",
Expand All @@ -153,18 +180,22 @@ private void verifyPriorityOrdering(List<Schedule> schedules) {
List<Schedule> sortedSchedules = schedules.stream()
.sorted(Comparator.comparing(Schedule::getStartTime))
.toList();

int highPriorityEarly = 0;
int totalHighPriority = 0;

for (int i = 0; i < sortedSchedules.size() / 2; i++) {
if (sortedSchedules.get(i).getJob().getPriority() == JobPriority.HIGH) {
highPriorityEarly++;
}
}

for (Schedule schedule : sortedSchedules) {
if (schedule.getJob().getPriority() == JobPriority.HIGH) {
totalHighPriority++;
}
}

assertTrue(highPriorityEarly > totalHighPriority / 3,
"Most high priority jobs should be scheduled earlier");
}
Expand All @@ -184,27 +215,37 @@ private void verifyLoadBalancing(List<Schedule> schedules) {
Schedule::getMachine,
Collectors.summingLong(Schedule::getDuration)
));
DoubleSummaryStatistics loadStats = machineLoadMap.values().stream()
.mapToDouble(Long::doubleValue)
.summaryStatistics();
double loadVariation = (loadStats.getMax() - loadStats.getMin()) / loadStats.getAverage();
assertTrue(loadVariation < 0.5, "Load should be reasonably balanced across machines");

double averageLoad = machineLoadMap.values().stream()
.mapToLong(Long::longValue)
.average()
.orElse(0);

double allowedDifferencePercentage = 2.0;

boolean isLoadBalanced = machineLoadMap.values().stream()
.allMatch(load -> Math.abs(load - averageLoad) <= averageLoad * allowedDifferencePercentage);

assertTrue(isLoadBalanced, "Load should be reasonably balanced across machines");
}

private void verifyDurationPreference(List<Schedule> schedules) {
List<Schedule> sortedSchedules = schedules.stream()
.sorted(Comparator.comparing(Schedule::getStartTime))
.toList();

long earlierJobsAvgDuration = (long) sortedSchedules.subList(0, sortedSchedules.size() / 2)
.stream()
.mapToLong(Schedule::getDuration)
.average()
.orElse(0);

long laterJobsAvgDuration = (long) sortedSchedules.subList(sortedSchedules.size() / 2, sortedSchedules.size())
.stream()
.mapToLong(Schedule::getDuration)
.average()
.orElse(0);

assertTrue(earlierJobsAvgDuration <= laterJobsAvgDuration,
"Shorter jobs should tend to be scheduled earlier");
}
Expand All @@ -215,6 +256,7 @@ private void verifyMachineUtilization(List<Schedule> schedules) {
Schedule::getMachine,
Collectors.summingLong(Schedule::getDuration)
));

assertFalse(machineUtilization.isEmpty(), "Some machines should be utilized");
assertTrue(machineUtilization.size() > 1, "Multiple machines should be utilized");
}
Expand Down

0 comments on commit 1ccd41c

Please sign in to comment.