Skip to content

Commit

Permalink
Development: Fix flaky priorityExamTest (#9276)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonEntholzer authored Oct 5, 2024
1 parent e3db599 commit 0634b5b
Showing 1 changed file with 112 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.naming.InvalidNameException;
import javax.naming.ldap.LdapName;
Expand All @@ -32,6 +31,7 @@
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.slf4j.Logger;
Expand All @@ -41,6 +41,11 @@
import org.springframework.http.HttpStatus;
import org.springframework.security.test.context.support.WithMockUser;

import com.hazelcast.collection.IQueue;
import com.hazelcast.core.HazelcastInstance;

import de.tum.cit.aet.artemis.buildagent.dto.BuildJobQueueItem;
import de.tum.cit.aet.artemis.buildagent.service.SharedQueueProcessingService;
import de.tum.cit.aet.artemis.core.service.ldap.LdapUserDto;
import de.tum.cit.aet.artemis.exam.domain.Exam;
import de.tum.cit.aet.artemis.exam.domain.ExerciseGroup;
Expand All @@ -55,6 +60,8 @@
import de.tum.cit.aet.artemis.programming.domain.build.BuildJob;
import de.tum.cit.aet.artemis.programming.domain.submissionpolicy.LockRepositoryPolicy;
import de.tum.cit.aet.artemis.programming.domain.submissionpolicy.SubmissionPolicy;
import de.tum.cit.aet.artemis.programming.service.localci.LocalCITriggerService;
import de.tum.cit.aet.artemis.programming.test_repository.BuildJobTestRepository;
import de.tum.cit.aet.artemis.programming.util.LocalRepository;

/**
Expand All @@ -69,6 +76,18 @@ class LocalVCLocalCIIntegrationTest extends AbstractLocalCILocalVCIntegrationTes
@Autowired
private ExamUtilService examUtilService;

@Autowired
private BuildJobTestRepository buildJobRepository;

@Autowired
protected LocalCITriggerService localCITriggerService;

@Autowired
private SharedQueueProcessingService sharedQueueProcessingService;

@Autowired
private HazelcastInstance hazelcastInstance;

@Value("${artemis.user-management.internal-admin.username}")
private String localVCUsername;

Expand All @@ -88,6 +107,8 @@ class LocalVCLocalCIIntegrationTest extends AbstractLocalCILocalVCIntegrationTes

private String teamRepositorySlug;

protected IQueue<BuildJobQueueItem> queuedJobs;

@BeforeAll
void setupAll() {
CredentialsProvider.setDefault(new UsernamePasswordCredentialsProvider(localVCUsername, localVCPassword));
Expand Down Expand Up @@ -137,6 +158,8 @@ void initRepositories() throws GitAPIException, IOException, URISyntaxException,
doReturn(true).when(ldapTemplate).compare(anyString(), anyString(), any());

localVCLocalCITestService.mockInspectImage(dockerClient);

queuedJobs = hazelcastInstance.getQueue("buildJobQueue");
}

@AfterEach
Expand Down Expand Up @@ -925,75 +948,93 @@ void testFetchPush_instructorPracticeRepository() throws Exception {
practiceRepository.resetLocalRepo();
}

@Test
@WithMockUser(username = TEST_PREFIX + "student1", roles = "USER")
void testBuildPriorityAfterDueDate() throws Exception {
// Set dueDate before now
programmingExercise.setDueDate(ZonedDateTime.now().minusMinutes(1));
programmingExerciseRepository.save(programmingExercise);

testPriority(instructor1Login, PRIORITY_OPTIONAL_EXERCISE);
}

@Test
@WithMockUser(username = TEST_PREFIX + "student1", roles = "USER")
void testBuildPriorityBeforeDueDate() throws Exception {
testPriority(student1Login, PRIORITY_NORMAL);
}

@Test
@WithMockUser(username = TEST_PREFIX + "student1", roles = "USER")
void testPriorityRunningExam() throws Exception {
Exam exam = examUtilService.addExamWithExerciseGroup(course, true);
ExerciseGroup exerciseGroup = exam.getExerciseGroups().getFirst();

programmingExercise.setCourse(null);
programmingExercise.setExerciseGroup(exerciseGroup);
programmingExercise = programmingExerciseRepository.save(programmingExercise);

// Exam is running
var now = ZonedDateTime.now();
exam.setStartDate(now.minusHours(1));
exam.setEndDate(now.plusHours(1));
exam.setWorkingTime(2 * 60 * 60);
exam = examRepository.save(exam);

// Create StudentExam.
StudentExam studentExam = examUtilService.addStudentExamWithUser(exam, student1);
studentExam.setExercises(List.of(programmingExercise));
studentExam.setWorkingTime(exam.getWorkingTime());
studentExam.setStartedAndStartDate(now.minusHours(1));
studentExamRepository.save(studentExam);

testPriority(student1Login, PRIORITY_EXAM_CONDUCTION);
}

private void testPriority(String login, int expectedPriority) throws Exception {
ProgrammingExerciseStudentParticipation studentParticipation = localVCLocalCITestService.createParticipation(programmingExercise, student1Login);

localVCLocalCITestService.testFetchSuccessful(assignmentRepository.localGit, login, projectKey1, assignmentRepositorySlug);
String commitHash = localVCLocalCITestService.commitFile(assignmentRepository.localRepoFile.toPath(), assignmentRepository.localGit);
localVCLocalCITestService.mockInputStreamReturnedFromContainer(dockerClient, LOCALCI_WORKING_DIRECTORY + "/testing-dir/assignment/.git/refs/heads/[^/]+",
Map.of("commitHash", commitHash), Map.of("commitHash", commitHash));
localVCLocalCITestService.mockTestResults(dockerClient, PARTLY_SUCCESSFUL_TEST_RESULTS_PATH, LOCALCI_WORKING_DIRECTORY + LOCALCI_RESULTS_DIRECTORY);
localVCLocalCITestService.testPushSuccessful(assignmentRepository.localGit, login, projectKey1, assignmentRepositorySlug);

log.info("Push done");

await().atMost(15, TimeUnit.SECONDS).until(() -> {
log.info("Search for a build job for participation id: {}", studentParticipation.getId());
Optional<BuildJob> buildJobOptional = buildJobRepository.findFirstByParticipationIdOrderByBuildStartDateDesc(studentParticipation.getId());
if (buildJobOptional.isPresent()) {
return true;
}
else {
var allBuildJobs = buildJobRepository.findAll();
log.info("All found build jobs: {}", allBuildJobs);
return false;
}
});

BuildJob buildJob = buildJobRepository.findFirstByParticipationIdOrderByBuildStartDateDesc(studentParticipation.getId()).orElseThrow();
assertThat(buildJob.getPriority()).isEqualTo(expectedPriority);
@Nested
class BuildJobPriorityTest {

@BeforeEach
void setUp() {
sharedQueueProcessingService.removeListener();
}

@AfterEach
void tearDown() {
queuedJobs.clear();
log.info("Clear queued jobs done");

sharedQueueProcessingService.init();
log.info("Cleanup queue processing service done");
}

@Test
@WithMockUser(username = TEST_PREFIX + "student1", roles = "USER")
void testBuildPriorityBeforeDueDate() throws Exception {
testPriority(student1Login, PRIORITY_NORMAL);
}

@Test
@WithMockUser(username = TEST_PREFIX + "student1", roles = "USER")
void testBuildPriorityAfterDueDate() throws Exception {
// Set dueDate before now
programmingExercise.setDueDate(ZonedDateTime.now().minusMinutes(1));
programmingExerciseRepository.save(programmingExercise);

testPriority(instructor1Login, PRIORITY_OPTIONAL_EXERCISE);
}

@Test
@WithMockUser(username = TEST_PREFIX + "student1", roles = "USER")
void testPriorityRunningExam() throws Exception {
Exam exam = examUtilService.addExamWithExerciseGroup(course, true);
ExerciseGroup exerciseGroup = exam.getExerciseGroups().getFirst();

programmingExercise.setCourse(null);
programmingExercise.setExerciseGroup(exerciseGroup);
programmingExercise = programmingExerciseRepository.save(programmingExercise);

// Exam is running
var now = ZonedDateTime.now();
exam.setStartDate(now.minusHours(1));
exam.setEndDate(now.plusHours(1));
exam.setWorkingTime(2 * 60 * 60);
exam = examRepository.save(exam);

// Create StudentExam.
StudentExam studentExam = examUtilService.addStudentExamWithUser(exam, student1);
studentExam.setExercises(List.of(programmingExercise));
studentExam.setWorkingTime(exam.getWorkingTime());
studentExam.setStartedAndStartDate(now.minusHours(1));
studentExamRepository.save(studentExam);

testPriority(student1Login, PRIORITY_EXAM_CONDUCTION);
}

private void testPriority(String login, int expectedPriority) throws Exception {
log.info("Creating participation");
ProgrammingExerciseStudentParticipation studentParticipation = localVCLocalCITestService.createParticipation(programmingExercise, student1Login);

localVCLocalCITestService.testFetchSuccessful(assignmentRepository.localGit, login, projectKey1, assignmentRepositorySlug);
String commitHash = localVCLocalCITestService.commitFile(assignmentRepository.localRepoFile.toPath(), assignmentRepository.localGit);
localVCLocalCITestService.mockInputStreamReturnedFromContainer(dockerClient, LOCALCI_WORKING_DIRECTORY + "/testing-dir/assignment/.git/refs/heads/[^/]+",
Map.of("commitHash", commitHash), Map.of("commitHash", commitHash));
localVCLocalCITestService.mockTestResults(dockerClient, PARTLY_SUCCESSFUL_TEST_RESULTS_PATH, LOCALCI_WORKING_DIRECTORY + LOCALCI_RESULTS_DIRECTORY);

localCITriggerService.triggerBuild(studentParticipation, false);
log.info("Trigger build done");

await().until(() -> {
BuildJobQueueItem buildJobQueueItem = queuedJobs.peek();
log.info("Poll queue jobs: is null %s".formatted(buildJobQueueItem == null ? "true" : "false"));
if (buildJobQueueItem == null) {
queuedJobs.forEach(item -> log.info("Item in Queue: %s".formatted(item.toString())));
}
return buildJobQueueItem != null && buildJobQueueItem.participationId() == studentParticipation.getId();
});
BuildJobQueueItem buildJobQueueItem = queuedJobs.poll();
log.info("Polled queue item");

assertThat(buildJobQueueItem).isNotNull();
assertThat(buildJobQueueItem.priority()).isEqualTo(expectedPriority);
log.info("Assertions done");
}
}
}

0 comments on commit 0634b5b

Please sign in to comment.