diff --git a/src/main/java/de/tum/in/www1/artemis/service/scheduled/NotificationScheduleService.java b/src/main/java/de/tum/in/www1/artemis/service/scheduled/NotificationScheduleService.java index d9bb867f3bc4..d1f49b6e1997 100644 --- a/src/main/java/de/tum/in/www1/artemis/service/scheduled/NotificationScheduleService.java +++ b/src/main/java/de/tum/in/www1/artemis/service/scheduled/NotificationScheduleService.java @@ -164,8 +164,9 @@ private void scheduleNotificationForAssessedExercisesSubmissions(Exercise exerci * @return true if the time is valid else false */ private boolean checkIfTimeIsCorrectForScheduledTask(ZonedDateTime relevantTime) { - // only send a notification if relevantTime is defined and not in the future (i.e. in the range [now-2 minutes, now]) (due to possible delays in scheduling) - return relevantTime != null && !relevantTime.isBefore(ZonedDateTime.now().minusMinutes(2)) && !relevantTime.isAfter(ZonedDateTime.now()); + // Only send a notification if relevantTime is defined and close to the current time (i.e. in the range [now-2 minutes, now+2 minutes]) (due to possible delays in + // scheduling) + return relevantTime != null && !relevantTime.isBefore(ZonedDateTime.now().minusMinutes(2)) && !relevantTime.isAfter(ZonedDateTime.now().plusMinutes(2)); } /** diff --git a/src/main/java/de/tum/in/www1/artemis/web/websocket/QuizSubmissionWebsocketService.java b/src/main/java/de/tum/in/www1/artemis/web/websocket/QuizSubmissionWebsocketService.java index e394a3863d1f..8aac25aa6091 100644 --- a/src/main/java/de/tum/in/www1/artemis/web/websocket/QuizSubmissionWebsocketService.java +++ b/src/main/java/de/tum/in/www1/artemis/web/websocket/QuizSubmissionWebsocketService.java @@ -4,8 +4,6 @@ import javax.validation.Valid; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.messaging.handler.annotation.DestinationVariable; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.messaging.handler.annotation.Payload; @@ -14,13 +12,12 @@ import de.tum.in.www1.artemis.domain.quiz.QuizSubmission; import de.tum.in.www1.artemis.exception.QuizSubmissionException; import de.tum.in.www1.artemis.security.SecurityUtils; -import de.tum.in.www1.artemis.service.*; +import de.tum.in.www1.artemis.service.QuizSubmissionService; +import de.tum.in.www1.artemis.service.WebsocketMessagingService; @Controller public class QuizSubmissionWebsocketService { - private static final Logger log = LoggerFactory.getLogger(QuizSubmissionWebsocketService.class); - private final QuizSubmissionService quizSubmissionService; private final WebsocketMessagingService websocketMessagingService; @@ -45,29 +42,11 @@ public void saveSubmission(@DestinationVariable Long exerciseId, @Valid @Payload // Without this, custom jpa repository methods don't work in websocket channel. SecurityUtils.setAuthorizationObject(); try { - QuizSubmission updatedQuizSubmission = quizSubmissionService.saveSubmissionForLiveMode(exerciseId, quizSubmission, principal.getName(), false); - // send updated submission over websocket (use a thread to prevent that the outbound channel blocks the inbound channel (e.g. due a slow client)) - // to improve the performance, this is currently deactivated: slow clients might lead to bottlenecks so that more important messages can not be distributed any more - // new Thread(() -> sendSubmissionToUser(username, exerciseId, quizSubmission)).start(); - - // log.info("WS.Inbound: Sent quiz submission (async) back to user {} in quiz {} after {} µs ", principal.getName(), exerciseId, (System.nanoTime() - start) / 1000); + quizSubmissionService.saveSubmissionForLiveMode(exerciseId, quizSubmission, principal.getName(), false); } catch (QuizSubmissionException ex) { // send error message over websocket (use Async to prevent that the outbound channel blocks the inbound channel (e.g. due a slow client)) websocketMessagingService.sendMessageToUser(principal.getName(), "/topic/quizExercise/" + exerciseId + "/submission", new WebsocketError(ex.getMessage())); } } - - /** - * Should be invoked using a thread asynchronously - * - * @param username the user who saved / submitted the quiz submission - * @param exerciseId the quiz exercise id - * @param quizSubmission the quiz submission that is returned back to the user - */ - private void sendSubmissionToUser(String username, Long exerciseId, QuizSubmission quizSubmission) { - long start = System.nanoTime(); - websocketMessagingService.sendMessageToUser(username, "/topic/quizExercise/" + exerciseId + "/submission", quizSubmission); - log.info("WS.Outbound: Sent quiz submission to user {} in quiz {} in {} µs ", username, exerciseId, (System.nanoTime() - start) / 1000); - } } diff --git a/src/main/webapp/app/exam/manage/exams/exam-exercise-import/exam-exercise-import.component.ts b/src/main/webapp/app/exam/manage/exams/exam-exercise-import/exam-exercise-import.component.ts index b5f3d94a8c64..be3ba91c83fc 100644 --- a/src/main/webapp/app/exam/manage/exams/exam-exercise-import/exam-exercise-import.component.ts +++ b/src/main/webapp/app/exam/manage/exams/exam-exercise-import/exam-exercise-import.component.ts @@ -1,9 +1,8 @@ import { Component, Input, OnInit } from '@angular/core'; import { Exam } from 'app/entities/exam.model'; -import { faCheckDouble, faFileUpload, faFont, faKeyboard, faProjectDiagram } from '@fortawesome/free-solid-svg-icons'; +import { faCheckDouble, faFont } from '@fortawesome/free-solid-svg-icons'; import { Exercise, ExerciseType } from 'app/entities/exercise.model'; import { ExerciseGroup } from 'app/entities/exercise-group.model'; -import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { SHORT_NAME_PATTERN } from 'app/shared/constants/input.constants'; import { getIcon } from 'app/entities/exercise.model'; @@ -40,9 +39,6 @@ export class ExamExerciseImportComponent implements OnInit { // Icons faCheckDouble = faCheckDouble; - faFileUpload = faFileUpload; - faProjectDiagram = faProjectDiagram; - faKeyboard = faKeyboard; faFont = faFont; getExerciseIcon = getIcon; diff --git a/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationBambooBitbucketJiraTest.java b/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationBambooBitbucketJiraTest.java index bb2788dbb75c..b5d0a0e03fcf 100644 --- a/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationBambooBitbucketJiraTest.java +++ b/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationBambooBitbucketJiraTest.java @@ -17,6 +17,9 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.junit.jupiter.api.parallel.ResourceLock; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; @@ -57,6 +60,8 @@ @SpringBootTest @AutoConfigureMockMvc @ExtendWith(SpringExtension.class) +@Execution(ExecutionMode.CONCURRENT) +@ResourceLock("AbstractSpringIntegrationBambooBitbucketJiraTest") @AutoConfigureEmbeddedDatabase // NOTE: we use a common set of active profiles to reduce the number of application launches during testing. This significantly saves time and memory! @ActiveProfiles({ SPRING_PROFILE_TEST, "artemis", "bamboo", "bitbucket", "jira", "ldap", "scheduling", "athena", "apollon", "iris" }) diff --git a/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationGitlabCIGitlabSamlTest.java b/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationGitlabCIGitlabSamlTest.java index c04448a40faa..9203c5e0ac25 100644 --- a/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationGitlabCIGitlabSamlTest.java +++ b/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationGitlabCIGitlabSamlTest.java @@ -1,7 +1,5 @@ package de.tum.in.www1.artemis; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; import static tech.jhipster.config.JHipsterConstants.SPRING_PROFILE_TEST; @@ -13,6 +11,9 @@ import org.gitlab4j.api.models.PipelineStatus; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.junit.jupiter.api.parallel.ResourceLock; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; @@ -44,6 +45,8 @@ @SpringBootTest @AutoConfigureMockMvc @ExtendWith(SpringExtension.class) +@Execution(ExecutionMode.CONCURRENT) +@ResourceLock("AbstractSpringIntegrationGitlabCIGitlabSamlTest") @AutoConfigureEmbeddedDatabase // NOTE: we use a common set of active profiles to reduce the number of application launches during testing. This significantly saves time and memory! @ActiveProfiles({ SPRING_PROFILE_TEST, "artemis", "gitlabci", "gitlab", "saml2", "scheduling" }) diff --git a/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationIndependentTest.java b/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationIndependentTest.java new file mode 100644 index 000000000000..f1e0b8343697 --- /dev/null +++ b/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationIndependentTest.java @@ -0,0 +1,301 @@ +package de.tum.in.www1.artemis; + +import static tech.jhipster.config.JHipsterConstants.SPRING_PROFILE_TEST; + +import java.util.Set; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.junit.jupiter.api.parallel.ResourceLock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import de.tum.in.www1.artemis.domain.*; +import de.tum.in.www1.artemis.domain.participation.AbstractBaseProgrammingExerciseParticipation; +import de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation; +import de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation; +import de.tum.in.www1.artemis.util.AbstractArtemisIntegrationTest; +import io.zonky.test.db.AutoConfigureEmbeddedDatabase; + +/** + * This SpringBootTest is used for tests that only require a minimal set of Active Spring Profiles. + */ +@SpringBootTest +@AutoConfigureMockMvc +@ExtendWith(SpringExtension.class) +@Execution(ExecutionMode.CONCURRENT) +@ResourceLock("AbstractSpringIntegrationIndependentTest") +@AutoConfigureEmbeddedDatabase +// NOTE: we use a common set of active profiles to reduce the number of application launches during testing. This significantly saves time and memory! +@ActiveProfiles({ SPRING_PROFILE_TEST, "artemis", "scheduling" }) +@TestPropertySource(properties = { "artemis.user-management.use-external=false" }) +public abstract class AbstractSpringIntegrationIndependentTest extends AbstractArtemisIntegrationTest { + + private final Logger log = LoggerFactory.getLogger(this.getClass()); + + @AfterEach + protected void resetSpyBeans() { + super.resetSpyBeans(); + } + + @Override + public void mockConnectorRequestsForSetup(ProgrammingExercise exercise, boolean failToCreateCiProject) { + log.debug("Called mockConnectorRequestsForSetup with args {}, {}", exercise, failToCreateCiProject); + } + + @Override + public void mockConnectorRequestsForImport(ProgrammingExercise sourceExercise, ProgrammingExercise exerciseToBeImported, boolean recreateBuildPlans, boolean addAuxRepos) { + log.debug("Called mockConnectorRequestsForImport with args {}, {}, {}, {}", sourceExercise, exerciseToBeImported, recreateBuildPlans, addAuxRepos); + } + + @Override + public void mockConnectorRequestForImportFromFile(ProgrammingExercise exerciseForImport) { + log.debug("Called mockConnectorRequestForImportFromFile with args {}", exerciseForImport); + } + + @Override + public void mockImportProgrammingExerciseWithFailingEnablePlan(ProgrammingExercise sourceExercise, ProgrammingExercise exerciseToBeImported, boolean planExistsInCi, + boolean shouldPlanEnableFail) { + log.debug("Called mockImportProgrammingExerciseWithFailingEnablePlan with args {}, {}, {}, {}", sourceExercise, exerciseToBeImported, planExistsInCi, shouldPlanEnableFail); + } + + @Override + public void mockConnectorRequestsForStartParticipation(ProgrammingExercise exercise, String username, Set users, boolean ltiUserExists) { + log.debug("Called mockConnectorRequestsForStartParticipation with args {}, {}, {}, {}", exercise, username, users, ltiUserExists); + } + + @Override + public void mockConnectorRequestsForResumeParticipation(ProgrammingExercise exercise, String username, Set users, boolean ltiUserExists) { + log.debug("Called mockConnectorRequestsForResumeParticipation with args {}, {}, {}, {}", exercise, username, users, ltiUserExists); + } + + @Override + public void mockUpdatePlanRepositoryForParticipation(ProgrammingExercise exercise, String username) { + log.debug("Called mockUpdatePlanRepositoryForParticipation with args {}, {}", exercise, username); + } + + @Override + public void mockUpdatePlanRepository(ProgrammingExercise exercise, String planName, String repoNameInCI, String repoNameInVcs) { + log.debug("Called mockUpdatePlanRepository with args {}, {}, {}, {}", exercise, planName, repoNameInCI, repoNameInVcs); + } + + @Override + public void mockRemoveRepositoryAccess(ProgrammingExercise exercise, Team team, User firstStudent) { + log.debug("Called mockRemoveRepositoryAccess with args {}, {}, {}", exercise, team, firstStudent); + } + + @Override + public void mockCopyRepositoryForParticipation(ProgrammingExercise exercise, String username) { + log.debug("Called mockCopyRepositoryForParticipation with args {}, {}", exercise, username); + } + + @Override + public void mockRepositoryWritePermissionsForTeam(Team team, User newStudent, ProgrammingExercise exercise, HttpStatus status) { + log.debug("Called mockRepositoryWritePermissionsForTeam with args {}, {}, {}, {}", team, newStudent, exercise, status); + } + + @Override + public void mockRepositoryWritePermissionsForStudent(User student, ProgrammingExercise exercise, HttpStatus status) { + log.debug("Called mockRepositoryWritePermissionsForStudent with args {}, {}, {}", student, exercise, status); + } + + @Override + public void mockRetrieveArtifacts(ProgrammingExerciseStudentParticipation participation) { + log.debug("Called mockRetrieveArtifacts with args {}", participation); + } + + @Override + public void mockFetchCommitInfo(String projectKey, String repositorySlug, String hash) { + log.debug("Called mockFetchCommitInfo with args {}, {}, {}", projectKey, repositorySlug, hash); + } + + @Override + public void mockCopyBuildPlan(ProgrammingExerciseStudentParticipation participation) { + log.debug("Called mockCopyBuildPlan with args {}", participation); + } + + @Override + public void mockConfigureBuildPlan(ProgrammingExerciseStudentParticipation participation) { + log.debug("Called mockConfigureBuildPlan with args {}", participation); + } + + @Override + public void mockTriggerFailedBuild(ProgrammingExerciseStudentParticipation participation) { + log.debug("Called mockTriggerFailedBuild with args {}", participation); + } + + @Override + public void mockGrantReadAccess(ProgrammingExerciseStudentParticipation participation) { + log.debug("Called mockGrantReadAccess with args {}", participation); + } + + @Override + public void mockNotifyPush(ProgrammingExerciseStudentParticipation participation) { + log.debug("Called mockNotifyPush with args {}", participation); + } + + @Override + public void mockTriggerParticipationBuild(ProgrammingExerciseStudentParticipation participation) { + log.debug("Called mockTriggerParticipationBuild with args {}", participation); + } + + @Override + public void mockTriggerInstructorBuildAll(ProgrammingExerciseStudentParticipation participation) { + log.debug("Called mockTriggerInstructorBuildAll with args {}", participation); + } + + @Override + public void resetMockProvider() { + log.debug("Called resetMockProvider"); + } + + @Override + public void verifyMocks() { + log.debug("Called verifyMocks"); + } + + @Override + public void mockUpdateUserInUserManagement(String oldLogin, User user, String password, Set oldGroups) { + log.debug("Called mockUpdateUserInUserManagement with args {}, {}, {}, {}", oldLogin, user, password, oldGroups); + } + + @Override + public void mockUpdateCoursePermissions(Course updatedCourse, String oldInstructorGroup, String oldEditorGroup, String oldTeachingAssistantGroup) { + log.debug("Called mockUpdateCoursePermissions with args {}, {}, {}, {}", updatedCourse, oldInstructorGroup, oldEditorGroup, oldTeachingAssistantGroup); + } + + @Override + public void mockFailUpdateCoursePermissionsInCi(Course updatedCourse, String oldInstructorGroup, String oldEditorGroup, String oldTeachingAssistantGroup, + boolean failToAddUsers, boolean failToRemoveUsers) { + log.debug("Called mockFailUpdateCoursePermissionsInCi with args {}, {}, {}, {}, {}, {}", updatedCourse, oldInstructorGroup, oldEditorGroup, oldTeachingAssistantGroup, + failToAddUsers, failToRemoveUsers); + } + + @Override + public void mockCreateUserInUserManagement(User user, boolean userExistsInCi) { + log.debug("Called mockCreateUserInUserManagement with args {}, {}", user, userExistsInCi); + } + + @Override + public void mockFailToCreateUserInExternalUserManagement(User user, boolean failInVcs, boolean failInCi, boolean failToGetCiUser) { + log.debug("Called mockFailToCreateUserInExternalUserManagement with args {}, {}, {}, {}", user, failInVcs, failInCi, failToGetCiUser); + } + + @Override + public void mockDeleteUserInUserManagement(User user, boolean userExistsInUserManagement, boolean failInVcs, boolean failInCi) { + log.debug("Called mockDeleteUserInUserManagement with args {}, {}, {}, {}", user, userExistsInUserManagement, failInVcs, failInCi); + } + + @Override + public void mockCreateGroupInUserManagement(String groupName) { + log.debug("Called mockCreateGroupInUserManagement with args {}", groupName); + } + + @Override + public void mockDeleteGroupInUserManagement(String groupName) { + log.debug("Called mockDeleteGroupInUserManagement with args {}", groupName); + } + + @Override + public void mockAddUserToGroupInUserManagement(User user, String group, boolean failInCi) { + log.debug("Called mockAddUserToGroupInUserManagement with args {}, {}, {}", user, group, failInCi); + } + + @Override + public void mockRemoveUserFromGroup(User user, String group, boolean failInCi) { + log.debug("Called mockRemoveUserFromGroup with args {}, {}, {}", user, group, failInCi); + } + + @Override + public void mockDeleteRepository(String projectKey, String repositoryName, boolean shouldFail) { + log.debug("Called mockDeleteRepository with args {}, {}, {}", projectKey, repositoryName, shouldFail); + } + + @Override + public void mockDeleteProjectInVcs(String projectKey, boolean shouldFail) { + log.debug("Called mockDeleteProjectInVcs with args {}, {}", projectKey, shouldFail); + } + + @Override + public void mockDeleteBuildPlan(String projectKey, String planName, boolean shouldFail) { + log.debug("Called mockDeleteBuildPlan with args {}, {}, {}", projectKey, planName, shouldFail); + } + + @Override + public void mockDeleteBuildPlanProject(String projectKey, boolean shouldFail) { + log.debug("Called mockDeleteBuildPlanProject with args {}, {}", projectKey, shouldFail); + } + + @Override + public void mockGetBuildPlan(String projectKey, String planName, boolean planExistsInCi, boolean planIsActive, boolean planIsBuilding, boolean failToGetBuild) { + log.debug("Called mockGetBuildPlan with args {}, {}, {}, {}, {}, {}", projectKey, planName, planExistsInCi, planIsActive, planIsBuilding, failToGetBuild); + } + + @Override + public void mockHealthInCiService(boolean isRunning, HttpStatus httpStatus) { + log.debug("Called mockHealthInCiService with args {}, {}", isRunning, httpStatus); + } + + @Override + public void mockConfigureBuildPlan(ProgrammingExerciseParticipation participation, String defaultBranch) { + log.debug("Called mockConfigureBuildPlan with args {}, {}", participation, defaultBranch); + } + + @Override + public void mockCheckIfProjectExistsInVcs(ProgrammingExercise exercise, boolean existsInVcs) { + log.debug("Called mockCheckIfProjectExistsInVcs with args {}, {}", exercise, existsInVcs); + } + + @Override + public void mockCheckIfProjectExistsInCi(ProgrammingExercise exercise, boolean existsInCi, boolean shouldFail) { + log.debug("Called mockCheckIfProjectExistsInCi with args {}, {}, {}", exercise, existsInCi, shouldFail); + } + + @Override + public void mockCheckIfBuildPlanExists(String projectKey, String templateBuildPlanId, boolean buildPlanExists, boolean shouldFail) { + log.debug("Called mockCheckIfBuildPlanExists with args {}, {}, {}, {}", projectKey, templateBuildPlanId, buildPlanExists, shouldFail); + } + + @Override + public void mockRepositoryUrlIsValid(VcsRepositoryUrl vcsTemplateRepositoryUrl, String projectKey, boolean b) { + log.debug("Called mockRepositoryUrlIsValid with args {}, {}, {}", vcsTemplateRepositoryUrl, projectKey, b); + } + + @Override + public void mockTriggerBuild(AbstractBaseProgrammingExerciseParticipation solutionParticipation) { + log.debug("Called mockTriggerBuild with args {}", solutionParticipation); + } + + @Override + public void mockTriggerBuildFailed(AbstractBaseProgrammingExerciseParticipation solutionParticipation) { + log.debug("Called mockTriggerBuildFailed with args {}", solutionParticipation); + } + + @Override + public void mockSetRepositoryPermissionsToReadOnly(VcsRepositoryUrl repositoryUrl, String projectKey, Set users) { + log.debug("Called mockSetRepositoryPermissionsToReadOnly with args {}, {}, {}", repositoryUrl, projectKey, users); + } + + @Override + public void mockConfigureRepository(ProgrammingExercise exercise, String participantIdentifier, Set students, boolean userExists) { + log.debug("Called mockConfigureRepository with args {}, {}, {}, {}", exercise, participantIdentifier, students, userExists); + } + + @Override + public void mockDefaultBranch(ProgrammingExercise programmingExercise) { + log.debug("Called mockDefaultBranch with args {}", programmingExercise); + } + + @Override + public void mockUserExists(String username) { + log.debug("Called mockUserExists with args {}", username); + } +} diff --git a/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationJenkinsGitlabTest.java b/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationJenkinsGitlabTest.java index 6408d1206b73..e1b6e7a24cf5 100644 --- a/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationJenkinsGitlabTest.java +++ b/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationJenkinsGitlabTest.java @@ -13,6 +13,9 @@ import org.gitlab4j.api.GitLabApiException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.junit.jupiter.api.parallel.ResourceLock; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; @@ -40,6 +43,8 @@ @SpringBootTest @AutoConfigureMockMvc @ExtendWith(SpringExtension.class) +@Execution(ExecutionMode.CONCURRENT) +@ResourceLock("AbstractSpringIntegrationJenkinsGitlabTest") @AutoConfigureEmbeddedDatabase // NOTE: we use a common set of active profiles to reduce the number of application launches during testing. This significantly saves time and memory! @ActiveProfiles({ SPRING_PROFILE_TEST, "artemis", "gitlab", "jenkins", "athena", "scheduling" }) diff --git a/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationLocalCILocalVCTest.java b/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationLocalCILocalVCTest.java index b95466f8b7fe..b46c528daa67 100644 --- a/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationLocalCILocalVCTest.java +++ b/src/test/java/de/tum/in/www1/artemis/AbstractSpringIntegrationLocalCILocalVCTest.java @@ -11,6 +11,9 @@ import org.gitlab4j.api.GitLabApiException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.junit.jupiter.api.parallel.ResourceLock; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -55,6 +58,8 @@ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) @AutoConfigureMockMvc @ExtendWith(SpringExtension.class) +@Execution(ExecutionMode.CONCURRENT) +@ResourceLock("AbstractSpringIntegrationLocalCILocalVCTest") @AutoConfigureEmbeddedDatabase // NOTE: we use a common set of active profiles to reduce the number of application launches during testing. This significantly saves time and memory! @ActiveProfiles({ SPRING_PROFILE_TEST, "artemis", "localci", "localvc", "scheduling", "ldap-only" }) diff --git a/src/test/java/de/tum/in/www1/artemis/ClientForwardTest.java b/src/test/java/de/tum/in/www1/artemis/ClientForwardTest.java index b3fe8d4e6a05..452ff334c92c 100644 --- a/src/test/java/de/tum/in/www1/artemis/ClientForwardTest.java +++ b/src/test/java/de/tum/in/www1/artemis/ClientForwardTest.java @@ -20,7 +20,7 @@ * * @see ClientForwardResource */ -class ClientForwardTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ClientForwardTest extends AbstractSpringIntegrationIndependentTest { @Autowired private JWTCookieService jwtCookieService; diff --git a/src/test/java/de/tum/in/www1/artemis/ContentVersionIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/ContentVersionIntegrationTest.java index 90f05369fcbd..98e1a3805c85 100644 --- a/src/test/java/de/tum/in/www1/artemis/ContentVersionIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/ContentVersionIntegrationTest.java @@ -15,7 +15,7 @@ import de.tum.in.www1.artemis.config.ApiVersionFilter; import de.tum.in.www1.artemis.user.UserUtilService; -class ContentVersionIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ContentVersionIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "contentversion"; diff --git a/src/test/java/de/tum/in/www1/artemis/DatabaseQueryCountTest.java b/src/test/java/de/tum/in/www1/artemis/DatabaseQueryCountTest.java index db17e3683e4c..060dac060f74 100644 --- a/src/test/java/de/tum/in/www1/artemis/DatabaseQueryCountTest.java +++ b/src/test/java/de/tum/in/www1/artemis/DatabaseQueryCountTest.java @@ -1,5 +1,7 @@ package de.tum.in.www1.artemis; +import java.util.Set; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.slf4j.Logger; @@ -10,11 +12,12 @@ import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; +import de.tum.in.www1.artemis.domain.User; import de.tum.in.www1.artemis.domain.exam.StudentExam; import de.tum.in.www1.artemis.exam.ExamUtilService; import de.tum.in.www1.artemis.user.UserUtilService; -class DatabaseQueryCountTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class DatabaseQueryCountTest extends AbstractSpringIntegrationIndependentTest { private final Logger log = LoggerFactory.getLogger(this.getClass()); @@ -35,6 +38,8 @@ class DatabaseQueryCountTest extends AbstractSpringIntegrationBambooBitbucketJir void setup() { participantScoreScheduleService.shutdown(); userUtilService.addUsers(TEST_PREFIX, 1, NUMBER_OF_TUTORS, 0, 0); + User student = userUtilService.getUserByLogin(TEST_PREFIX + "student1"); + student.setGroups(Set.of(TEST_PREFIX + "tumuser")); } @Test diff --git a/src/test/java/de/tum/in/www1/artemis/FileIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/FileIntegrationTest.java index 7bb99c70f786..ab1cef3d3679 100644 --- a/src/test/java/de/tum/in/www1/artemis/FileIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/FileIntegrationTest.java @@ -41,7 +41,7 @@ import de.tum.in.www1.artemis.repository.*; import de.tum.in.www1.artemis.user.UserUtilService; -class FileIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class FileIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "fileintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/GuidedTourSettingResourceTest.java b/src/test/java/de/tum/in/www1/artemis/GuidedTourSettingResourceTest.java index d7caee4aafc1..38c70b38b40a 100644 --- a/src/test/java/de/tum/in/www1/artemis/GuidedTourSettingResourceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/GuidedTourSettingResourceTest.java @@ -15,7 +15,7 @@ import de.tum.in.www1.artemis.domain.User; import de.tum.in.www1.artemis.user.UserUtilService; -class GuidedTourSettingResourceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class GuidedTourSettingResourceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "gtsettingtest"; diff --git a/src/test/java/de/tum/in/www1/artemis/ImprintResourceIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/ImprintResourceIntegrationTest.java index be24ac89805a..bca382ba465c 100644 --- a/src/test/java/de/tum/in/www1/artemis/ImprintResourceIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/ImprintResourceIntegrationTest.java @@ -2,7 +2,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.argThat; import static org.mockito.Mockito.mockStatic; import java.io.IOException; @@ -22,7 +21,7 @@ import de.tum.in.www1.artemis.domain.enumeration.Language; import net.minidev.json.JSONObject; -class ImprintResourceIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ImprintResourceIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "ir"; // only lower case is supported diff --git a/src/test/java/de/tum/in/www1/artemis/LogResourceIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/LogResourceIntegrationTest.java index 9499fcfd370f..0a324351bdd3 100644 --- a/src/test/java/de/tum/in/www1/artemis/LogResourceIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/LogResourceIntegrationTest.java @@ -10,7 +10,7 @@ import de.tum.in.www1.artemis.web.rest.vm.LoggerVM; -class LogResourceIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class LogResourceIntegrationTest extends AbstractSpringIntegrationIndependentTest { @Test @WithMockUser(roles = "ADMIN") diff --git a/src/test/java/de/tum/in/www1/artemis/LongFeedbackResourceIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/LongFeedbackResourceIntegrationTest.java index ba7f057256e7..fcea52814b21 100644 --- a/src/test/java/de/tum/in/www1/artemis/LongFeedbackResourceIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/LongFeedbackResourceIntegrationTest.java @@ -15,7 +15,7 @@ import de.tum.in.www1.artemis.participation.ParticipationUtilService; import de.tum.in.www1.artemis.user.UserUtilService; -class LongFeedbackResourceIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class LongFeedbackResourceIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "longfeedbackintegration"; @@ -49,7 +49,7 @@ void getLongFeedbackAsStudent() throws Exception { final Feedback feedback = addLongFeedbackToResult(resultStudent1); final LongFeedbackText longFeedbackText = request.get(getUrl(resultStudent1.getId(), feedback.getId()), HttpStatus.OK, LongFeedbackText.class); - assertThat(longFeedbackText.getId()).isEqualTo(feedback.getId()); + assertThat(longFeedbackText.getFeedback().getId()).isEqualTo(feedback.getId()); } @Test @@ -58,7 +58,7 @@ void getLongFeedbackAsTutor() throws Exception { final Feedback feedback = addLongFeedbackToResult(resultStudent1); final LongFeedbackText longFeedbackText = request.get(getUrl(resultStudent1.getId(), feedback.getId()), HttpStatus.OK, LongFeedbackText.class); - assertThat(longFeedbackText.getId()).isEqualTo(feedback.getId()); + assertThat(longFeedbackText.getFeedback().getId()).isEqualTo(feedback.getId()); } @Test diff --git a/src/test/java/de/tum/in/www1/artemis/Lti13LaunchIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/Lti13LaunchIntegrationTest.java index 0a8cedd60144..03c497955843 100644 --- a/src/test/java/de/tum/in/www1/artemis/Lti13LaunchIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/Lti13LaunchIntegrationTest.java @@ -37,7 +37,7 @@ * see LTI message general details * see OpenId Connect launch flow */ -class Lti13LaunchIntegrationTest extends AbstractSpringIntegrationJenkinsGitlabTest { +class Lti13LaunchIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final Key SIGNING_KEY = new SecretKeySpec("a".repeat(100).getBytes(), SignatureAlgorithm.HS256.getJcaName()); diff --git a/src/test/java/de/tum/in/www1/artemis/OAuth2JWKSIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/OAuth2JWKSIntegrationTest.java index 3a27ad298350..9fa488862cd8 100644 --- a/src/test/java/de/tum/in/www1/artemis/OAuth2JWKSIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/OAuth2JWKSIntegrationTest.java @@ -18,7 +18,7 @@ import de.tum.in.www1.artemis.repository.OnlineCourseConfigurationRepository; import de.tum.in.www1.artemis.security.OAuth2JWKSService; -class OAuth2JWKSIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class OAuth2JWKSIntegrationTest extends AbstractSpringIntegrationIndependentTest { @Autowired private CourseRepository courseRepository; diff --git a/src/test/java/de/tum/in/www1/artemis/PrivacyStatementResourceIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/PrivacyStatementResourceIntegrationTest.java index a5418e0cdfab..8bb40f27e639 100644 --- a/src/test/java/de/tum/in/www1/artemis/PrivacyStatementResourceIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/PrivacyStatementResourceIntegrationTest.java @@ -21,7 +21,7 @@ import de.tum.in.www1.artemis.domain.enumeration.Language; import net.minidev.json.JSONObject; -class PrivacyStatementResourceIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class PrivacyStatementResourceIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "psr"; // only lower case is supported diff --git a/src/test/java/de/tum/in/www1/artemis/StatisticsIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/StatisticsIntegrationTest.java index 05565d100a63..185e049968f1 100644 --- a/src/test/java/de/tum/in/www1/artemis/StatisticsIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/StatisticsIntegrationTest.java @@ -46,7 +46,7 @@ import de.tum.in.www1.artemis.web.rest.dto.CourseManagementStatisticsDTO; import de.tum.in.www1.artemis.web.rest.dto.ExerciseManagementStatisticsDTO; -class StatisticsIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class StatisticsIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "statisticsintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/assessment/AssessmentComplaintIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/assessment/AssessmentComplaintIntegrationTest.java index 131f6742512c..1e9595153988 100644 --- a/src/test/java/de/tum/in/www1/artemis/assessment/AssessmentComplaintIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/assessment/AssessmentComplaintIntegrationTest.java @@ -16,7 +16,7 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.util.LinkedMultiValueMap; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.AssessmentType; @@ -40,7 +40,7 @@ import de.tum.in.www1.artemis.util.FileUtils; import de.tum.in.www1.artemis.web.rest.dto.SubmissionWithComplaintDTO; -class AssessmentComplaintIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class AssessmentComplaintIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "assessmentcomplaintintegration"; @@ -364,8 +364,12 @@ void submitComplaintResponse_examExercise() throws Exception { complaintResponse.setResponseText("abcdefghijklmnopqrstuvwxyz"); request.putWithResponseBody("/api/complaint-responses/complaint/" + examExerciseComplaint.getId() + "/resolve", complaintResponse, ComplaintResponse.class, HttpStatus.OK); - TextSubmission finalTextSubmission = textSubmission; - await().untilAsserted(() -> assertThat(complaintRepo.findByResultId(finalTextSubmission.getId())).isPresent()); + + assertThat(textSubmission.getLatestResult()).isNotNull(); + assertThat(complaintRepo.findByResultId(textSubmission.getLatestResult().getId())).isPresent(); + + Complaint finalExamExerciseComplaint = examExerciseComplaint; + await().untilAsserted(() -> assertThat(complaintResponseRepo.findByComplaint_Id(finalExamExerciseComplaint.getId())).isPresent()); } @Test diff --git a/src/test/java/de/tum/in/www1/artemis/assessment/AssessmentTeamComplaintIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/assessment/AssessmentTeamComplaintIntegrationTest.java index eb411380c3d9..4a482f1c05ac 100644 --- a/src/test/java/de/tum/in/www1/artemis/assessment/AssessmentTeamComplaintIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/assessment/AssessmentTeamComplaintIntegrationTest.java @@ -13,7 +13,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.ComplaintType; import de.tum.in.www1.artemis.domain.enumeration.ExerciseMode; @@ -30,7 +30,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.util.FileUtils; -class AssessmentTeamComplaintIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class AssessmentTeamComplaintIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "assmentteamcomplaint"; // only lower case is supported diff --git a/src/test/java/de/tum/in/www1/artemis/assessment/ComplaintResponseIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/assessment/ComplaintResponseIntegrationTest.java index c9e9d7d90b46..73ea06bc48b2 100644 --- a/src/test/java/de/tum/in/www1/artemis/assessment/ComplaintResponseIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/assessment/ComplaintResponseIntegrationTest.java @@ -14,7 +14,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.config.Constants; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; @@ -27,7 +27,7 @@ import de.tum.in.www1.artemis.service.ParticipationService; import de.tum.in.www1.artemis.user.UserUtilService; -class ComplaintResponseIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ComplaintResponseIntegrationTest extends AbstractSpringIntegrationIndependentTest { private final Logger log = LoggerFactory.getLogger(ComplaintResponseIntegrationTest.class); diff --git a/src/test/java/de/tum/in/www1/artemis/assessment/ExampleSubmissionIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/assessment/ExampleSubmissionIntegrationTest.java index 739677d584c0..406e25f51e81 100644 --- a/src/test/java/de/tum/in/www1/artemis/assessment/ExampleSubmissionIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/assessment/ExampleSubmissionIntegrationTest.java @@ -15,7 +15,7 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.util.LinkedMultiValueMap; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.AssessmentType; @@ -34,7 +34,7 @@ import de.tum.in.www1.artemis.util.FileUtils; import de.tum.in.www1.artemis.web.rest.dto.TextAssessmentDTO; -class ExampleSubmissionIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ExampleSubmissionIntegrationTest extends AbstractSpringIntegrationIndependentTest { private final Logger log = LoggerFactory.getLogger(ExampleSubmissionIntegrationTest.class); diff --git a/src/test/java/de/tum/in/www1/artemis/assessment/ExerciseScoresChartIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/assessment/ExerciseScoresChartIntegrationTest.java index e5335333637f..b9c1839d4d05 100644 --- a/src/test/java/de/tum/in/www1/artemis/assessment/ExerciseScoresChartIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/assessment/ExerciseScoresChartIntegrationTest.java @@ -14,18 +14,20 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.exercise.textexercise.TextExerciseUtilService; import de.tum.in.www1.artemis.participation.ParticipationUtilService; -import de.tum.in.www1.artemis.repository.*; +import de.tum.in.www1.artemis.repository.ParticipantScoreRepository; +import de.tum.in.www1.artemis.repository.TeamRepository; +import de.tum.in.www1.artemis.repository.UserRepository; import de.tum.in.www1.artemis.service.scheduled.ParticipantScoreScheduleService; import de.tum.in.www1.artemis.team.TeamUtilService; import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.web.rest.dto.ExerciseScoresDTO; -class ExerciseScoresChartIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ExerciseScoresChartIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "exercisescoreschart"; @@ -111,6 +113,7 @@ void setupTestScenario() { participationUtilService.createParticipationSubmissionAndResult(idOfTeamTextExercise, team2, 10.0, 10.0, 90, true); participantScoreScheduleService.executeScheduledTasks(); + await().until(participantScoreScheduleService::isIdle); await().until(() -> participantScoreRepository.findAllByExercise(textExercise).size() == 3); await().until(() -> participantScoreRepository.findAllByExercise(teamExercise).size() == 2); } diff --git a/src/test/java/de/tum/in/www1/artemis/assessment/GradeStepIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/assessment/GradeStepIntegrationTest.java index a2afe884c270..d3e45e4736a4 100644 --- a/src/test/java/de/tum/in/www1/artemis/assessment/GradeStepIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/assessment/GradeStepIntegrationTest.java @@ -12,7 +12,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.exam.Exam; @@ -29,7 +29,7 @@ import de.tum.in.www1.artemis.web.rest.dto.GradeDTO; import de.tum.in.www1.artemis.web.rest.dto.GradeStepsDTO; -class GradeStepIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class GradeStepIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "gradestep"; diff --git a/src/test/java/de/tum/in/www1/artemis/assessment/GradingScaleIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/assessment/GradingScaleIntegrationTest.java index 474f5d38546c..dc857b4506d2 100644 --- a/src/test/java/de/tum/in/www1/artemis/assessment/GradingScaleIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/assessment/GradingScaleIntegrationTest.java @@ -12,7 +12,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.GradeStep; @@ -28,7 +28,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.util.PageableSearchUtilService; -class GradingScaleIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class GradingScaleIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "gradingscale"; diff --git a/src/test/java/de/tum/in/www1/artemis/assessment/ParticipantScoreIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/assessment/ParticipantScoreIntegrationTest.java index c66ab688cdf8..86bb975e28b9 100644 --- a/src/test/java/de/tum/in/www1/artemis/assessment/ParticipantScoreIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/assessment/ParticipantScoreIntegrationTest.java @@ -14,7 +14,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationLocalCILocalVCTest; import de.tum.in.www1.artemis.competency.CompetencyUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.exam.Exam; @@ -30,7 +30,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.web.rest.dto.ScoreDTO; -class ParticipantScoreIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ParticipantScoreIntegrationTest extends AbstractSpringIntegrationLocalCILocalVCTest { private static final String TEST_PREFIX = "participantscoreintegrationtest"; @@ -137,6 +137,8 @@ void setupTestScenario() { long getIdOfIndividualTextExerciseOfExam = examTextExercise.getId(); participationUtilService.createParticipationSubmissionAndResult(getIdOfIndividualTextExerciseOfExam, student1, 10.0, 10.0, 50, true); + participantScoreScheduleService.executeScheduledTasks(); + await().until(participantScoreScheduleService::isIdle); await().until(() -> participantScoreRepository.findAllByExercise(textExercise).size() == 1); await().until(() -> participantScoreRepository.findAllByExercise(teamExercise).size() == 1); await().until(() -> participantScoreRepository.findAllByExercise(examTextExercise).size() == 1); diff --git a/src/test/java/de/tum/in/www1/artemis/assessment/RatingResourceIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/assessment/RatingResourceIntegrationTest.java index 9ff42e2be9f9..6c200b0e88ef 100644 --- a/src/test/java/de/tum/in/www1/artemis/assessment/RatingResourceIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/assessment/RatingResourceIntegrationTest.java @@ -11,7 +11,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.Language; import de.tum.in.www1.artemis.exercise.ExerciseUtilService; @@ -22,7 +22,7 @@ import de.tum.in.www1.artemis.service.RatingService; import de.tum.in.www1.artemis.user.UserUtilService; -class RatingResourceIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class RatingResourceIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "ratingresourceintegrationtest"; // only lower case is supported diff --git a/src/test/java/de/tum/in/www1/artemis/assessment/TutorEffortIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/assessment/TutorEffortIntegrationTest.java index 7d7bf44213ba..7e31bbae4836 100644 --- a/src/test/java/de/tum/in/www1/artemis/assessment/TutorEffortIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/assessment/TutorEffortIntegrationTest.java @@ -13,7 +13,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.Exercise; @@ -28,7 +28,7 @@ import de.tum.in.www1.artemis.repository.UserRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class TutorEffortIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class TutorEffortIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "tutoreffort"; // only lower case is supported diff --git a/src/test/java/de/tum/in/www1/artemis/assessment/TutorLeaderboardServiceIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/assessment/TutorLeaderboardServiceIntegrationTest.java index 455499098824..c85e0eb84d29 100644 --- a/src/test/java/de/tum/in/www1/artemis/assessment/TutorLeaderboardServiceIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/assessment/TutorLeaderboardServiceIntegrationTest.java @@ -12,7 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.Exercise; import de.tum.in.www1.artemis.domain.enumeration.AssessmentType; @@ -25,7 +25,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.web.rest.dto.TutorLeaderboardDTO; -class TutorLeaderboardServiceIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class TutorLeaderboardServiceIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "tlbsitest"; // only lower case is supported diff --git a/src/test/java/de/tum/in/www1/artemis/assessment/TutorParticipationIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/assessment/TutorParticipationIntegrationTest.java index 2ae138e14657..a17159213d22 100644 --- a/src/test/java/de/tum/in/www1/artemis/assessment/TutorParticipationIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/assessment/TutorParticipationIntegrationTest.java @@ -15,7 +15,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.FeedbackType; @@ -35,7 +35,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.util.FileUtils; -class TutorParticipationIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class TutorParticipationIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "tutorparticipationintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/assessment/TutorParticipationResourceIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/assessment/TutorParticipationResourceIntegrationTest.java index 2eb4f1f47dca..42384f7bd58c 100644 --- a/src/test/java/de/tum/in/www1/artemis/assessment/TutorParticipationResourceIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/assessment/TutorParticipationResourceIntegrationTest.java @@ -10,7 +10,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.ExampleSubmission; @@ -23,7 +23,7 @@ import de.tum.in.www1.artemis.repository.TutorParticipationRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class TutorParticipationResourceIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class TutorParticipationResourceIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "tutorparticipationresource"; diff --git a/src/test/java/de/tum/in/www1/artemis/bonus/BonusIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/bonus/BonusIntegrationTest.java index 6d2a0e9fdf84..f80bc1ea4342 100644 --- a/src/test/java/de/tum/in/www1/artemis/bonus/BonusIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/bonus/BonusIntegrationTest.java @@ -14,7 +14,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.assessment.GradingScaleFactory; import de.tum.in.www1.artemis.assessment.GradingScaleUtilService; import de.tum.in.www1.artemis.course.CourseUtilService; @@ -27,7 +27,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.web.rest.dto.BonusExampleDTO; -class BonusIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class BonusIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "bonusintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/config/TopicSubscriptionInterceptorTest.java b/src/test/java/de/tum/in/www1/artemis/config/TopicSubscriptionInterceptorTest.java index 81025f1fc268..1d3c2672a013 100644 --- a/src/test/java/de/tum/in/www1/artemis/config/TopicSubscriptionInterceptorTest.java +++ b/src/test/java/de/tum/in/www1/artemis/config/TopicSubscriptionInterceptorTest.java @@ -12,14 +12,14 @@ import org.springframework.messaging.simp.stomp.StompCommand; import org.springframework.messaging.simp.stomp.StompHeaderAccessor; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.config.websocket.WebsocketConfiguration; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.exam.ExamUtilService; import de.tum.in.www1.artemis.user.UserUtilService; @SuppressWarnings("unchecked") -class TopicSubscriptionInterceptorTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class TopicSubscriptionInterceptorTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "topicsubscriptioninterceptor"; diff --git a/src/test/java/de/tum/in/www1/artemis/course/CourseTestService.java b/src/test/java/de/tum/in/www1/artemis/course/CourseTestService.java index 227b117c4034..77151499fcde 100644 --- a/src/test/java/de/tum/in/www1/artemis/course/CourseTestService.java +++ b/src/test/java/de/tum/in/www1/artemis/course/CourseTestService.java @@ -5,7 +5,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.awaitility.Awaitility.await; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.argThat; +import static org.mockito.Mockito.mockStatic; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import java.io.IOException; @@ -68,12 +69,14 @@ import de.tum.in.www1.artemis.repository.metis.conversation.ChannelRepository; import de.tum.in.www1.artemis.repository.metis.conversation.ConversationRepository; import de.tum.in.www1.artemis.security.SecurityUtils; -import de.tum.in.www1.artemis.service.*; +import de.tum.in.www1.artemis.service.FilePathService; +import de.tum.in.www1.artemis.service.ParticipationService; import de.tum.in.www1.artemis.service.dto.StudentDTO; import de.tum.in.www1.artemis.service.dto.UserDTO; import de.tum.in.www1.artemis.service.dto.UserPublicInfoDTO; import de.tum.in.www1.artemis.service.export.CourseExamExportService; import de.tum.in.www1.artemis.service.notifications.GroupNotificationService; +import de.tum.in.www1.artemis.service.scheduled.ParticipantScoreScheduleService; import de.tum.in.www1.artemis.team.TeamUtilService; import de.tum.in.www1.artemis.user.UserFactory; import de.tum.in.www1.artemis.user.UserUtilService; @@ -210,6 +213,9 @@ public class CourseTestService { @Autowired private LearningPathRepository learningPathRepository; + @Autowired + private ParticipantScoreScheduleService participantScoreScheduleService; + private static final int numberOfStudents = 8; private static final int numberOfTutors = 5; @@ -1523,8 +1529,8 @@ public void testEnrollInCourse() throws Exception { assertThat(updatedGroups).as("User is enrolled in course").contains(course1.getStudentGroupName()); List auditEvents = auditEventRepo.find("ab12cde", Instant.now().minusSeconds(20), Constants.ENROLL_IN_COURSE); - assertThat(auditEvents).as("Audit Event for course enrollment added").hasSize(1); - AuditEvent auditEvent = auditEvents.get(0); + AuditEvent auditEvent = auditEvents.stream().max(Comparator.comparing(AuditEvent::getTimestamp)).orElse(null); + assertThat(auditEvent).as("Audit Event for course enrollment added").isNotNull(); assertThat(auditEvent.getData()).as("Correct Event Data").containsEntry("course", course1.getTitle()); request.postWithResponseBody("/api/courses/" + course2.getId() + "/enroll", null, Set.class, HttpStatus.FORBIDDEN); @@ -2703,6 +2709,7 @@ public void testGetCourseManagementDetailData() throws Exception { request.putWithResponseBody("/api/participations/" + result2.getSubmission().getParticipation().getId() + "/submissions/" + result2.getSubmission().getId() + "/text-assessment-after-complaint", feedbackUpdate, Result.class, HttpStatus.OK); + await().until(participantScoreScheduleService::isIdle); TextExercise finalExercise1 = exercise1; await().until(() -> participantScoreRepository.findAllByExercise(finalExercise1).size() == 2); TextExercise finalExercise2 = exercise2; diff --git a/src/test/java/de/tum/in/www1/artemis/domain/ExerciseTest.java b/src/test/java/de/tum/in/www1/artemis/domain/ExerciseTest.java index e62051329a60..2e9c330c015c 100644 --- a/src/test/java/de/tum/in/www1/artemis/domain/ExerciseTest.java +++ b/src/test/java/de/tum/in/www1/artemis/domain/ExerciseTest.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseFactory; import de.tum.in.www1.artemis.domain.enumeration.AssessmentType; import de.tum.in.www1.artemis.domain.enumeration.DiagramType; @@ -24,7 +24,7 @@ import de.tum.in.www1.artemis.participation.ParticipationFactory; import de.tum.in.www1.artemis.service.ExerciseService; -class ExerciseTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ExerciseTest extends AbstractSpringIntegrationIndependentTest { private Course course; diff --git a/src/test/java/de/tum/in/www1/artemis/domain/ResultTest.java b/src/test/java/de/tum/in/www1/artemis/domain/ResultTest.java index 336fa73962fb..bb98e07371f7 100644 --- a/src/test/java/de/tum/in/www1/artemis/domain/ResultTest.java +++ b/src/test/java/de/tum/in/www1/artemis/domain/ResultTest.java @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.enumeration.FeedbackType; import de.tum.in.www1.artemis.domain.enumeration.Visibility; import de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation; @@ -18,7 +18,7 @@ import de.tum.in.www1.artemis.repository.ResultRepository; import de.tum.in.www1.artemis.service.AssessmentService; -class ResultTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ResultTest extends AbstractSpringIntegrationIndependentTest { Result result = new Result(); diff --git a/src/test/java/de/tum/in/www1/artemis/entitylistener/ResultListenerIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/entitylistener/ResultListenerIntegrationTest.java index fee1e001dbb4..fe602b3564b4 100644 --- a/src/test/java/de/tum/in/www1/artemis/entitylistener/ResultListenerIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/entitylistener/ResultListenerIntegrationTest.java @@ -17,7 +17,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationLocalCILocalVCTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.participation.Participant; @@ -34,7 +34,7 @@ import de.tum.in.www1.artemis.team.TeamUtilService; import de.tum.in.www1.artemis.user.UserUtilService; -class ResultListenerIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ResultListenerIntegrationTest extends AbstractSpringIntegrationLocalCILocalVCTest { private static final String TEST_PREFIX = "resultlistenerintegrationtest"; diff --git a/src/test/java/de/tum/in/www1/artemis/exam/ExamSessionIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/exam/ExamSessionIntegrationTest.java index 26df61ed14b8..f77f31d8bbf9 100644 --- a/src/test/java/de/tum/in/www1/artemis/exam/ExamSessionIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exam/ExamSessionIntegrationTest.java @@ -7,7 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.exam.Exam; @@ -18,7 +18,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import inet.ipaddr.IPAddressString; -class ExamSessionIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ExamSessionIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "examsessionintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/ExerciseIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/ExerciseIntegrationTest.java index f7db2779160a..7931609ccc71 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/ExerciseIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/ExerciseIntegrationTest.java @@ -14,7 +14,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.*; @@ -37,7 +37,7 @@ import de.tum.in.www1.artemis.web.rest.dto.StatsForDashboardDTO; import de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException; -class ExerciseIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ExerciseIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "exerciseintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/fileuploadexercise/FileUploadAssessmentIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/fileuploadexercise/FileUploadAssessmentIntegrationTest.java index b9f5e5a0071e..a50184014df5 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/fileuploadexercise/FileUploadAssessmentIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/fileuploadexercise/FileUploadAssessmentIntegrationTest.java @@ -15,7 +15,7 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.util.LinkedMultiValueMap; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.assessment.ComplaintUtilService; import de.tum.in.www1.artemis.config.Constants; import de.tum.in.www1.artemis.domain.*; @@ -35,7 +35,7 @@ import de.tum.in.www1.artemis.web.rest.dto.ResultDTO; @TestMethodOrder(MethodOrderer.OrderAnnotation.class) -class FileUploadAssessmentIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class FileUploadAssessmentIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "fileuploadassessment"; diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/fileuploadexercise/FileUploadExerciseIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/fileuploadexercise/FileUploadExerciseIntegrationTest.java index c7d9c08dcff2..6f979cbc7d97 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/fileuploadexercise/FileUploadExerciseIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/fileuploadexercise/FileUploadExerciseIntegrationTest.java @@ -16,7 +16,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.IncludedInOverallScore; @@ -35,7 +35,7 @@ import de.tum.in.www1.artemis.web.rest.dto.CourseForDashboardDTO; import de.tum.in.www1.artemis.web.rest.dto.SearchResultPageDTO; -class FileUploadExerciseIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class FileUploadExerciseIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "fileuploaderxercise"; diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/fileuploadexercise/FileUploadSubmissionIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/fileuploadexercise/FileUploadSubmissionIntegrationTest.java index 64c2dd888f98..99c5e9065fad 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/fileuploadexercise/FileUploadSubmissionIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/fileuploadexercise/FileUploadSubmissionIntegrationTest.java @@ -18,7 +18,7 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.util.LinkedMultiValueMap; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.config.Constants; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.InitializationState; @@ -36,7 +36,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException; -class FileUploadSubmissionIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class FileUploadSubmissionIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "fileuploadsubmission"; diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/modelingexercise/ApollonDiagramResourceIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/modelingexercise/ApollonDiagramResourceIntegrationTest.java index 8b0bb122ad28..1f707aa15233 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/modelingexercise/ApollonDiagramResourceIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/modelingexercise/ApollonDiagramResourceIntegrationTest.java @@ -13,7 +13,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseFactory; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.enumeration.DiagramType; @@ -22,7 +22,7 @@ import de.tum.in.www1.artemis.repository.CourseRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class ApollonDiagramResourceIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ApollonDiagramResourceIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "repositoryintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/modelingexercise/ModelingAssessmentIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/modelingexercise/ModelingAssessmentIntegrationTest.java index 57996459c6dd..4fb60c5b33c4 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/modelingexercise/ModelingAssessmentIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/modelingexercise/ModelingAssessmentIntegrationTest.java @@ -15,7 +15,7 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.util.LinkedMultiValueMap; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationLocalCILocalVCTest; import de.tum.in.www1.artemis.config.Constants; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.*; @@ -41,7 +41,7 @@ import de.tum.in.www1.artemis.util.FileUtils; import de.tum.in.www1.artemis.web.rest.dto.ResultDTO; -class ModelingAssessmentIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ModelingAssessmentIntegrationTest extends AbstractSpringIntegrationLocalCILocalVCTest { private static final String TEST_PREFIX = "modelingassessment"; diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/modelingexercise/ModelingExerciseIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/modelingexercise/ModelingExerciseIntegrationTest.java index 1f49d93c02fd..f58bd0ab3cc8 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/modelingexercise/ModelingExerciseIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/modelingexercise/ModelingExerciseIntegrationTest.java @@ -18,7 +18,7 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.util.LinkedMultiValueMap; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationLocalCILocalVCTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.*; @@ -39,7 +39,7 @@ import de.tum.in.www1.artemis.util.InvalidExamExerciseDatesArgumentProvider.InvalidExamExerciseDateConfiguration; import de.tum.in.www1.artemis.web.rest.dto.CourseForDashboardDTO; -class ModelingExerciseIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ModelingExerciseIntegrationTest extends AbstractSpringIntegrationLocalCILocalVCTest { private static final String TEST_PREFIX = "modelingexerciseintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/modelingexercise/ModelingSubmissionIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/modelingexercise/ModelingSubmissionIntegrationTest.java index e7770a975fb0..5b6ec29e766d 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/modelingexercise/ModelingSubmissionIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/modelingexercise/ModelingSubmissionIntegrationTest.java @@ -17,7 +17,7 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.util.LinkedMultiValueMap; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationLocalCILocalVCTest; import de.tum.in.www1.artemis.config.Constants; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.DiagramType; @@ -47,7 +47,7 @@ import de.tum.in.www1.artemis.util.FileUtils; import de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException; -class ModelingSubmissionIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ModelingSubmissionIntegrationTest extends AbstractSpringIntegrationLocalCILocalVCTest { private static final String TEST_PREFIX = "modelingsubmissionintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/GitServiceTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/GitServiceTest.java index a8f4cd3eb5e6..a8953ef58b6f 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/GitServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/GitServiceTest.java @@ -26,13 +26,13 @@ import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.File; import de.tum.in.www1.artemis.domain.FileType; import de.tum.in.www1.artemis.domain.Repository; import de.tum.in.www1.artemis.util.GitUtilService; -class GitServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class GitServiceTest extends AbstractSpringIntegrationIndependentTest { @Autowired private GitUtilService gitUtilService; diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/PlantUmlIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/PlantUmlIntegrationTest.java index a30be74d26df..29e7fb51be26 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/PlantUmlIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/PlantUmlIntegrationTest.java @@ -19,12 +19,12 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.util.LinkedMultiValueMap; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.user.UserUtilService; import net.sourceforge.plantuml.SourceStringReader; import net.sourceforge.plantuml.core.DiagramDescription; -class PlantUmlIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class PlantUmlIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "plantumlintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingAssessmentIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingAssessmentIntegrationTest.java index 74b3eec32ed4..3db8760bc506 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingAssessmentIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingAssessmentIntegrationTest.java @@ -19,7 +19,7 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.util.LinkedMultiValueMap; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.assessment.ComplaintUtilService; import de.tum.in.www1.artemis.config.Constants; import de.tum.in.www1.artemis.domain.*; @@ -37,7 +37,7 @@ import de.tum.in.www1.artemis.util.FileUtils; import de.tum.in.www1.artemis.web.rest.dto.ResultDTO; -class ProgrammingAssessmentIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ProgrammingAssessmentIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "programmingassessment"; diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseGitIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseGitIntegrationTest.java index 745852518f42..334b336cd6ea 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseGitIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseGitIntegrationTest.java @@ -22,7 +22,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.ProgrammingExercise; import de.tum.in.www1.artemis.domain.VcsRepositoryUrl; import de.tum.in.www1.artemis.exercise.ExerciseUtilService; @@ -35,7 +35,7 @@ import de.tum.in.www1.artemis.web.rest.ProgrammingExerciseResourceEndpoints; import de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException; -class ProgrammingExerciseGitIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ProgrammingExerciseGitIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "progexgitintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseGradingServiceTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseGradingServiceTest.java index 88dc5b760cc3..75b5a615da1c 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseGradingServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseGradingServiceTest.java @@ -3,6 +3,8 @@ import static de.tum.in.www1.artemis.config.Constants.TEST_CASES_DUPLICATE_NOTIFICATION; import static de.tum.in.www1.artemis.web.rest.ProgrammingExerciseResourceEndpoints.ROOT; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; import java.time.ZonedDateTime; @@ -10,6 +12,8 @@ import java.util.function.Function; import java.util.stream.Collectors; +import javax.mail.internet.MimeMessage; + import org.assertj.core.data.Offset; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -30,10 +34,7 @@ import de.tum.in.www1.artemis.domain.enumeration.Visibility; import de.tum.in.www1.artemis.domain.exam.Exam; import de.tum.in.www1.artemis.domain.exam.ExerciseGroup; -import de.tum.in.www1.artemis.domain.participation.Participation; -import de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation; -import de.tum.in.www1.artemis.domain.participation.SolutionProgrammingExerciseParticipation; -import de.tum.in.www1.artemis.domain.participation.StudentParticipation; +import de.tum.in.www1.artemis.domain.participation.*; import de.tum.in.www1.artemis.exam.ExamUtilService; import de.tum.in.www1.artemis.exercise.ExerciseUtilService; import de.tum.in.www1.artemis.participation.ParticipationUtilService; @@ -257,6 +258,7 @@ void shouldAddFeedbackForDuplicateTestCases() { assertThat(result.getFeedbacks()).hasSize(countOfNewFeedbacks); String notificationText = TEST_CASES_DUPLICATE_NOTIFICATION + "test3, test1"; verify(groupNotificationService).notifyEditorAndInstructorGroupAboutDuplicateTestCasesForExercise(programmingExercise, notificationText); + verify(javaMailSender, timeout(4000)).send(any(MimeMessage.class)); } @Test diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseIntegrationTestService.java b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseIntegrationTestService.java index 7e9657f3c7fc..70b9c8fd60ef 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseIntegrationTestService.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseIntegrationTestService.java @@ -1633,12 +1633,13 @@ void lockAllRepositories() throws Exception { verify(versionControlService, timeout(300)).setRepositoryPermissionsToReadOnly(participation2.getVcsRepositoryUrl(), programmingExercise.getProjectKey(), participation2.getStudents()); - userUtilService.changeUser(userPrefix + "instructor1"); - - var notifications = request.getList("/api/notifications", HttpStatus.OK, Notification.class); - assertThat(notifications).as("Instructor get notified that lock operations were successful") - .anyMatch(n -> n.getText().contains(Constants.PROGRAMMING_EXERCISE_SUCCESSFUL_LOCK_OPERATION_NOTIFICATION)) - .noneMatch(n -> n.getText().contains(Constants.PROGRAMMING_EXERCISE_FAILED_LOCK_OPERATIONS_NOTIFICATION)); + await().untilAsserted(() -> { + userUtilService.changeUser(userPrefix + "instructor1"); + var notifications = request.getList("/api/notifications", HttpStatus.OK, Notification.class); + assertThat(notifications).as("Instructor get notified that lock operations were successful") + .anyMatch(n -> n.getText().contains(Constants.PROGRAMMING_EXERCISE_SUCCESSFUL_LOCK_OPERATION_NOTIFICATION)) + .noneMatch(n -> n.getText().contains(Constants.PROGRAMMING_EXERCISE_FAILED_LOCK_OPERATIONS_NOTIFICATION)); + }); } void unlockAllRepositories_asStudent_forbidden() throws Exception { diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseParticipationIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseParticipationIntegrationTest.java index 79ebb1edaadf..0d91f8e94c74 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseParticipationIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseParticipationIntegrationTest.java @@ -20,7 +20,7 @@ import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.AssessmentType; import de.tum.in.www1.artemis.domain.participation.*; @@ -29,7 +29,7 @@ import de.tum.in.www1.artemis.repository.*; import de.tum.in.www1.artemis.user.UserUtilService; -class ProgrammingExerciseParticipationIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ProgrammingExerciseParticipationIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "programmingexerciseparticipation"; diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseRepositoryServiceTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseRepositoryServiceTest.java index 4b0711b07d34..780bf90380e5 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseRepositoryServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseRepositoryServiceTest.java @@ -8,13 +8,13 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.ProgrammingExercise; import de.tum.in.www1.artemis.exercise.ExerciseUtilService; import de.tum.in.www1.artemis.repository.ProgrammingExerciseRepository; import de.tum.in.www1.artemis.service.programming.ProgrammingExerciseRepositoryService; -class ProgrammingExerciseRepositoryServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ProgrammingExerciseRepositoryServiceTest extends AbstractSpringIntegrationIndependentTest { @Autowired private ProgrammingExerciseRepository programmingExerciseRepository; diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseScheduleServiceTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseScheduleServiceTest.java index 7570d86ff89a..6b546e374c79 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseScheduleServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseScheduleServiceTest.java @@ -1,16 +1,8 @@ package de.tum.in.www1.artemis.exercise.programmingexercise; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; - -import java.net.URISyntaxException; +import static org.mockito.Mockito.*; + import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; import java.util.List; @@ -18,6 +10,7 @@ import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.ObjectId; +import org.gitlab4j.api.GitLabApiException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -27,9 +20,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationGitlabCIGitlabSamlTest; import de.tum.in.www1.artemis.config.Constants; -import de.tum.in.www1.artemis.connector.BitbucketRequestMockProvider; import de.tum.in.www1.artemis.domain.ProgrammingExercise; import de.tum.in.www1.artemis.domain.User; import de.tum.in.www1.artemis.domain.VcsRepositoryUrl; @@ -47,7 +39,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.util.LocalRepository; -class ProgrammingExerciseScheduleServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ProgrammingExerciseScheduleServiceTest extends AbstractSpringIntegrationGitlabCIGitlabSamlTest { private static final String TEST_PREFIX = "programmingexercisescheduleservice"; @@ -63,9 +55,6 @@ class ProgrammingExerciseScheduleServiceTest extends AbstractSpringIntegrationBa @Autowired private ProgrammingExerciseTestCaseRepository programmingExerciseTestCaseRepository; - @Autowired - private BitbucketRequestMockProvider bitbucketRequestMockProvider; - @Autowired private ExamRepository examRepository; @@ -95,10 +84,14 @@ class ProgrammingExerciseScheduleServiceTest extends AbstractSpringIntegrationBa // TODO: This could be improved by e.g. manually setting the system time instead of waiting for actual time to pass. private static final long SCHEDULER_TASK_TRIGGER_DELAY_MS = 1000; + private static final long DELAY_MS = 300; + + private static final long TIMEOUT_MS = 5000; + @BeforeEach void init() throws Exception { studentRepository.configureRepos("studentLocalRepo", "studentOriginRepo"); - bitbucketRequestMockProvider.enableMockingOfRequests(true); + gitlabRequestMockProvider.enableMockingOfRequests(); doReturn(ObjectId.fromString("fffb09455885349da6e19d3ad7fd9c3404c5a0df")).when(gitService).getLastCommitHash(any()); userUtilService.addUsers(TEST_PREFIX, 3, 1, 0, 1); @@ -114,16 +107,8 @@ void init() throws Exception { @AfterEach void tearDown() throws Exception { - // not yet finished scheduled futures may otherwise affect following tests scheduleService.clearAllTasks(); - - // TODO: find a better solution in the future, because this makes the tests slower - // Some futures might already run while all tasks are cancelled. Waiting a bit makes sure the mocks are not called by the futures after the reset. - // Otherwise, the following test might fail. - Thread.sleep(500); // ok - - bambooRequestMockProvider.reset(); - bitbucketRequestMockProvider.reset(); + gitlabRequestMockProvider.reset(); studentRepository.resetLocalRepo(); } @@ -146,10 +131,10 @@ private void verifyLockStudentRepositoryAndParticipationOperation(boolean wasCal } } - private void mockStudentRepoLocks() throws URISyntaxException, GitAPIException { + private void mockStudentRepoLocks() throws GitAPIException, GitLabApiException { for (final var participation : programmingExercise.getStudentParticipations()) { - final var repositorySlug = (programmingExercise.getProjectKey() + "-" + participation.getParticipantIdentifier()).toLowerCase(); - bitbucketRequestMockProvider.mockSetRepositoryPermissionsToReadOnly(repositorySlug, programmingExercise.getProjectKey(), participation.getStudents()); + final VcsRepositoryUrl repositoryUrl = ((ProgrammingExerciseParticipation) participation).getVcsRepositoryUrl(); + gitlabRequestMockProvider.setRepositoryPermissionsToReadOnly(repositoryUrl, participation.getStudents()); doReturn(gitService.getExistingCheckedOutRepositoryByLocalPath(studentRepository.localRepoFile.toPath(), null)).when(gitService) .getOrCheckoutRepository((ProgrammingExerciseParticipation) participation); } @@ -159,84 +144,75 @@ private void mockStudentRepoLocks() throws URISyntaxException, GitAPIException { @WithMockUser(username = "admin", roles = "ADMIN") void shouldExecuteScheduledBuildAndTestAfterDueDate() throws Exception { mockStudentRepoLocks(); - final var dueDateDelayMS = 200; - programmingExercise.setDueDate(ZonedDateTime.now().plus(dueDateDelayMS / 2, ChronoUnit.MILLIS)); - programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(plusMillis(ZonedDateTime.now(), dueDateDelayMS)); - programmingExerciseRepository.save(programmingExercise); + programmingExercise.setDueDate(nowPlusMillis(DELAY_MS)); + programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(nowPlusMillis(DELAY_MS)); + programmingExerciseRepository.saveAndFlush(programmingExercise); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); // Lock student repository must be called once per participation. - verifyLockStudentRepositoryAndParticipationOperation(true, dueDateDelayMS); + verifyLockStudentRepositoryAndParticipationOperation(true, TIMEOUT_MS); // Instructor build should have been triggered. - verify(programmingTriggerService, timeout(dueDateDelayMS)).triggerInstructorBuildForExercise(programmingExercise.getId()); + verify(programmingTriggerService, timeout(TIMEOUT_MS)).triggerInstructorBuildForExercise(programmingExercise.getId()); } @Test @WithMockUser(username = "admin", roles = "ADMIN") - void shouldNotExecuteScheduledIfBuildAndTestAfterDueDateHasPassed() throws InterruptedException { + void shouldNotExecuteScheduledIfBuildAndTestAfterDueDateHasPassed() { programmingExercise.setDueDate(ZonedDateTime.now().minusHours(1L)); programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(ZonedDateTime.now().minusHours(1L)); - programmingExerciseRepository.save(programmingExercise); + programmingExerciseRepository.saveAndFlush(programmingExercise); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); - Thread.sleep(SCHEDULER_TASK_TRIGGER_DELAY_MS); // ok - // Lock student repository must not be called. - verifyLockStudentRepositoryAndParticipationOperation(false, 0); + verifyLockStudentRepositoryAndParticipationOperation(false, TIMEOUT_MS); verify(programmingTriggerService, never()).triggerInstructorBuildForExercise(programmingExercise.getId()); } @Test @WithMockUser(username = "admin", roles = "ADMIN") - void shouldNotExecuteScheduledIfBuildAndTestAfterDueDateIsNull() throws InterruptedException { + void shouldNotExecuteScheduledIfBuildAndTestAfterDueDateIsNull() { instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); - Thread.sleep(SCHEDULER_TASK_TRIGGER_DELAY_MS); // ok - - // Lock student repository must not be called. - verifyLockStudentRepositoryAndParticipationOperation(false, 0); - verify(programmingTriggerService, never()).triggerInstructorBuildForExercise(programmingExercise.getId()); + verify(programmingTriggerService, after(SCHEDULER_TASK_TRIGGER_DELAY_MS).never()).triggerInstructorBuildForExercise(programmingExercise.getId()); // Update all scores should not have been triggered. verify(programmingExerciseGradingService, never()).updateAllResults(programmingExercise); + // Lock student repository must not be called. + verifyLockStudentRepositoryAndParticipationOperation(false, 0); } @Test @WithMockUser(username = "admin", roles = "ADMIN") void shouldNotExecuteScheduledTwiceIfSameExercise() throws Exception { mockStudentRepoLocks(); - long delayMS = 200; // 200 ms. - programmingExercise.setDueDate(plusMillis(ZonedDateTime.now(), delayMS / 2)); + programmingExercise.setDueDate(nowPlusMillis(DELAY_MS)); // Setting it the first time. - programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(plusMillis(ZonedDateTime.now(), delayMS)); - programmingExercise = programmingExerciseRepository.save(programmingExercise); + programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(nowPlusMillis(DELAY_MS)); + programmingExercise = programmingExerciseRepository.saveAndFlush(programmingExercise); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); // Setting it the second time. - programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(plusMillis(ZonedDateTime.now(), delayMS * 2)); - programmingExercise = programmingExerciseRepository.save(programmingExercise); + programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(nowPlusMillis(DELAY_MS)); + programmingExercise = programmingExerciseRepository.saveAndFlush(programmingExercise); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); // Lock student repository must be called once per participation. - verifyLockStudentRepositoryAndParticipationOperation(true, delayMS * 2); - verify(programmingTriggerService, timeout(delayMS * 2)).triggerInstructorBuildForExercise(programmingExercise.getId()); + verifyLockStudentRepositoryAndParticipationOperation(true, TIMEOUT_MS); + verify(programmingTriggerService, timeout(TIMEOUT_MS)).triggerInstructorBuildForExercise(programmingExercise.getId()); } @Test @WithMockUser(username = "admin", roles = "ADMIN") - void shouldNotExecuteScheduledIfBuildAndTestAfterDueDateChangesToNull() throws InterruptedException { - long delayMS = 200; + void shouldNotExecuteScheduledIfBuildAndTestAfterDueDateChangesToNull() { // Setting it the first time. - programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(plusMillis(ZonedDateTime.now(), delayMS)); + programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(nowPlusMillis(DELAY_MS)); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); // Now setting the date to null - this must also clear the old scheduled task! programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(null); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); - Thread.sleep(delayMS + SCHEDULER_TASK_TRIGGER_DELAY_MS); // ok - + verify(programmingTriggerService, after(SCHEDULER_TASK_TRIGGER_DELAY_MS).never()).triggerInstructorBuildForExercise(programmingExercise.getId()); verifyLockStudentRepositoryAndParticipationOperation(false, 0); - verify(programmingTriggerService, never()).triggerInstructorBuildForExercise(programmingExercise.getId()); verify(programmingExerciseGradingService, never()).updateAllResults(programmingExercise); } @@ -244,55 +220,48 @@ void shouldNotExecuteScheduledIfBuildAndTestAfterDueDateChangesToNull() throws I @WithMockUser(username = "admin", roles = "ADMIN") void shouldScheduleExercisesWithBuildAndTestDateInFuture() throws Exception { mockStudentRepoLocks(); - long delayMS = 800; - programmingExercise.setDueDate(plusMillis(ZonedDateTime.now(), delayMS / 2)); - programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(plusMillis(ZonedDateTime.now(), delayMS)); - programmingExerciseRepository.save(programmingExercise); + programmingExercise.setDueDate(nowPlusMillis(DELAY_MS)); + programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(nowPlusMillis(DELAY_MS * 2)); + programmingExerciseRepository.saveAndFlush(programmingExercise); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); - verifyLockStudentRepositoryAndParticipationOperation(true, delayMS); - verify(programmingTriggerService, timeout(5000)).triggerInstructorBuildForExercise(programmingExercise.getId()); + verifyLockStudentRepositoryAndParticipationOperation(true, TIMEOUT_MS); + verify(programmingTriggerService, timeout(TIMEOUT_MS)).triggerInstructorBuildForExercise(programmingExercise.getId()); } @Test @WithMockUser(username = "admin", roles = "ADMIN") void shouldScheduleExercisesWithManualAssessment() throws Exception { mockStudentRepoLocks(); - long delayMS = 200; - programmingExercise.setDueDate(plusMillis(ZonedDateTime.now(), delayMS / 2)); + programmingExercise.setDueDate(nowPlusMillis(DELAY_MS)); programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(null); programmingExercise.setAssessmentType(AssessmentType.SEMI_AUTOMATIC); - programmingExerciseRepository.save(programmingExercise); + programmingExerciseRepository.saveAndFlush(programmingExercise); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); - Thread.sleep(delayMS + SCHEDULER_TASK_TRIGGER_DELAY_MS); // ok - - // Only lock participations - verifyLockStudentRepositoryAndParticipationOperation(true, delayMS); // but do not build all - verify(programmingTriggerService, never()).triggerInstructorBuildForExercise(programmingExercise.getId()); + verify(programmingTriggerService, after(SCHEDULER_TASK_TRIGGER_DELAY_MS).never()).triggerInstructorBuildForExercise(programmingExercise.getId()); + // Only lock participations + verifyLockStudentRepositoryAndParticipationOperation(true, TIMEOUT_MS); } @Test @WithMockUser(username = "admin", roles = "ADMIN") void shouldUpdateScoresIfHasTestsAfterDueDateAndNoBuildAfterDueDate() throws Exception { mockStudentRepoLocks(); - final var dueDateDelayMS = 500; - programmingExercise.setDueDate(ZonedDateTime.now().plus(dueDateDelayMS / 2, ChronoUnit.MILLIS)); + programmingExercise.setDueDate(nowPlusMillis(DELAY_MS)); programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(null); - programmingExerciseRepository.save(programmingExercise); + programmingExerciseRepository.saveAndFlush(programmingExercise); var testCases = programmingExerciseTestCaseRepository.findByExerciseId(programmingExercise.getId()); testCases.stream().findFirst().orElseThrow().setVisibility(Visibility.AFTER_DUE_DATE); - programmingExerciseTestCaseRepository.saveAll(testCases); + programmingExerciseTestCaseRepository.saveAllAndFlush(testCases); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); - Thread.sleep(dueDateDelayMS + SCHEDULER_TASK_TRIGGER_DELAY_MS); // ok - - verifyLockStudentRepositoryAndParticipationOperation(true, dueDateDelayMS); - verify(programmingTriggerService, never()).triggerInstructorBuildForExercise(programmingExercise.getId()); + verify(programmingTriggerService, after(SCHEDULER_TASK_TRIGGER_DELAY_MS).never()).triggerInstructorBuildForExercise(programmingExercise.getId()); + verifyLockStudentRepositoryAndParticipationOperation(true, TIMEOUT_MS); // has AFTER_DUE_DATE tests and no additional build after due date => update the scores to show those test cases in it verify(programmingExerciseGradingService, timeout(5000)).updateResultsOnlyRegularDueDateParticipations(programmingExercise); // make sure to trigger the update only for participants who do not have got an individual due date @@ -303,22 +272,19 @@ void shouldUpdateScoresIfHasTestsAfterDueDateAndNoBuildAfterDueDate() throws Exc @WithMockUser(username = "admin", roles = "ADMIN") void shouldNotUpdateScoresIfHasTestsAfterDueDateAndBuildAfterDueDate() throws Exception { mockStudentRepoLocks(); - final var dueDateDelayMS = 500; - programmingExercise.setDueDate(ZonedDateTime.now().plus(dueDateDelayMS / 2, ChronoUnit.MILLIS)); - programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(plusMillis(ZonedDateTime.now(), dueDateDelayMS)); - programmingExerciseRepository.save(programmingExercise); + programmingExercise.setDueDate(nowPlusMillis(DELAY_MS)); + programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(nowPlusMillis(DELAY_MS * 2)); + programmingExerciseRepository.saveAndFlush(programmingExercise); var testCases = programmingExerciseTestCaseRepository.findByExerciseId(programmingExercise.getId()); testCases.stream().findFirst().orElseThrow().setVisibility(Visibility.AFTER_DUE_DATE); - programmingExerciseTestCaseRepository.saveAll(testCases); + programmingExerciseTestCaseRepository.saveAllAndFlush(testCases); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); - Thread.sleep(dueDateDelayMS + SCHEDULER_TASK_TRIGGER_DELAY_MS); // ok - - verifyLockStudentRepositoryAndParticipationOperation(true, dueDateDelayMS / 2); - verify(programmingTriggerService, timeout(dueDateDelayMS)).triggerInstructorBuildForExercise(programmingExercise.getId()); // has AFTER_DUE_DATE tests, but also buildAfterDueDate => do not update results, but use the results created on additional build run - verify(programmingExerciseGradingService, never()).updateAllResults(programmingExercise); + verify(programmingExerciseGradingService, after(SCHEDULER_TASK_TRIGGER_DELAY_MS).never()).updateAllResults(programmingExercise); + verifyLockStudentRepositoryAndParticipationOperation(true, TIMEOUT_MS); + verify(programmingTriggerService, timeout(TIMEOUT_MS)).triggerInstructorBuildForExercise(programmingExercise.getId()); } @ParameterizedTest(name = "{displayName} [{index}] {argumentsWithNames}") @@ -326,32 +292,29 @@ void shouldNotUpdateScoresIfHasTestsAfterDueDateAndBuildAfterDueDate() throws Ex @WithMockUser(username = "admin", roles = "ADMIN") void shouldNotUpdateScoresIfHasNoTestsAfterDueDate(boolean hasBuildAndTestAfterDueDate) throws Exception { mockStudentRepoLocks(); - final var dueDateDelayMS = 200; - programmingExercise.setDueDate(ZonedDateTime.now().plus(dueDateDelayMS / 2, ChronoUnit.MILLIS)); + programmingExercise.setDueDate(nowPlusMillis(DELAY_MS)); if (hasBuildAndTestAfterDueDate) { - programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(plusMillis(ZonedDateTime.now(), dueDateDelayMS)); + programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(nowPlusMillis(DELAY_MS * 2)); } else { programmingExercise.setBuildAndTestStudentSubmissionsAfterDueDate(null); } - programmingExerciseRepository.save(programmingExercise); + programmingExerciseRepository.saveAndFlush(programmingExercise); var testCases = programmingExerciseTestCaseRepository.findByExerciseId(programmingExercise.getId()); testCases.forEach(testCase -> testCase.setVisibility(Visibility.ALWAYS)); - programmingExerciseTestCaseRepository.saveAll(testCases); + programmingExerciseTestCaseRepository.saveAllAndFlush(testCases); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); - Thread.sleep(dueDateDelayMS + SCHEDULER_TASK_TRIGGER_DELAY_MS); // ok - - verifyLockStudentRepositoryAndParticipationOperation(true, dueDateDelayMS / 2); + // no tests marked as AFTER_DUE_DATE => do not update scores on due date + verify(programmingExerciseGradingService, after(SCHEDULER_TASK_TRIGGER_DELAY_MS).never()).updateAllResults(programmingExercise); + verifyLockStudentRepositoryAndParticipationOperation(true, TIMEOUT_MS); if (hasBuildAndTestAfterDueDate) { - verify(programmingTriggerService, timeout(dueDateDelayMS)).triggerInstructorBuildForExercise(programmingExercise.getId()); + verify(programmingTriggerService, timeout(TIMEOUT_MS)).triggerInstructorBuildForExercise(programmingExercise.getId()); } else { verify(programmingTriggerService, never()).triggerInstructorBuildForExercise(programmingExercise.getId()); } - // no tests marked as AFTER_DUE_DATE => do not update scores on due date - verify(programmingExerciseGradingService, never()).updateAllResults(programmingExercise); } @Test @@ -361,23 +324,22 @@ void testCombineTemplateBeforeRelease() throws Exception { VcsRepositoryUrl repositoryUrl = programmingExerciseWithTemplate.getVcsTemplateRepositoryUrl(); doNothing().when(gitService).combineAllCommitsOfRepositoryIntoOne(repositoryUrl); - programmingExercise.setReleaseDate(ZonedDateTime.now().plusSeconds(Constants.SECONDS_BEFORE_RELEASE_DATE_FOR_COMBINING_TEMPLATE_COMMITS + 1)); - programmingExerciseRepository.save(programmingExercise); + programmingExercise.setReleaseDate(nowPlusMillis(DELAY_MS).plusSeconds(Constants.SECONDS_BEFORE_RELEASE_DATE_FOR_COMBINING_TEMPLATE_COMMITS)); + programmingExerciseRepository.saveAndFlush(programmingExercise); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); - verify(gitService, timeout(5000)).combineAllCommitsOfRepositoryIntoOne(repositoryUrl); + verify(gitService, timeout(TIMEOUT_MS)).combineAllCommitsOfRepositoryIntoOne(repositoryUrl); } @Test @WithMockUser(username = "admin", roles = "ADMIN") void scheduleIndividualDueDateNoBuildAndTestDateLock() throws Exception { mockStudentRepoLocks(); - final long delayMS = 400; final ZonedDateTime now = ZonedDateTime.now(); - setupProgrammingExerciseDates(now, delayMS / 2, null); + setupProgrammingExerciseDates(now, DELAY_MS, null); var login = TEST_PREFIX + "student3"; - var participationIndividualDueDate = setupParticipationIndividualDueDate(now, 3 * delayMS + SCHEDULER_TASK_TRIGGER_DELAY_MS, login); + var participationIndividualDueDate = setupParticipationIndividualDueDate(now, DELAY_MS * 2 + SCHEDULER_TASK_TRIGGER_DELAY_MS, login); programmingExercise = programmingExerciseRepository.findWithAllParticipationsById(programmingExercise.getId()).orElseThrow(); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); @@ -390,88 +352,80 @@ void scheduleIndividualDueDateNoBuildAndTestDateLock() throws Exception { assertThat(studentParticipationIndividualDueDate.getIndividualDueDate()).isNotEqualTo(programmingExercise.getDueDate()); // the repo-lock for the participation with a later due date should only have been called after that individual due date has passed - verifyLockStudentRepositoryAndParticipationOperation(true, studentParticipationsRegularDueDate, delayMS); + verifyLockStudentRepositoryAndParticipationOperation(true, studentParticipationsRegularDueDate, DELAY_MS * 2); // first the operation should not be called verifyLockStudentRepositoryAndParticipationOperation(false, participationIndividualDueDate, 0); // after some time the operation should be called as well (verify waits up to 5s until this condition is fulfilled) - verifyLockStudentRepositoryAndParticipationOperation(true, participationIndividualDueDate, 3 * delayMS + SCHEDULER_TASK_TRIGGER_DELAY_MS); + verifyLockStudentRepositoryAndParticipationOperation(true, participationIndividualDueDate, TIMEOUT_MS); } @Test @WithMockUser(username = "admin", roles = "ADMIN") void scheduleIndividualDueDateBetweenDueDateAndBuildAndTestDate() throws Exception { - bitbucketRequestMockProvider.reset(); mockStudentRepoLocks(); - final long delayMS = 200; final ZonedDateTime now = ZonedDateTime.now(); - setupProgrammingExerciseDates(now, delayMS / 2, 2 * SCHEDULER_TASK_TRIGGER_DELAY_MS); + setupProgrammingExerciseDates(now, DELAY_MS, 2 * SCHEDULER_TASK_TRIGGER_DELAY_MS); // individual due date between regular due date and build and test date - var participationIndividualDueDate = setupParticipationIndividualDueDate(now, 2 * delayMS + SCHEDULER_TASK_TRIGGER_DELAY_MS, TEST_PREFIX + "student3"); + var participationIndividualDueDate = setupParticipationIndividualDueDate(now, DELAY_MS * 2 + SCHEDULER_TASK_TRIGGER_DELAY_MS, TEST_PREFIX + "student3"); programmingExercise = programmingExerciseRepository.findWithAllParticipationsById(programmingExercise.getId()).orElseThrow(); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); - verify(scheduleService, timeout(5000)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); + verify(scheduleService, timeout(DELAY_MS * 2)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); verify(scheduleService, never()).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE), any()); - Thread.sleep(delayMS + SCHEDULER_TASK_TRIGGER_DELAY_MS); // ok - // not yet locked on regular due date + verify(programmingTriggerService, after(DELAY_MS * 2).never()).triggerInstructorBuildForExercise(programmingExercise.getId()); verifyLockStudentRepositoryAndParticipationOperation(false, participationIndividualDueDate, 0); - verify(programmingTriggerService, never()).triggerInstructorBuildForExercise(programmingExercise.getId()); // locked after individual due date - verifyLockStudentRepositoryAndParticipationOperation(true, participationIndividualDueDate, 2 * delayMS + SCHEDULER_TASK_TRIGGER_DELAY_MS); - - Thread.sleep(delayMS + SCHEDULER_TASK_TRIGGER_DELAY_MS); // ok + verifyLockStudentRepositoryAndParticipationOperation(true, participationIndividualDueDate, 2 * DELAY_MS + SCHEDULER_TASK_TRIGGER_DELAY_MS); // after build and test date: no individual build and test actions are scheduled - verify(programmingTriggerService, never()).triggerBuildForParticipations(List.of(participationIndividualDueDate)); - verify(programmingTriggerService, timeout(2 * SCHEDULER_TASK_TRIGGER_DELAY_MS)).triggerInstructorBuildForExercise(programmingExercise.getId()); + verify(programmingTriggerService, after(DELAY_MS + SCHEDULER_TASK_TRIGGER_DELAY_MS).never()).triggerBuildForParticipations(List.of(participationIndividualDueDate)); + verify(programmingTriggerService, timeout(TIMEOUT_MS)).triggerInstructorBuildForExercise(programmingExercise.getId()); } @Test @WithMockUser(username = "admin", roles = "ADMIN") void scheduleIndividualDueDateAfterBuildAndTestDate() throws Exception { mockStudentRepoLocks(); - final long delayMS = 200; final ZonedDateTime now = ZonedDateTime.now(); - setupProgrammingExerciseDates(now, delayMS / 2, delayMS); + setupProgrammingExerciseDates(now, DELAY_MS, DELAY_MS); // individual due date after build and test date - var participationIndividualDueDate = setupParticipationIndividualDueDate(now, 2 * delayMS, TEST_PREFIX + "student3"); + var participationIndividualDueDate = setupParticipationIndividualDueDate(now, DELAY_MS * 2, TEST_PREFIX + "student3"); programmingExercise = programmingExerciseRepository.findWithAllParticipationsById(programmingExercise.getId()).orElseThrow(); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); // special scheduling for both lock and build and test - verify(scheduleService, timeout(5000)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); - verify(scheduleService, timeout(5000)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE), any()); + verify(scheduleService, timeout(TIMEOUT_MS)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); + verify(scheduleService, timeout(TIMEOUT_MS)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE), any()); } @Test @WithMockUser(username = "admin", roles = "ADMIN") void scheduleIndividualDueDateTestsAfterDueDateNoBuildAndTestDate() throws Exception { mockStudentRepoLocks(); - final long delayMS = 500; final ZonedDateTime now = ZonedDateTime.now(); // no build and test date, but after_due_date tests ⇒ score update needed - setupProgrammingExerciseDates(now, delayMS / 2, null); + setupProgrammingExerciseDates(now, DELAY_MS, null); var testCases = programmingExerciseTestCaseRepository.findByExerciseId(programmingExercise.getId()); testCases.stream().findFirst().orElseThrow().setVisibility(Visibility.AFTER_DUE_DATE); - programmingExerciseTestCaseRepository.saveAll(testCases); + programmingExerciseTestCaseRepository.saveAllAndFlush(testCases); - var participationIndividualDueDate = setupParticipationIndividualDueDate(now, 2 * delayMS, TEST_PREFIX + "student3"); + var participationIndividualDueDate = setupParticipationIndividualDueDate(now, DELAY_MS * 2, TEST_PREFIX + "student3"); programmingExercise = programmingExerciseRepository.findWithAllParticipationsById(programmingExercise.getId()).orElseThrow(); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); - verify(scheduleService, timeout(5000)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); + verify(scheduleService, timeout(TIMEOUT_MS)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); verify(scheduleService, never()).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE), any()); - verify(scheduleService, timeout(5000)).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.DUE), any(Runnable.class)); + verify(scheduleService, timeout(TIMEOUT_MS)).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.DUE), any(Runnable.class)); verify(scheduleService, never()).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE), any(Runnable.class)); } @@ -479,39 +433,38 @@ void scheduleIndividualDueDateTestsAfterDueDateNoBuildAndTestDate() throws Excep @WithMockUser(username = "admin", roles = "ADMIN") void cancelAllSchedulesOnRemovingExerciseDueDate() throws Exception { mockStudentRepoLocks(); - final long delayMS = 500; final ZonedDateTime now = ZonedDateTime.now(); - setupProgrammingExerciseDates(now, delayMS / 2, null); + setupProgrammingExerciseDates(now, DELAY_MS, null); var testCases = programmingExerciseTestCaseRepository.findByExerciseId(programmingExercise.getId()); testCases.stream().findFirst().orElseThrow().setVisibility(Visibility.AFTER_DUE_DATE); programmingExerciseTestCaseRepository.saveAll(testCases); - var participationIndividualDueDate = setupParticipationIndividualDueDate(now, 2 * delayMS, TEST_PREFIX + "student3"); + var participationIndividualDueDate = setupParticipationIndividualDueDate(now, DELAY_MS * 2, TEST_PREFIX + "student3"); programmingExercise = programmingExerciseRepository.findWithAllParticipationsById(programmingExercise.getId()).orElseThrow(); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); - verify(scheduleService, timeout(5000)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); + verify(scheduleService, timeout(TIMEOUT_MS)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); verify(scheduleService, never()).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE), any()); - verify(scheduleService, timeout(5000)).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.DUE), any(Runnable.class)); + verify(scheduleService, timeout(TIMEOUT_MS)).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.DUE), any(Runnable.class)); verify(scheduleService, never()).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE), any(Runnable.class)); // remove due date and schedule again programmingExercise.setDueDate(null); - programmingExercise = programmingExerciseRepository.save(programmingExercise); + programmingExercise = programmingExerciseRepository.saveAndFlush(programmingExercise); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); // all schedules are cancelled InOrder cancelCalls = inOrder(scheduleService); - cancelCalls.verify(scheduleService, timeout(5000)).cancelScheduledTaskForLifecycle(programmingExercise.getId(), ExerciseLifecycle.DUE); - cancelCalls.verify(scheduleService, timeout(5000)).cancelScheduledTaskForLifecycle(programmingExercise.getId(), ExerciseLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE); + cancelCalls.verify(scheduleService, timeout(TIMEOUT_MS)).cancelScheduledTaskForLifecycle(programmingExercise.getId(), ExerciseLifecycle.DUE); + cancelCalls.verify(scheduleService, timeout(TIMEOUT_MS)).cancelScheduledTaskForLifecycle(programmingExercise.getId(), ExerciseLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE); for (final var participation : programmingExercise.getStudentParticipations()) { - cancelCalls.verify(scheduleService, timeout(5000)).cancelScheduledTaskForParticipationLifecycle(programmingExercise.getId(), participation.getId(), + cancelCalls.verify(scheduleService, timeout(TIMEOUT_MS)).cancelScheduledTaskForParticipationLifecycle(programmingExercise.getId(), participation.getId(), ParticipationLifecycle.DUE); - cancelCalls.verify(scheduleService, timeout(5000)).cancelScheduledTaskForParticipationLifecycle(programmingExercise.getId(), participation.getId(), + cancelCalls.verify(scheduleService, timeout(TIMEOUT_MS)).cancelScheduledTaskForParticipationLifecycle(programmingExercise.getId(), participation.getId(), ParticipationLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE); } } @@ -520,91 +473,88 @@ void cancelAllSchedulesOnRemovingExerciseDueDate() throws Exception { @WithMockUser(username = "admin", roles = "ADMIN") void cancelIndividualSchedulesOnRemovingIndividualDueDate() throws Exception { mockStudentRepoLocks(); - final long delayMS = 200; final ZonedDateTime now = ZonedDateTime.now(); - setupProgrammingExerciseDates(now, delayMS, null); + setupProgrammingExerciseDates(now, DELAY_MS, null); - var participationIndividualDueDate = setupParticipationIndividualDueDate(now, 2 * delayMS, TEST_PREFIX + "student3"); + var participationIndividualDueDate = setupParticipationIndividualDueDate(now, 2 * DELAY_MS, TEST_PREFIX + "student3"); programmingExercise = programmingExerciseRepository.findWithAllParticipationsById(programmingExercise.getId()).orElseThrow(); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); - verify(scheduleService, timeout(5000)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); - verify(scheduleService, timeout(5000)).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.DUE), any(Runnable.class)); + verify(scheduleService, timeout(TIMEOUT_MS)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); + verify(scheduleService, timeout(TIMEOUT_MS)).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.DUE), any(Runnable.class)); // remove individual due date and schedule again participationIndividualDueDate.setIndividualDueDate(null); - participationIndividualDueDate = participationRepository.save(participationIndividualDueDate); + participationIndividualDueDate = participationRepository.saveAndFlush(participationIndividualDueDate); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); // called twice: first time when removing potential old schedules before scheduling, second time only cancelling - verify(scheduleService, timeout(5000).times(2)).cancelScheduledTaskForParticipationLifecycle(programmingExercise.getId(), participationIndividualDueDate.getId(), + verify(scheduleService, timeout(TIMEOUT_MS).times(2)).cancelScheduledTaskForParticipationLifecycle(programmingExercise.getId(), participationIndividualDueDate.getId(), ParticipationLifecycle.DUE); - verify(scheduleService, timeout(5000)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); + verify(scheduleService, timeout(TIMEOUT_MS)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); } @Test @WithMockUser(username = "admin", roles = "ADMIN") void updateIndividualScheduleOnIndividualDueDateChange() throws Exception { mockStudentRepoLocks(); - final long delayMS = 500; final ZonedDateTime now = ZonedDateTime.now(); - setupProgrammingExerciseDates(now, delayMS / 2, null); + setupProgrammingExerciseDates(now, DELAY_MS, null); - var participationIndividualDueDate = setupParticipationIndividualDueDate(now, 2 * delayMS, TEST_PREFIX + "student3"); + var participationIndividualDueDate = setupParticipationIndividualDueDate(now, 2 * DELAY_MS, TEST_PREFIX + "student3"); programmingExercise = programmingExerciseRepository.findWithAllParticipationsById(programmingExercise.getId()).orElseThrow(); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); - verify(scheduleService, timeout(5000)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); - verify(scheduleService, timeout(5000)).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.DUE), any(Runnable.class)); + verify(scheduleService, timeout(TIMEOUT_MS)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); + verify(scheduleService, timeout(TIMEOUT_MS)).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.DUE), any(Runnable.class)); // change individual due date and schedule again - participationIndividualDueDate.setIndividualDueDate(plusMillis(now, 3 * delayMS)); - participationIndividualDueDate = participationRepository.save(participationIndividualDueDate); + participationIndividualDueDate.setIndividualDueDate(nowPlusMillis(DELAY_MS)); + participationIndividualDueDate = participationRepository.saveAndFlush(participationIndividualDueDate); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); // scheduling called twice, each scheduling cancels potential old schedules - verify(scheduleService, timeout(5000).times(2)).cancelScheduledTaskForParticipationLifecycle(programmingExercise.getId(), participationIndividualDueDate.getId(), + verify(scheduleService, timeout(TIMEOUT_MS).times(2)).cancelScheduledTaskForParticipationLifecycle(programmingExercise.getId(), participationIndividualDueDate.getId(), ParticipationLifecycle.DUE); - verify(scheduleService, timeout(5000).times(2)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); + verify(scheduleService, timeout(TIMEOUT_MS).times(2)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); } @Test @WithMockUser(username = "admin", roles = "ADMIN") void keepIndividualScheduleOnExerciseDueDateChange() throws Exception { mockStudentRepoLocks(); - final long delayMS = 500; final ZonedDateTime now = ZonedDateTime.now(); - setupProgrammingExerciseDates(now, delayMS / 2, null); + setupProgrammingExerciseDates(now, DELAY_MS, null); var testCases = programmingExerciseTestCaseRepository.findByExerciseId(programmingExercise.getId()); testCases.stream().findFirst().orElseThrow().setVisibility(Visibility.AFTER_DUE_DATE); - programmingExerciseTestCaseRepository.saveAll(testCases); + programmingExerciseTestCaseRepository.saveAllAndFlush(testCases); - var participationIndividualDueDate = setupParticipationIndividualDueDate(now, 2 * delayMS, TEST_PREFIX + "student3"); + var participationIndividualDueDate = setupParticipationIndividualDueDate(now, DELAY_MS * 2, TEST_PREFIX + "student3"); programmingExercise = programmingExerciseRepository.findWithAllParticipationsById(programmingExercise.getId()).orElseThrow(); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); - verify(scheduleService, timeout(5000)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); + verify(scheduleService, timeout(TIMEOUT_MS)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); verify(scheduleService, never()).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE), any()); - verify(scheduleService, timeout(5000)).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.DUE), any(Runnable.class)); + verify(scheduleService, timeout(TIMEOUT_MS)).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.DUE), any(Runnable.class)); verify(scheduleService, never()).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE), any(Runnable.class)); // change exercise due date and schedule again - programmingExercise.setDueDate(plusMillis(now, delayMS)); - programmingExercise = programmingExerciseRepository.save(programmingExercise); + programmingExercise.setDueDate(nowPlusMillis(DELAY_MS)); + programmingExercise = programmingExerciseRepository.saveAndFlush(programmingExercise); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); - verify(scheduleService, timeout(5000).times(2)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); + verify(scheduleService, timeout(TIMEOUT_MS).times(2)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); verify(scheduleService, never()).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE), any()); - verify(scheduleService, timeout(5000).times(2)).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.DUE), any(Runnable.class)); + verify(scheduleService, timeout(TIMEOUT_MS).times(2)).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.DUE), any(Runnable.class)); verify(scheduleService, never()).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE), any(Runnable.class)); } @@ -612,19 +562,18 @@ void keepIndividualScheduleOnExerciseDueDateChange() throws Exception { @WithMockUser(username = "admin", roles = "ADMIN") void shouldScheduleExerciseIfAnyIndividualDueDateInFuture() throws Exception { mockStudentRepoLocks(); - final long delayMS = 200; final ZonedDateTime now = ZonedDateTime.now(); - setupProgrammingExerciseDates(now, -1 * delayMS / 2, null); + setupProgrammingExerciseDates(now, -DELAY_MS, null); programmingExercise.setReleaseDate(ZonedDateTime.now().minusHours(1)); - programmingExercise = programmingExerciseRepository.save(programmingExercise); + programmingExercise = programmingExerciseRepository.saveAndFlush(programmingExercise); - var participationIndividualDueDate = setupParticipationIndividualDueDate(now, 2 * delayMS, TEST_PREFIX + "student3"); + var participationIndividualDueDate = setupParticipationIndividualDueDate(now, DELAY_MS, TEST_PREFIX + "student3"); programmingExercise = programmingExerciseRepository.findWithAllParticipationsById(programmingExercise.getId()).orElseThrow(); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); - verify(scheduleService, timeout(5000)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); + verify(scheduleService, timeout(TIMEOUT_MS)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.DUE), any()); verify(scheduleService, never()).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.DUE), any(Runnable.class)); } @@ -632,22 +581,21 @@ void shouldScheduleExerciseIfAnyIndividualDueDateInFuture() throws Exception { @WithMockUser(username = "admin", roles = "ADMIN") void shouldCancelAllTasksIfSchedulingNoLongerNeeded() throws Exception { mockStudentRepoLocks(); - final long delayMS = 200; final ZonedDateTime now = ZonedDateTime.now(); - setupProgrammingExerciseDates(now, -1 * delayMS / 2, null); + setupProgrammingExerciseDates(now, -DELAY_MS, null); programmingExercise.setReleaseDate(ZonedDateTime.now().minusHours(1)); programmingExercise.setAssessmentType(AssessmentType.AUTOMATIC); programmingExercise.setAllowComplaintsForAutomaticAssessments(false); - programmingExercise = programmingExerciseRepository.save(programmingExercise); + programmingExercise = programmingExerciseRepository.saveAndFlush(programmingExercise); instanceMessageReceiveService.processScheduleProgrammingExercise(programmingExercise.getId()); - verify(scheduleService, never()).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.DUE), any(Runnable.class)); - verify(scheduleService, timeout(5000)).cancelScheduledTaskForLifecycle(programmingExercise.getId(), ExerciseLifecycle.RELEASE); - verify(scheduleService, timeout(5000)).cancelScheduledTaskForLifecycle(programmingExercise.getId(), ExerciseLifecycle.DUE); - verify(scheduleService, timeout(5000)).cancelScheduledTaskForLifecycle(programmingExercise.getId(), ExerciseLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE); - verify(scheduleService, timeout(5000)).cancelScheduledTaskForLifecycle(programmingExercise.getId(), ExerciseLifecycle.ASSESSMENT_DUE); + verify(scheduleService, after(SCHEDULER_TASK_TRIGGER_DELAY_MS).never()).scheduleTask(eq(programmingExercise), eq(ExerciseLifecycle.DUE), any(Runnable.class)); + verify(scheduleService, timeout(TIMEOUT_MS)).cancelScheduledTaskForLifecycle(programmingExercise.getId(), ExerciseLifecycle.RELEASE); + verify(scheduleService, timeout(TIMEOUT_MS)).cancelScheduledTaskForLifecycle(programmingExercise.getId(), ExerciseLifecycle.DUE); + verify(scheduleService, timeout(TIMEOUT_MS)).cancelScheduledTaskForLifecycle(programmingExercise.getId(), ExerciseLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE); + verify(scheduleService, timeout(TIMEOUT_MS)).cancelScheduledTaskForLifecycle(programmingExercise.getId(), ExerciseLifecycle.ASSESSMENT_DUE); } @Test @@ -656,18 +604,18 @@ void testExamWorkingTimeChangeDuringConduction() { ProgrammingExercise examExercise = programmingExerciseUtilService.addCourseExamExerciseGroupWithOneProgrammingExercise(); Exam exam = examExercise.getExamViaExerciseGroupOrCourseMember(); exam.setStartDate(ZonedDateTime.now().minusMinutes(1)); - exam = examRepository.save(exam); + exam = examRepository.saveAndFlush(exam); User user = userUtilService.getUserByLogin(TEST_PREFIX + "student1"); StudentExam studentExam = examUtilService.addStudentExamWithUser(exam, user); ProgrammingExerciseStudentParticipation participation = (ProgrammingExerciseStudentParticipation) participationUtilService .addProgrammingParticipationWithResultForExercise(examExercise, TEST_PREFIX + "student1").getParticipation(); studentExam.setExercises(List.of(examExercise)); studentExam.setWorkingTime(1); - studentExamRepository.save(studentExam); + studentExamRepository.saveAndFlush(studentExam); instanceMessageReceiveService.processStudentExamIndividualWorkingTimeChangeDuringConduction(studentExam.getId()); - verify(versionControlService, timeout(200)).setRepositoryPermissionsToReadOnly(participation.getVcsRepositoryUrl(), examExercise.getProjectKey(), + verify(versionControlService, timeout(TIMEOUT_MS)).setRepositoryPermissionsToReadOnly(participation.getVcsRepositoryUrl(), examExercise.getProjectKey(), participation.getStudents()); } @@ -693,7 +641,7 @@ private void setupProgrammingExerciseDates(final ZonedDateTime reference, Long d } programmingExercise.setAssessmentType(AssessmentType.SEMI_AUTOMATIC); - programmingExercise = programmingExerciseRepository.save(programmingExercise); + programmingExercise = programmingExerciseRepository.saveAndFlush(programmingExercise); } private ProgrammingExerciseStudentParticipation setupParticipationIndividualDueDate(final ZonedDateTime reference, Long individualDueDateDelayMillis, String login) { @@ -706,7 +654,7 @@ private ProgrammingExerciseStudentParticipation setupParticipationIndividualDueD participationIndividualDueDate.setIndividualDueDate(null); } - return participationRepository.save((ProgrammingExerciseStudentParticipation) participationIndividualDueDate); + return participationRepository.saveAndFlush((ProgrammingExerciseStudentParticipation) participationIndividualDueDate); } private StudentParticipation getParticipation(String login) { @@ -721,4 +669,8 @@ private List getParticipationsWithoutIndividualDueDate() { private ZonedDateTime plusMillis(final ZonedDateTime reference, long millis) { return reference.plus(millis, ChronoUnit.MILLIS); } + + private ZonedDateTime nowPlusMillis(long millis) { + return ZonedDateTime.now().plus(millis, ChronoUnit.MILLIS); + } } diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseServiceTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseServiceTest.java index 808c63ffc237..f24dc8ec5d00 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseServiceTest.java @@ -10,14 +10,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.ProgrammingExercise; import de.tum.in.www1.artemis.exercise.ExerciseUtilService; import de.tum.in.www1.artemis.repository.ProgrammingExerciseRepository; import de.tum.in.www1.artemis.repository.ProgrammingExerciseTestRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class ProgrammingExerciseServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ProgrammingExerciseServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "progexservice"; diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseTemplateIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseTemplateIntegrationTest.java index fc84e008452e..e8d86320e8f4 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseTemplateIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseTemplateIntegrationTest.java @@ -3,7 +3,6 @@ import static de.tum.in.www1.artemis.web.rest.ProgrammingExerciseResourceEndpoints.*; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Fail.fail; -import static org.mockito.Mockito.reset; import java.io.*; import java.nio.file.Files; @@ -34,7 +33,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationJenkinsGitlabTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.ProgrammingExercise; @@ -44,7 +43,7 @@ import de.tum.in.www1.artemis.util.LocalRepository; @TestInstance(TestInstance.Lifecycle.PER_CLASS) -class ProgrammingExerciseTemplateIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ProgrammingExerciseTemplateIntegrationTest extends AbstractSpringIntegrationJenkinsGitlabTest { private final Logger log = LoggerFactory.getLogger(this.getClass()); @@ -110,8 +109,8 @@ void setup() throws Exception { programmingExerciseTestService.setupTestUsers(TEST_PREFIX, 1, 1, 0, 1); Course course = courseUtilService.addEmptyCourse(); exercise = ProgrammingExerciseFactory.generateProgrammingExercise(ZonedDateTime.now().minusDays(1), ZonedDateTime.now().plusDays(7), course); - bambooRequestMockProvider.enableMockingOfRequests(); - bitbucketRequestMockProvider.enableMockingOfRequests(true); + jenkinsRequestMockProvider.enableMockingOfRequests(jenkinsServer); + gitlabRequestMockProvider.enableMockingOfRequests(); exerciseRepo.configureRepos("exerciseLocalRepo", "exerciseOriginRepo"); testRepo.configureRepos("testLocalRepo", "testOriginRepo"); @@ -124,11 +123,9 @@ void setup() throws Exception { @AfterEach void tearDown() throws Exception { - reset(gitService); - reset(bambooServer); + jenkinsRequestMockProvider.enableMockingOfRequests(jenkinsServer); + gitlabRequestMockProvider.enableMockingOfRequests(); programmingExerciseTestService.tearDown(); - bitbucketRequestMockProvider.reset(); - bambooRequestMockProvider.reset(); exerciseRepo.resetLocalRepo(); testRepo.resetLocalRepo(); solutionRepo.resetLocalRepo(); @@ -153,6 +150,10 @@ private Stream languageTypeBuilder() { argumentBuilder.add(Arguments.of(language, null, false)); } for (ProjectType projectType : projectTypes) { + // TODO: MAVEN_BLACKBOX Templates should be tested in the future! + if (projectType == ProjectType.MAVEN_BLACKBOX) { + continue; + } argumentBuilder.add(Arguments.of(language, projectType, false)); } @@ -161,6 +162,9 @@ private Stream languageTypeBuilder() { argumentBuilder.add(Arguments.of(language, null, true)); } for (ProjectType projectType : projectTypes) { + if (projectType == ProjectType.MAVEN_BLACKBOX) { + continue; + } argumentBuilder.add(Arguments.of(language, projectType, true)); } } diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingSubmissionIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingSubmissionIntegrationTest.java index 243c7edcc9f6..1202044ed886 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingSubmissionIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingSubmissionIntegrationTest.java @@ -16,7 +16,6 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; @@ -34,19 +33,13 @@ import de.tum.in.www1.artemis.domain.enumeration.SubmissionType; import de.tum.in.www1.artemis.domain.modeling.ModelingExercise; import de.tum.in.www1.artemis.domain.modeling.ModelingSubmission; -import de.tum.in.www1.artemis.domain.participation.Participation; -import de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation; -import de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation; -import de.tum.in.www1.artemis.domain.participation.StudentParticipation; +import de.tum.in.www1.artemis.domain.participation.*; import de.tum.in.www1.artemis.exception.ContinuousIntegrationException; import de.tum.in.www1.artemis.exercise.ExerciseUtilService; import de.tum.in.www1.artemis.exercise.modelingexercise.ModelingExerciseUtilService; import de.tum.in.www1.artemis.participation.ParticipationFactory; import de.tum.in.www1.artemis.participation.ParticipationUtilService; -import de.tum.in.www1.artemis.repository.ProgrammingExerciseRepository; -import de.tum.in.www1.artemis.repository.ProgrammingExerciseStudentParticipationRepository; -import de.tum.in.www1.artemis.repository.ProgrammingSubmissionRepository; -import de.tum.in.www1.artemis.repository.StudentParticipationRepository; +import de.tum.in.www1.artemis.repository.*; import de.tum.in.www1.artemis.service.connectors.bamboo.dto.BambooBuildPlanDTO; import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.util.FileUtils; @@ -231,7 +224,6 @@ void triggerBuildStudentForbidden() throws Exception { } @Test - @Timeout(5) @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR") void triggerBuildForExerciseAsInstructor() throws Exception { bambooRequestMockProvider.enableMockingOfRequests(); diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/quizexercise/QuizExerciseIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/quizexercise/QuizExerciseIntegrationTest.java index c1aae99010df..4dbd1b9914c5 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/quizexercise/QuizExerciseIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/quizexercise/QuizExerciseIntegrationTest.java @@ -3,7 +3,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.byLessThan; -import java.security.Principal; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; import java.util.*; @@ -17,12 +16,11 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; -import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.util.LinkedMultiValueMap; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.enumeration.*; @@ -41,9 +39,8 @@ import de.tum.in.www1.artemis.util.PageableSearchUtilService; import de.tum.in.www1.artemis.web.rest.dto.QuizBatchJoinDTO; import de.tum.in.www1.artemis.web.rest.dto.SearchResultPageDTO; -import de.tum.in.www1.artemis.web.websocket.QuizSubmissionWebsocketService; -class QuizExerciseIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class QuizExerciseIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "quizexerciseintegration"; @@ -52,9 +49,6 @@ class QuizExerciseIntegrationTest extends AbstractSpringIntegrationBambooBitbuck @Autowired private QuizExerciseService quizExerciseService; - @Autowired - private QuizSubmissionWebsocketService quizSubmissionWebsocketService; - @Autowired private StudentParticipationRepository studentParticipationRepository; @@ -70,9 +64,6 @@ class QuizExerciseIntegrationTest extends AbstractSpringIntegrationBambooBitbuck @Autowired private SubmittedAnswerRepository submittedAnswerRepository; - @Autowired - private QuizExerciseUtilService quizUtilService; - @Autowired private TeamRepository teamRepository; @@ -332,19 +323,10 @@ void testDeleteQuizExerciseWithSubmittedAnswers(QuizMode quizMode) throws Except QuizExercise quizExercise = quizExerciseUtilService.createAndSaveQuiz(ZonedDateTime.now(), ZonedDateTime.now().plusMinutes(1), quizMode); assertThat(quizExerciseRepository.findOneWithQuestionsAndStatistics(quizExercise.getId())).as("Exercise is created correctly").isNotNull(); - String username = TEST_PREFIX + "student1"; - final Principal principal = () -> username; QuizSubmission quizSubmission = QuizExerciseFactory.generateSubmissionForThreeQuestions(quizExercise, 1, true, null); - - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - quizUtilService.prepareBatchForSubmitting(quizExercise, authentication, SecurityUtils.makeAuthorizationObject(username)); - quizSubmissionWebsocketService.saveSubmission(quizExercise.getId(), quizSubmission, principal); - SecurityContextHolder.getContext().setAuthentication(authentication); - - // Quiz submissions are not yet in database - assertThat(quizSubmissionRepository.findByParticipation_Exercise_Id(quizExercise.getId())).isEmpty(); - - quizScheduleService.processCachedQuizSubmissions(); + quizSubmission.submitted(true); + participationUtilService.addSubmission(quizExercise, quizSubmission, TEST_PREFIX + "student1"); + participationUtilService.addResultToSubmission(quizSubmission, AssessmentType.AUTOMATIC, null, quizExercise.getScoreForSubmission(quizSubmission), true); // Quiz submissions are now in database assertThat(quizSubmissionRepository.findByParticipation_Exercise_Id(quizExercise.getId())).hasSize(1); @@ -841,6 +823,24 @@ void testReEvaluateQuizQuestionWithMoreSolutions() throws Exception { assertThat(receivedShortAnswerQuestion.getCorrectMappings()).hasSize(3); } + @Test + @WithMockUser(username = TEST_PREFIX + "tutor1", roles = "TA") + void testAddAndStartQuizBatch() throws Exception { + QuizExercise quizExercise = quizExerciseUtilService.createAndSaveQuiz(ZonedDateTime.now().plusHours(5), null, QuizMode.BATCHED); + + QuizBatch batch = request.putWithResponseBody("/api/quiz-exercises/" + quizExercise.getId() + "/add-batch", null, QuizBatch.class, HttpStatus.OK); + request.put("/api/quiz-exercises/" + batch.getId() + "/start-batch", null, HttpStatus.OK); + } + + @Test + @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER") + void testAddAndStartQuizBatch_AsStudentNotAllowed() throws Exception { + QuizExercise quizExercise = quizExerciseUtilService.createAndSaveQuiz(ZonedDateTime.now().plusHours(5), null, QuizMode.BATCHED); + + request.putWithResponseBody("/api/quiz-exercises/" + quizExercise.getId() + "/add-batch", null, QuizBatch.class, HttpStatus.FORBIDDEN); + request.put("/api/quiz-exercises/" + null + "/start-batch", null, HttpStatus.BAD_REQUEST); + } + @Test @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR") void testPerformStartNow() throws Exception { @@ -912,12 +912,21 @@ void testPerformJoin(QuizMode quizMode, ZonedDateTime release, ZonedDateTime due SecurityContextHolder.getContext().setAuthentication(SecurityUtils.makeAuthorizationObject(TEST_PREFIX + "student1")); request.postWithResponseBody("/api/quiz-exercises/" + quizExercise.getId() + "/join", new QuizBatchJoinDTO(password), QuizBatch.class, result); - if (result == HttpStatus.OK) { - // if joining was successful repeating the request should fail, otherwise with the same reason as the first attempt - result = HttpStatus.BAD_REQUEST; - } + } - request.postWithResponseBody("/api/quiz-exercises/" + quizExercise.getId() + "/join", new QuizBatchJoinDTO(password), QuizBatch.class, result); + @ParameterizedTest(name = "{displayName} [{index}] {argumentsWithNames}") + @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER") + @EnumSource(QuizMode.class) + void testCannotPerformJoinTwice(QuizMode quizMode) throws Exception { + QuizExercise quizExercise = quizExerciseUtilService.createAndSaveQuiz(ZonedDateTime.now().minusMinutes(2), ZonedDateTime.now().plusMinutes(2), quizMode); + QuizBatch batch = new QuizBatch(); + batch.setStartTime(ZonedDateTime.now().minusMinutes(1)); + batch.setPassword("1234"); + + quizExerciseUtilService.setQuizBatchExerciseAndSave(batch, quizExercise); + quizScheduleService.joinQuizBatch(quizExercise, batch, userUtilService.getUserByLogin(TEST_PREFIX + "student1")); + + request.postWithResponseBody("/api/quiz-exercises/" + quizExercise.getId() + "/join", new QuizBatchJoinDTO("1234"), QuizBatch.class, HttpStatus.BAD_REQUEST); } /** diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/quizexercise/QuizExerciseUtilService.java b/src/test/java/de/tum/in/www1/artemis/exercise/quizexercise/QuizExerciseUtilService.java index 4c45c125cff6..909215386516 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/quizexercise/QuizExerciseUtilService.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/quizexercise/QuizExerciseUtilService.java @@ -12,19 +12,15 @@ import org.apache.commons.io.FileUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.util.ResourceUtils; import de.tum.in.www1.artemis.course.CourseFactory; import de.tum.in.www1.artemis.course.CourseUtilService; -import de.tum.in.www1.artemis.domain.Course; -import de.tum.in.www1.artemis.domain.Team; -import de.tum.in.www1.artemis.domain.TeamAssignmentConfig; -import de.tum.in.www1.artemis.domain.User; -import de.tum.in.www1.artemis.domain.enumeration.*; +import de.tum.in.www1.artemis.domain.*; +import de.tum.in.www1.artemis.domain.enumeration.ExerciseMode; +import de.tum.in.www1.artemis.domain.enumeration.QuizMode; +import de.tum.in.www1.artemis.domain.enumeration.SubmissionType; import de.tum.in.www1.artemis.domain.exam.Exam; import de.tum.in.www1.artemis.domain.exam.ExerciseGroup; import de.tum.in.www1.artemis.domain.participation.StudentParticipation; @@ -35,8 +31,6 @@ import de.tum.in.www1.artemis.service.FilePathService; import de.tum.in.www1.artemis.service.scheduled.cache.quiz.QuizScheduleService; import de.tum.in.www1.artemis.user.UserUtilService; -import de.tum.in.www1.artemis.util.RequestUtilService; -import de.tum.in.www1.artemis.web.rest.dto.QuizBatchJoinDTO; /** * Service responsible for initializing the database with specific testdata related to quiz exercises for use in integration tests. @@ -77,9 +71,6 @@ public class QuizExerciseUtilService { @Autowired private CourseUtilService courseUtilService; - @Autowired - private RequestUtilService requestUtilService; - @Autowired private SubmittedAnswerRepository submittedAnswerRepository; @@ -98,29 +89,6 @@ public class QuizExerciseUtilService { @Autowired private QuizScheduleService quizScheduleService; - /** - * Create, join and start a batch for student by tutor - */ - public void prepareBatchForSubmitting(QuizExercise quizExercise, Authentication tutor, Authentication student) throws Exception { - var authentication = SecurityContextHolder.getContext().getAuthentication(); - switch (quizExercise.getQuizMode()) { - case SYNCHRONIZED -> { - } - case BATCHED -> { - SecurityContextHolder.getContext().setAuthentication(tutor); - var batch = requestUtilService.putWithResponseBody("/api/quiz-exercises/" + quizExercise.getId() + "/add-batch", null, QuizBatch.class, HttpStatus.OK); - requestUtilService.put("/api/quiz-exercises/" + batch.getId() + "/start-batch", null, HttpStatus.OK); - SecurityContextHolder.getContext().setAuthentication(student); - requestUtilService.postWithoutLocation("/api/quiz-exercises/" + quizExercise.getId() + "/join", new QuizBatchJoinDTO(batch.getPassword()), HttpStatus.OK, null); - } - case INDIVIDUAL -> { - SecurityContextHolder.getContext().setAuthentication(student); - requestUtilService.postWithoutLocation("/api/quiz-exercises/" + quizExercise.getId() + "/join", new QuizBatchJoinDTO(null), HttpStatus.OK, null); - } - } - SecurityContextHolder.getContext().setAuthentication(authentication); - } - public Course addCourseWithOneQuizExercise() { return addCourseWithOneQuizExercise("Title"); } diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/quizexercise/QuizSubmissionIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/exercise/quizexercise/QuizSubmissionIntegrationTest.java index 12eba7fcb04e..c5290695b2b2 100644 --- a/src/test/java/de/tum/in/www1/artemis/exercise/quizexercise/QuizSubmissionIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/exercise/quizexercise/QuizSubmissionIntegrationTest.java @@ -12,9 +12,8 @@ import java.util.Arrays; import java.util.List; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.parallel.Isolated; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; import org.junit.jupiter.params.provider.ValueSource; @@ -24,23 +23,26 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationLocalCILocalVCTest; import de.tum.in.www1.artemis.config.Constants; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.Result; +import de.tum.in.www1.artemis.domain.enumeration.AssessmentType; import de.tum.in.www1.artemis.domain.enumeration.QuizMode; import de.tum.in.www1.artemis.domain.enumeration.ScoringType; import de.tum.in.www1.artemis.domain.exam.ExerciseGroup; import de.tum.in.www1.artemis.domain.quiz.*; import de.tum.in.www1.artemis.exam.ExamUtilService; +import de.tum.in.www1.artemis.participation.ParticipationUtilService; import de.tum.in.www1.artemis.repository.*; import de.tum.in.www1.artemis.service.QuizBatchService; import de.tum.in.www1.artemis.service.QuizExerciseService; +import de.tum.in.www1.artemis.service.QuizStatisticService; import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.web.websocket.QuizSubmissionWebsocketService; -class QuizSubmissionIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class QuizSubmissionIntegrationTest extends AbstractSpringIntegrationLocalCILocalVCTest { private static final String TEST_PREFIX = "quizsubmissiontest"; @@ -62,9 +64,6 @@ class QuizSubmissionIntegrationTest extends AbstractSpringIntegrationBambooBitbu @Autowired private QuizExerciseRepository quizExerciseRepository; - @Autowired - private QuizSubmissionWebsocketService quizSubmissionWebsocketService; - @Autowired private QuizSubmissionRepository quizSubmissionRepository; @@ -92,6 +91,15 @@ class QuizSubmissionIntegrationTest extends AbstractSpringIntegrationBambooBitbu @Autowired private ExamUtilService examUtilService; + @Autowired + QuizStatisticService quizStatisticService; + + @Autowired + ParticipationUtilService participationUtilService; + + @Autowired + QuizSubmissionWebsocketService quizSubmissionWebsocketService; + @BeforeEach void init() { // do not use the schedule service based on a time interval in the tests, because this would result in flaky tests that run much slower @@ -106,51 +114,69 @@ protected void resetSpyBeans() { @Test @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER") - void testQuizSubmit() { + void testQuizSubmitWebsocket() { QuizExercise quizExercise = setupQuizExerciseParameters(); quizExercise = quizExerciseService.save(quizExercise); - QuizSubmission quizSubmission; + QuizSubmission quizSubmission = QuizExerciseFactory.generateSubmissionForThreeQuestions(quizExercise, 1, false, null); - for (int i = 1; i <= NUMBER_OF_STUDENTS; i++) { - quizSubmission = QuizExerciseFactory.generateSubmissionForThreeQuestions(quizExercise, i, false, null); - final var username = TEST_PREFIX + "student" + i; - final Principal principal = () -> username; - // save - quizSubmissionWebsocketService.saveSubmission(quizExercise.getId(), quizSubmission, principal); - } + String username = TEST_PREFIX + "student1"; + Principal principal = () -> username; + + quizSubmissionWebsocketService.saveSubmission(quizExercise.getId(), quizSubmission, principal); + verify(websocketMessagingService, never()).sendMessageToUser(eq(username), any(), any()); + } + + @Test + @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER") + void testQuizSubmitUnactiveQuizWebsocket() { + QuizExercise quizExercise = quizExerciseUtilService.createQuiz(ZonedDateTime.now().plusDays(1), null, QuizMode.SYNCHRONIZED); + quizExercise.duration(240); + quizExerciseRepository.save(quizExercise); + + QuizSubmission quizSubmission = QuizExerciseFactory.generateSubmissionForThreeQuestions(quizExercise, 1, false, null); + + String username = TEST_PREFIX + "student1"; + Principal principal = () -> username; + + quizSubmissionWebsocketService.saveSubmission(quizExercise.getId(), quizSubmission, principal); + verify(websocketMessagingService).sendMessageToUser(eq(username), any(), any()); + } + + @Test + @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER") + void testQuizSubmit_CalculateScore() { + QuizExercise quizExercise = setupQuizExerciseParameters(); + quizExercise = quizExerciseService.save(quizExercise); + + QuizSubmission quizSubmission; - // only half of the students submit manually + // only half of the students submit for (int i = 1; i <= NUMBER_OF_STUDENTS / 2; i++) { - quizSubmission = QuizExerciseFactory.generateSubmissionForThreeQuestions(quizExercise, i, true, null); - final var username = TEST_PREFIX + "student" + i; - final Principal principal = () -> username; - // submit - quizSubmissionWebsocketService.saveSubmission(quizExercise.getId(), quizSubmission, principal); + quizSubmission = QuizExerciseFactory.generateSubmissionForThreeQuestions(quizExercise, i, false, null); + quizSubmission.setSubmitted(true); + participationUtilService.addSubmission(quizExercise, quizSubmission, TEST_PREFIX + "student" + i); + participationUtilService.addResultToSubmission(quizSubmission, AssessmentType.AUTOMATIC, null, quizExercise.getScoreForSubmission(quizSubmission), true); } - // before the quiz submissions are processed, none of them ends up in the database - assertThat(submissionRepository.countByExerciseIdSubmitted(quizExercise.getId())).isZero(); - - // process first half of the submissions - quizScheduleService.processCachedQuizSubmissions(); + // check first half of the submissions assertThat(submissionRepository.countByExerciseIdSubmitted(quizExercise.getId())).isEqualTo(NUMBER_OF_STUDENTS / 2); - // End the quiz right now so that results can be processed - quizExercise = quizExerciseRepository.findOneWithQuestionsAndStatistics(quizExercise.getId()); - final var exercise = quizExercise; - assertThat(quizExercise).isNotNull(); - quizExercise.setDueDate(ZonedDateTime.now()); - quizExercise.getQuizBatches().forEach(batch -> batch.setStartTime(quizBatchService.quizBatchStartDate(exercise, batch.getStartTime()))); - exerciseRepository.saveAndFlush(quizExercise); - - quizScheduleService.processCachedQuizSubmissions(); + for (int i = NUMBER_OF_STUDENTS / 2 + 1; i <= NUMBER_OF_STUDENTS; i++) { + quizSubmission = QuizExerciseFactory.generateSubmissionForThreeQuestions(quizExercise, i, false, null); + quizSubmission.setSubmitted(true); + participationUtilService.addSubmission(quizExercise, quizSubmission, TEST_PREFIX + "student" + i); + participationUtilService.addResultToSubmission(quizSubmission, AssessmentType.AUTOMATIC, null, quizExercise.getScoreForSubmission(quizSubmission), true); + } - // after the quiz submissions have been processed, all submission are saved to the database + // all submission are saved to the database assertThat(submissionRepository.countByExerciseIdSubmitted(quizExercise.getId())).isEqualTo(NUMBER_OF_STUDENTS); - // Test the statistics directly from the database - QuizExercise quizExerciseWithStatistic = quizExerciseRepository.findOneWithQuestionsAndStatistics(quizExercise.getId()); + // update the statistics + QuizExercise quizExerciseWithStatistic = quizExerciseRepository.findByIdWithQuestionsAndStatisticsElseThrow(quizExercise.getId()); + quizStatisticService.recalculateStatistics(quizExerciseWithStatistic); + + // Test the statistics assertThat(quizExerciseWithStatistic).isNotNull(); assertThat(quizExerciseWithStatistic.getQuizPointStatistic().getParticipantsUnrated()).isZero(); assertThat(quizExerciseWithStatistic.getQuizPointStatistic().getParticipantsRated()).isEqualTo(NUMBER_OF_STUDENTS); @@ -193,11 +219,6 @@ else if (question instanceof DragAndDropQuestion) { assertThat(question.getQuizQuestionStatistic().getParticipantsRated()).isEqualTo(NUMBER_OF_STUDENTS); assertThat(question.getQuizQuestionStatistic().getParticipantsUnrated()).isZero(); } - - // execute the scheduler again, this should remove the quiz exercise from the cache - quizScheduleService.processCachedQuizSubmissions(); - // but of course keep all submissions - assertThat(submissionRepository.countByExerciseIdSubmitted(quizExercise.getId())).isEqualTo(NUMBER_OF_STUDENTS); } @Test @@ -259,14 +280,14 @@ void testQuizSubmit_partial_points() { submissions.add(student3Submission); for (int i = 0; i < 3; i++) { - var username = TEST_PREFIX + "student" + (i + 1); - final Principal principal = () -> username; - quizSubmissionWebsocketService.saveSubmission(quizExercise.getId(), submissions.get(i), principal); + participationUtilService.addSubmission(quizExercise, submissions.get(i), TEST_PREFIX + "student" + (i + 1)); + participationUtilService.addResultToSubmission(submissions.get(i), AssessmentType.AUTOMATIC, null, quizExercise.getScoreForSubmission(submissions.get(i)), true); } - quizScheduleService.processCachedQuizSubmissions(); + // update the statistics + QuizExercise quizExerciseWithStatistic = quizExerciseRepository.findByIdWithQuestionsAndStatisticsElseThrow(quizExercise.getId()); + quizStatisticService.recalculateStatistics(quizExerciseWithStatistic); - QuizExercise quizExerciseWithStatistic = quizExerciseRepository.findOneWithQuestionsAndStatistics(quizExercise.getId()); var quizPointStatistic = quizExerciseWithStatistic.getQuizPointStatistic(); assertThat(quizExerciseWithStatistic).isNotNull(); @@ -284,51 +305,7 @@ else if (pointCounter.getPoints() == 6.0) { else { assertThat(pointCounter.getRatedCounter()).as("All other buckets contain 0 rated submissions").isZero(); } - - } - } - - @ParameterizedTest(name = "{displayName} [{index}] {argumentsWithNames}") - @WithMockUser(username = TEST_PREFIX + "student3", roles = "USER") - @EnumSource(QuizMode.class) - void testQuizSubmitLiveMode(QuizMode quizMode) throws Exception { - QuizExercise quizExercise = quizExerciseUtilService.createQuiz(ZonedDateTime.now().minusSeconds(10), null, quizMode); - quizExercise.setDuration(600); - quizExercise = quizExerciseService.save(quizExercise); - - // at the beginning there are no submissions and no participants - assertThat(quizSubmissionRepository.findByParticipation_Exercise_Id(quizExercise.getId())).isEmpty(); - assertThat(participationRepository.findByExerciseId(quizExercise.getId())).isEmpty(); - - if (quizMode != QuizMode.SYNCHRONIZED) { - var batch = quizBatchService.save(QuizExerciseFactory.generateQuizBatch(quizExercise, ZonedDateTime.now().minusSeconds(10))); - for (int i = 1; i <= NUMBER_OF_STUDENTS; i++) { - quizExerciseUtilService.joinQuizBatch(quizExercise, batch, TEST_PREFIX + "student" + i); - } - } - - for (int i = 1; i <= NUMBER_OF_STUDENTS; i++) { - userUtilService.changeUser(TEST_PREFIX + "student" + i); - QuizSubmission quizSubmission = QuizExerciseFactory.generateSubmissionForThreeQuestions(quizExercise, i, false, null); - assertThat(quizSubmission.getSubmittedAnswers()).hasSize(3); - assertThat(quizSubmission.isSubmitted()).isFalse(); - assertThat(quizSubmission.getSubmissionDate()).isNull(); - QuizSubmission updatedSubmission = request.postWithResponseBody("/api/exercises/" + quizExercise.getId() + "/submissions/live", quizSubmission, QuizSubmission.class, - HttpStatus.OK); - // check whether submission flag was updated - assertThat(updatedSubmission.isSubmitted()).isTrue(); - // check whether all answers were submitted properly - assertThat(updatedSubmission.getSubmittedAnswers()).hasSameSizeAs(quizSubmission.getSubmittedAnswers()); - // check whether submission date was set - assertThat(updatedSubmission.getSubmissionDate()).isNotNull(); } - - // process cached submissions - quizScheduleService.processCachedQuizSubmissions(); - - // check whether all submissions were saved to the database - assertThat(quizSubmissionRepository.findByParticipation_Exercise_Id(quizExercise.getId())).hasSize(NUMBER_OF_STUDENTS); - assertThat(participationRepository.findByExerciseId(quizExercise.getId())).hasSize(NUMBER_OF_STUDENTS); } @ParameterizedTest(name = "{displayName} [{index}] {argumentsWithNames}") @@ -353,26 +330,6 @@ void testQuizSubmitLiveMode_badRequest_notActive(QuizMode quizMode) throws Excep } } - @ParameterizedTest(name = "{displayName} [{index}] {argumentsWithNames}") - @WithMockUser(username = TEST_PREFIX + "student3", roles = "USER") - @EnumSource(QuizMode.class) - void testQuizSubmitLiveMode_badRequest_alreadySubmitted(QuizMode quizMode) throws Exception { - QuizExercise quizExercise = quizExerciseUtilService.createQuiz(ZonedDateTime.now().minusSeconds(5), ZonedDateTime.now().plusSeconds(10), quizMode); - quizExercise.setDuration(10); - quizExercise = quizExerciseService.save(quizExercise); - - if (quizMode != QuizMode.SYNCHRONIZED) { - var batch = quizBatchService.save(QuizExerciseFactory.generateQuizBatch(quizExercise, ZonedDateTime.now().minusSeconds(5))); - quizExerciseUtilService.joinQuizBatch(quizExercise, batch, TEST_PREFIX + "student3"); - } - - QuizSubmission quizSubmission = QuizExerciseFactory.generateSubmissionForThreeQuestions(quizExercise, 1, false, ZonedDateTime.now()); - // submit quiz for the first time, expected status = OK - request.postWithResponseBody("/api/exercises/" + quizExercise.getId() + "/submissions/live", quizSubmission, Result.class, HttpStatus.OK); - // submit quiz for the second time, expected status = BAD_REQUEST - request.postWithResponseBody("/api/exercises/" + quizExercise.getId() + "/submissions/live", quizSubmission, Result.class, HttpStatus.BAD_REQUEST); - } - @Test @WithMockUser(username = TEST_PREFIX + "student3", roles = "USER") void testQuizSubmitEmptyQuizInLiveMode() throws Exception { @@ -414,15 +371,15 @@ void testQuizSubmitPractice(QuizMode quizMode) throws Exception { assertThat(((QuizSubmission) receivedResult.getSubmission()).getSubmittedAnswers()).hasSameSizeAs(quizSubmission.getSubmittedAnswers()); } - // after the quiz has ended, all submission are saved to the database + // all submission are saved to the database assertThat(quizSubmissionRepository.findByParticipation_Exercise_Id(quizExercise.getId())).hasSize(NUMBER_OF_STUDENTS); assertThat(participationRepository.findByExerciseId(quizExercise.getId())).hasSize(NUMBER_OF_STUDENTS); - // processing the quiz submissions will update the statistics - quizScheduleService.processCachedQuizSubmissions(); + // update the statistics + QuizExercise quizExerciseWithStatistic = quizExerciseRepository.findByIdWithQuestionsAndStatisticsElseThrow(quizExercise.getId()); + quizStatisticService.recalculateStatistics(quizExerciseWithStatistic); - // Test the statistics directly from the database - QuizExercise quizExerciseWithStatistic = quizExerciseRepository.findOneWithQuestionsAndStatistics(quizExercise.getId()); + // Test the statistics assertThat(quizExerciseWithStatistic).isNotNull(); assertThat(quizExerciseWithStatistic.getQuizPointStatistic().getParticipantsRated()).isZero(); assertThat(quizExerciseWithStatistic.getQuizPointStatistic().getParticipantsUnrated()).isEqualTo(NUMBER_OF_STUDENTS); @@ -592,11 +549,12 @@ void testQuizSubmitPreview(QuizMode quizMode) throws Exception { // in the preview the submission will not be saved to the database assertThat(quizSubmissionRepository.findByParticipation_Exercise_Id(quizExercise.getId())).isEmpty(); - quizScheduleService.processCachedQuizSubmissions(); + // update the statistics + QuizExercise quizExerciseWithStatistic = quizExerciseRepository.findByIdWithQuestionsAndStatisticsElseThrow(quizExercise.getId()); + quizStatisticService.recalculateStatistics(quizExerciseWithStatistic); // all stats must be 0 because we have a preview here - // Test the statistics directly from the database - QuizExercise quizExerciseWithStatistic = quizExerciseRepository.findOneWithQuestionsAndStatistics(quizExercise.getId()); + // Test the statistics assertThat(quizExerciseWithStatistic).isNotNull(); assertThat(quizExerciseWithStatistic.getQuizPointStatistic().getParticipantsRated()).isZero(); assertThat(quizExerciseWithStatistic.getQuizPointStatistic().getParticipantsUnrated()).isZero(); @@ -618,8 +576,9 @@ void testQuizSubmitPreview(QuizMode quizMode) throws Exception { } @Test - @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER") - void testQuizSubmitScheduledAndDeleted() { + + @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR") + void testQuizSubmitScheduledAndDeleted() throws Exception { Course course = courseUtilService.createCourse(); String publishQuizPath = "/topic/courses/" + course.getId() + "/quizExercises"; log.debug("// Creating the quiz exercise 2s in the future"); @@ -635,9 +594,7 @@ void testQuizSubmitScheduledAndDeleted() { // check that submission fails QuizSubmission quizSubmission = QuizExerciseFactory.generateSubmissionForThreeQuestions(quizExercise, 1, true, null); - quizSubmissionWebsocketService.saveSubmission(quizExercise.getId(), quizSubmission, () -> TEST_PREFIX + "student3"); - - quizScheduleService.processCachedQuizSubmissions(); + request.postWithResponseBody("/api/exercises/" + quizExercise.getId() + "/submissions/live", quizSubmission, Result.class, HttpStatus.BAD_REQUEST); assertThat(submissionRepository.countByExerciseIdSubmitted(quizExercise.getId())).isZero(); // reschedule @@ -650,42 +607,27 @@ void testQuizSubmitScheduledAndDeleted() { assertThat(quizExercise.isQuizStarted()).isTrue(); assertThat(quizExercise.getQuizBatches()).allMatch(QuizBatch::isStarted); - // process cached submissions - quizScheduleService.processCachedQuizSubmissions(); - // save submissions for (int i = 1; i <= 2; i++) { quizSubmission = QuizExerciseFactory.generateSubmissionForThreeQuestions(quizExercise, i, false, null); - final var username = TEST_PREFIX + "student" + i; - final Principal principal = () -> username; - // save - quizSubmissionWebsocketService.saveSubmission(quizExercise.getId(), quizSubmission, principal); + participationUtilService.addSubmission(quizExercise, quizSubmission, TEST_PREFIX + "student" + i); + participationUtilService.addResultToSubmission(quizSubmission, AssessmentType.AUTOMATIC, null, quizExercise.getScoreForSubmission(quizSubmission), true); } - // process the saved but not submitted quiz submissions - quizScheduleService.processCachedQuizSubmissions(); - - // before the quiz submissions are submitted, none of them ends up in the database - assertThat(submissionRepository.countByExerciseIdSubmitted(quizExercise.getId())).isZero(); - // set the quiz end to now and ... log.debug("// End the quiz and delete it"); quizExercise = quizExerciseRepository.findOneWithQuestionsAndStatistics(quizExercise.getId()); assertThat(quizExercise).isNotNull(); quizExercise.setDuration((int) Duration.between(quizExercise.getReleaseDate(), ZonedDateTime.now()).getSeconds() - Constants.QUIZ_GRACE_PERIOD_IN_SECONDS); quizExercise = exerciseRepository.saveAndFlush(quizExercise); - quizScheduleService.updateQuizExercise(quizExercise); - // ... directly delete the quiz - exerciseRepository.delete(quizExercise); + + // ...delete the quiz + request.delete("/api/quiz-exercises/" + quizExercise.getId(), HttpStatus.OK); QuizExercise finalQuizExercise = quizExercise; await().until(() -> exerciseRepository.findById(finalQuizExercise.getId()).isEmpty()); - // the deleted quiz should get removed, no submissions should be saved - quizScheduleService.processCachedQuizSubmissions(); - // quiz is not cached anymore - assertThat(quizScheduleService.getQuizExercise(quizExercise.getId())).isNull(); - // no submissions were marked as submitted and saved + // no submissions left assertThat(submissionRepository.countByExerciseIdSubmitted(quizExercise.getId())).isZero(); } @@ -702,18 +644,10 @@ void testQuizScoringTypes() { quizSubmission.addSubmittedAnswers(QuizExerciseFactory.generateSubmittedAnswerForQuizWithCorrectAndFalseAnswers(question)); } quizSubmission.submitted(true); - quizSubmissionWebsocketService.saveSubmission(quizExercise.getId(), quizSubmission, () -> TEST_PREFIX + "student4"); - - quizScheduleService.processCachedQuizSubmissions(); - - // End the quiz right now so that results can be processed - quizExercise = quizExerciseRepository.findOneWithQuestionsAndStatistics(quizExercise.getId()); - assertThat(quizExercise).isNotNull(); - quizExercise.setDuration((int) Duration.between(quizExercise.getReleaseDate(), ZonedDateTime.now()).getSeconds() - Constants.QUIZ_GRACE_PERIOD_IN_SECONDS); - exerciseRepository.saveAndFlush(quizExercise); - - quizScheduleService.processCachedQuizSubmissions(); + participationUtilService.addSubmission(quizExercise, quizSubmission, TEST_PREFIX + "student4"); + participationUtilService.addResultToSubmission(quizSubmission, AssessmentType.AUTOMATIC, null, quizExercise.getScoreForSubmission(quizSubmission), true); + quizExerciseService.reEvaluate(quizExercise, quizExercise); assertThat(quizSubmissionRepository.findByQuizExerciseId(quizExercise.getId())).isPresent(); List results = resultRepository.findByParticipationExerciseIdOrderByCompletionDateAsc(quizExercise.getId()); @@ -752,18 +686,10 @@ void testQuizScoringType(ScoringType scoringType) { quizSubmission.addSubmittedAnswers(QuizExerciseFactory.generateSubmittedAnswerForQuizWithCorrectAndFalseAnswers(question)); } quizSubmission.submitted(true); - quizSubmissionWebsocketService.saveSubmission(quizExercise.getId(), quizSubmission, () -> TEST_PREFIX + "student3"); - - quizScheduleService.processCachedQuizSubmissions(); - - // End the quiz right now so that results can be processed - quizExercise = quizExerciseRepository.findOneWithQuestionsAndStatistics(quizExercise.getId()); - assertThat(quizExercise).isNotNull(); - quizExercise.setDuration((int) Duration.between(quizExercise.getReleaseDate(), ZonedDateTime.now()).getSeconds() - Constants.QUIZ_GRACE_PERIOD_IN_SECONDS); - exerciseRepository.saveAndFlush(quizExercise); - - quizScheduleService.processCachedQuizSubmissions(); + participationUtilService.addSubmission(quizExercise, quizSubmission, TEST_PREFIX + "student3"); + participationUtilService.addResultToSubmission(quizSubmission, AssessmentType.AUTOMATIC, null, quizExercise.getScoreForSubmission(quizSubmission), true); + quizExerciseService.reEvaluate(quizExercise, quizExercise); assertThat(submissionRepository.countByExerciseIdSubmitted(quizExercise.getId())).isEqualTo(1); List results = resultRepository.findByParticipationExerciseIdOrderByCompletionDateAsc(quizExercise.getId()); @@ -848,4 +774,57 @@ private QuizExercise setupQuizExerciseParameters() { quizExercise.duration(240); return quizExercise; } + + @Nested + @Isolated + class QuizSubmitLiveModeIsolatedTest { + + @ParameterizedTest(name = "{displayName} [{index}] {argumentsWithNames}") + @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER") + @EnumSource(QuizMode.class) + void testQuizSubmitLiveMode(QuizMode quizMode) throws Exception { + QuizExercise quizExercise = quizExerciseUtilService.createQuiz(ZonedDateTime.now().minusMinutes(2), null, quizMode); + quizExercise.setDuration(600); + quizExercise = quizExerciseService.save(quizExercise); + + // at the beginning there are no submissions and no participants + assertThat(quizSubmissionRepository.findByParticipation_Exercise_Id(quizExercise.getId())).isEmpty(); + assertThat(participationRepository.findByExerciseId(quizExercise.getId())).isEmpty(); + + if (quizMode != QuizMode.SYNCHRONIZED) { + var batch = quizBatchService.save(QuizExerciseFactory.generateQuizBatch(quizExercise, ZonedDateTime.now().minusSeconds(10))); + quizExerciseUtilService.joinQuizBatch(quizExercise, batch, TEST_PREFIX + "student1"); + } + + QuizSubmission quizSubmission = QuizExerciseFactory.generateSubmissionForThreeQuestions(quizExercise, 1, false, null); + QuizSubmission updatedSubmission = request.postWithResponseBody("/api/exercises/" + quizExercise.getId() + "/submissions/live", quizSubmission, QuizSubmission.class, + HttpStatus.OK); + // check whether submission flag was updated + assertThat(updatedSubmission.isSubmitted()).isTrue(); + // check whether all answers were submitted properly + assertThat(updatedSubmission.getSubmittedAnswers()).hasSameSizeAs(quizSubmission.getSubmittedAnswers()); + // check whether submission date was set + assertThat(updatedSubmission.getSubmissionDate()).isNotNull(); + } + + @ParameterizedTest(name = "{displayName} [{index}] {argumentsWithNames}") + @WithMockUser(username = TEST_PREFIX + "student3", roles = "USER") + @EnumSource(QuizMode.class) + void testQuizSubmitLiveMode_badRequest_alreadySubmitted(QuizMode quizMode) throws Exception { + QuizExercise quizExercise = quizExerciseUtilService.createQuiz(ZonedDateTime.now().minusSeconds(5), ZonedDateTime.now().plusSeconds(10), quizMode); + quizExercise.setDuration(10); + quizExercise = quizExerciseService.save(quizExercise); + + if (quizMode != QuizMode.SYNCHRONIZED) { + var batch = quizBatchService.save(QuizExerciseFactory.generateQuizBatch(quizExercise, ZonedDateTime.now().minusSeconds(5))); + quizExerciseUtilService.joinQuizBatch(quizExercise, batch, TEST_PREFIX + "student3"); + } + + // create a submission for the first time + QuizSubmission quizSubmission = QuizExerciseFactory.generateSubmissionForThreeQuestions(quizExercise, 1, true, ZonedDateTime.now()); + quizScheduleService.updateSubmission(quizExercise.getId(), TEST_PREFIX + "student3", quizSubmission); + // submit quiz for the second time, expected status = BAD_REQUEST + request.postWithResponseBody("/api/exercises/" + quizExercise.getId() + "/submissions/live", quizSubmission, Result.class, HttpStatus.BAD_REQUEST); + } + } } diff --git a/src/test/java/de/tum/in/www1/artemis/hestia/CodeHintIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/hestia/CodeHintIntegrationTest.java index a485b98a04a6..0f3822466f44 100644 --- a/src/test/java/de/tum/in/www1/artemis/hestia/CodeHintIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/hestia/CodeHintIntegrationTest.java @@ -13,7 +13,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.ProgrammingExercise; import de.tum.in.www1.artemis.domain.ProgrammingExerciseTestCase; @@ -26,7 +26,7 @@ import de.tum.in.www1.artemis.repository.hestia.ProgrammingExerciseSolutionEntryRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class CodeHintIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class CodeHintIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "codehint"; diff --git a/src/test/java/de/tum/in/www1/artemis/hestia/CodeHintServiceTest.java b/src/test/java/de/tum/in/www1/artemis/hestia/CodeHintServiceTest.java index fc31fe05fe6f..a3556cc65288 100644 --- a/src/test/java/de/tum/in/www1/artemis/hestia/CodeHintServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/hestia/CodeHintServiceTest.java @@ -10,7 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.ProgrammingExercise; import de.tum.in.www1.artemis.domain.ProgrammingExerciseTestCase; @@ -27,7 +27,7 @@ import de.tum.in.www1.artemis.web.rest.errors.BadRequestAlertException; @SuppressWarnings("ArraysAsListWithZeroOrOneArgument") -class CodeHintServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class CodeHintServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "codehintservice"; diff --git a/src/test/java/de/tum/in/www1/artemis/hestia/ExerciseHintIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/hestia/ExerciseHintIntegrationTest.java index dbaf0eb83581..e05647ec8480 100644 --- a/src/test/java/de/tum/in/www1/artemis/hestia/ExerciseHintIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/hestia/ExerciseHintIntegrationTest.java @@ -11,7 +11,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.AssessmentType; import de.tum.in.www1.artemis.domain.enumeration.FeedbackType; @@ -30,7 +30,7 @@ import de.tum.in.www1.artemis.service.hestia.ProgrammingExerciseTaskService; import de.tum.in.www1.artemis.user.UserUtilService; -class ExerciseHintIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ExerciseHintIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "exercisehintintegration"; @@ -193,9 +193,10 @@ void rateActivatedHintForAnExerciseBadRequest() throws Exception { @Test @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER") void rateNotActivatedHintForAnExerciseForbidden() throws Exception { + long sizeBefore = exerciseHintActivationRepository.count(); request.postWithoutLocation("/api/programming-exercises/" + exercise.getId() + "/exercise-hints/" + exerciseHint.getId() + "/rating/" + 4, null, HttpStatus.NOT_FOUND, null); - assertThat(exerciseHintActivationRepository.count()).isZero(); + assertThat(exerciseHintActivationRepository.count()).isEqualTo(sizeBefore); } @Test diff --git a/src/test/java/de/tum/in/www1/artemis/hestia/ExerciseHintServiceTest.java b/src/test/java/de/tum/in/www1/artemis/hestia/ExerciseHintServiceTest.java index d25c4b1ca992..5dc1c38c1deb 100644 --- a/src/test/java/de/tum/in/www1/artemis/hestia/ExerciseHintServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/hestia/ExerciseHintServiceTest.java @@ -12,7 +12,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.AssessmentType; import de.tum.in.www1.artemis.domain.enumeration.FeedbackType; @@ -32,7 +32,7 @@ import de.tum.in.www1.artemis.service.hestia.ProgrammingExerciseTaskService; import de.tum.in.www1.artemis.user.UserUtilService; -class ExerciseHintServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ExerciseHintServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "exercisehintservice"; diff --git a/src/test/java/de/tum/in/www1/artemis/hestia/HestiaDatabaseTest.java b/src/test/java/de/tum/in/www1/artemis/hestia/HestiaDatabaseTest.java index c35d9e94ab31..3bdcdad52da6 100644 --- a/src/test/java/de/tum/in/www1/artemis/hestia/HestiaDatabaseTest.java +++ b/src/test/java/de/tum/in/www1/artemis/hestia/HestiaDatabaseTest.java @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.ProgrammingExercise; import de.tum.in.www1.artemis.domain.ProgrammingExerciseTestCase; @@ -30,7 +30,7 @@ * This currently includes ProgrammingExerciseTask, ProgrammingExerciseSolutionEntry and CodeHint. * It tests if the addition and deletion of these models works as expected. */ -class HestiaDatabaseTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class HestiaDatabaseTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "hestiadatabase"; diff --git a/src/test/java/de/tum/in/www1/artemis/hestia/ProgrammingExerciseSolutionEntryIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/hestia/ProgrammingExerciseSolutionEntryIntegrationTest.java index aa9fa024f0ab..b8a2864e6d76 100644 --- a/src/test/java/de/tum/in/www1/artemis/hestia/ProgrammingExerciseSolutionEntryIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/hestia/ProgrammingExerciseSolutionEntryIntegrationTest.java @@ -12,7 +12,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.ProgrammingExercise; import de.tum.in.www1.artemis.domain.ProgrammingExerciseTestCase; import de.tum.in.www1.artemis.domain.hestia.CodeHint; @@ -26,7 +26,7 @@ import de.tum.in.www1.artemis.repository.hestia.ProgrammingExerciseTaskRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class ProgrammingExerciseSolutionEntryIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ProgrammingExerciseSolutionEntryIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "progexsolutionentry"; diff --git a/src/test/java/de/tum/in/www1/artemis/hestia/ProgrammingExerciseTaskIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/hestia/ProgrammingExerciseTaskIntegrationTest.java index 2df5b20c9fa7..20b60d78d642 100644 --- a/src/test/java/de/tum/in/www1/artemis/hestia/ProgrammingExerciseTaskIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/hestia/ProgrammingExerciseTaskIntegrationTest.java @@ -11,7 +11,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.DomainObject; import de.tum.in.www1.artemis.domain.ProgrammingExercise; @@ -27,7 +27,7 @@ import de.tum.in.www1.artemis.service.hestia.ProgrammingExerciseTaskService; import de.tum.in.www1.artemis.user.UserUtilService; -class ProgrammingExerciseTaskIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ProgrammingExerciseTaskIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "progextask"; diff --git a/src/test/java/de/tum/in/www1/artemis/hestia/ProgrammingExerciseTaskServiceTest.java b/src/test/java/de/tum/in/www1/artemis/hestia/ProgrammingExerciseTaskServiceTest.java index fcb42d0b6d0d..6af86de04963 100644 --- a/src/test/java/de/tum/in/www1/artemis/hestia/ProgrammingExerciseTaskServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/hestia/ProgrammingExerciseTaskServiceTest.java @@ -10,7 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.ProgrammingExercise; import de.tum.in.www1.artemis.domain.ProgrammingExerciseTestCase; @@ -25,7 +25,7 @@ import de.tum.in.www1.artemis.service.hestia.ProgrammingExerciseTaskService; import de.tum.in.www1.artemis.user.UserUtilService; -class ProgrammingExerciseTaskServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ProgrammingExerciseTaskServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "progextaskservice"; diff --git a/src/test/java/de/tum/in/www1/artemis/hestia/TestwiseCoverageIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/hestia/TestwiseCoverageIntegrationTest.java index 6ea13cb715ce..2e0b2b5f61c7 100644 --- a/src/test/java/de/tum/in/www1/artemis/hestia/TestwiseCoverageIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/hestia/TestwiseCoverageIntegrationTest.java @@ -11,7 +11,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.ProgrammingExercise; import de.tum.in.www1.artemis.domain.ProgrammingExerciseTestCase; @@ -31,7 +31,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.util.RequestUtilService; -class TestwiseCoverageIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class TestwiseCoverageIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "testwisecoverageint"; diff --git a/src/test/java/de/tum/in/www1/artemis/hestia/behavioral/BehavioralTestCaseServiceTest.java b/src/test/java/de/tum/in/www1/artemis/hestia/behavioral/BehavioralTestCaseServiceTest.java index 0d54a0a94441..4eece5351289 100644 --- a/src/test/java/de/tum/in/www1/artemis/hestia/behavioral/BehavioralTestCaseServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/hestia/behavioral/BehavioralTestCaseServiceTest.java @@ -5,7 +5,9 @@ import java.io.IOException; import java.util.HashSet; -import org.junit.jupiter.api.*; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; @@ -18,7 +20,6 @@ import de.tum.in.www1.artemis.domain.hestia.*; import de.tum.in.www1.artemis.exercise.ExerciseUtilService; import de.tum.in.www1.artemis.exercise.programmingexercise.ProgrammingExerciseUtilService; -import de.tum.in.www1.artemis.repository.ProgrammingExerciseRepository; import de.tum.in.www1.artemis.repository.ProgrammingExerciseTestCaseRepository; import de.tum.in.www1.artemis.repository.SolutionProgrammingExerciseParticipationRepository; import de.tum.in.www1.artemis.repository.hestia.*; @@ -42,9 +43,6 @@ class BehavioralTestCaseServiceTest extends AbstractSpringIntegrationBambooBitbu @Autowired private ProgrammingExerciseTestCaseRepository testCaseRepository; - @Autowired - private ProgrammingExerciseRepository programmingExerciseRepository; - @Autowired private ProgrammingExerciseGitDiffReportRepository programmingExerciseGitDiffReportRepository; @@ -72,7 +70,7 @@ class BehavioralTestCaseServiceTest extends AbstractSpringIntegrationBambooBitbu private ProgrammingExercise exercise; @BeforeEach - void initTestCase() throws Exception { + void initTestCase() { userUtilService.addUsers(TEST_PREFIX, 0, 0, 0, 1); final Course course = programmingExerciseUtilService.addCourseWithOneProgrammingExercise(false, true, ProgrammingLanguage.JAVA); exercise = exerciseUtilService.getFirstExerciseWithType(course, ProgrammingExercise.class); @@ -148,7 +146,6 @@ private TestwiseCoverageReportEntry newCoverageReportEntry(int startLine, int li } @Test - @Timeout(1000) @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR") void testGenerationForSimpleExample() throws Exception { exercise = hestiaUtilTestService.setupSolution("Test.java", "A\nB\nC\nD\nE\nF\nG\nH", exercise, solutionRepo); diff --git a/src/test/java/de/tum/in/www1/artemis/iris/AbstractIrisIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/iris/AbstractIrisIntegrationTest.java index d6893a13f9f8..f2ccfa6cdfab 100644 --- a/src/test/java/de/tum/in/www1/artemis/iris/AbstractIrisIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/iris/AbstractIrisIntegrationTest.java @@ -55,6 +55,8 @@ public abstract class AbstractIrisIntegrationTest extends AbstractSpringIntegrat @Autowired protected ProgrammingExerciseUtilService programmingExerciseUtilService; + private static final long TIMEOUT_MS = 200; + @BeforeEach void setup() { irisRequestMockProvider.enableMockingOfRequests(); @@ -99,15 +101,6 @@ protected IrisTemplate createDummyTemplate() { return template; } - /** - * Wait for the iris message to be processed by Iris, the LLM mock and the websocket service. - * - * @throws InterruptedException if the thread is interrupted - */ - protected void waitForIrisMessageToBeProcessed() throws InterruptedException { - Thread.sleep(100); - } - /** * Verify that the message was sent through the websocket. * @@ -116,7 +109,7 @@ protected void waitForIrisMessageToBeProcessed() throws InterruptedException { * @param message the content of the message */ protected void verifyMessageWasSentOverWebsocket(String user, Long sessionId, String message) { - verify(websocketMessagingService, times(1)).sendMessageToUser(eq(user), eq("/topic/iris/sessions/" + sessionId), + verify(websocketMessagingService, timeout(TIMEOUT_MS).times(1)).sendMessageToUser(eq(user), eq("/topic/iris/sessions/" + sessionId), ArgumentMatchers.argThat(object -> object instanceof IrisWebsocketService.IrisWebsocketDTO websocketDTO && websocketDTO.getType() == IrisWebsocketService.IrisWebsocketDTO.IrisWebsocketMessageType.MESSAGE && Objects.equals(websocketDTO.getMessage().getContent().stream().map(IrisMessageContent::getTextContent).collect(Collectors.joining("\n")), message))); @@ -130,7 +123,7 @@ protected void verifyMessageWasSentOverWebsocket(String user, Long sessionId, St * @param message the message */ protected void verifyMessageWasSentOverWebsocket(String user, Long sessionId, IrisMessage message) { - verify(websocketMessagingService, times(1)).sendMessageToUser(eq(user), eq("/topic/iris/sessions/" + sessionId), + verify(websocketMessagingService, timeout(TIMEOUT_MS).times(1)).sendMessageToUser(eq(user), eq("/topic/iris/sessions/" + sessionId), ArgumentMatchers.argThat(object -> object instanceof IrisWebsocketService.IrisWebsocketDTO websocketDTO && websocketDTO.getType() == IrisWebsocketService.IrisWebsocketDTO.IrisWebsocketMessageType.MESSAGE && Objects.equals(websocketDTO.getMessage().getContent().stream().map(IrisMessageContent::getTextContent).toList(), @@ -144,7 +137,7 @@ protected void verifyMessageWasSentOverWebsocket(String user, Long sessionId, Ir * @param sessionId the session id */ protected void verifyErrorWasSentOverWebsocket(String user, Long sessionId) { - verify(websocketMessagingService, times(1)).sendMessageToUser(eq(user), eq("/topic/iris/sessions/" + sessionId), + verify(websocketMessagingService, timeout(TIMEOUT_MS).times(1)).sendMessageToUser(eq(user), eq("/topic/iris/sessions/" + sessionId), ArgumentMatchers.argThat(object -> object instanceof IrisWebsocketService.IrisWebsocketDTO websocketDTO && websocketDTO.getType() == IrisWebsocketService.IrisWebsocketDTO.IrisWebsocketMessageType.ERROR)); } diff --git a/src/test/java/de/tum/in/www1/artemis/iris/IrisMessageIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/iris/IrisMessageIntegrationTest.java index a9fd6c76e075..6ce1fea32261 100644 --- a/src/test/java/de/tum/in/www1/artemis/iris/IrisMessageIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/iris/IrisMessageIntegrationTest.java @@ -84,9 +84,7 @@ void sendOneMessage() throws Exception { // Compare contents of messages by only comparing the textContent field assertThat(irisMessage.getContent()).hasSize(3).map(IrisMessageContent::getTextContent) .isEqualTo(messageToSend.getContent().stream().map(IrisMessageContent::getTextContent).toList()); - var irisSessionFromDb = irisSessionRepository.findByIdWithMessagesElseThrow(irisSession.getId()); - assertThat(irisSessionFromDb.getMessages()).hasSize(1).isEqualTo(List.of(irisMessage)); - await().until(() -> irisSessionRepository.findByIdWithMessagesElseThrow(irisSession.getId()).getMessages().size() == 2); + await().untilAsserted(() -> assertThat(irisSessionRepository.findByIdWithMessagesElseThrow(irisSession.getId()).getMessages()).hasSize(2).contains(irisMessage)); verifyMessageWasSentOverWebsocket(TEST_PREFIX + "student1", irisSession.getId(), messageToSend); verifyMessageWasSentOverWebsocket(TEST_PREFIX + "student1", irisSession.getId(), "Hello World"); @@ -249,7 +247,6 @@ void sendOneMessageBadRequest() throws Exception { request.postWithResponseBody("/api/iris/sessions/" + irisSession.getId() + "/messages", messageToSend, IrisMessage.class, HttpStatus.CREATED); - waitForIrisMessageToBeProcessed(); verifyMessageWasSentOverWebsocket(TEST_PREFIX + "student1", irisSession.getId(), messageToSend); verifyErrorWasSentOverWebsocket(TEST_PREFIX + "student1", irisSession.getId()); verifyNothingElseWasSentOverWebsocket(TEST_PREFIX + "student1", irisSession.getId()); @@ -269,7 +266,6 @@ void sendOneMessageEmptyBody() throws Exception { request.postWithResponseBody("/api/iris/sessions/" + irisSession.getId() + "/messages", messageToSend, IrisMessage.class, HttpStatus.CREATED); - waitForIrisMessageToBeProcessed(); verifyMessageWasSentOverWebsocket(TEST_PREFIX + "student1", irisSession.getId(), messageToSend); verifyErrorWasSentOverWebsocket(TEST_PREFIX + "student1", irisSession.getId()); verifyNothingElseWasSentOverWebsocket(TEST_PREFIX + "student1", irisSession.getId()); diff --git a/src/test/java/de/tum/in/www1/artemis/lecture/AttachmentResourceIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/lecture/AttachmentResourceIntegrationTest.java index 8be636335cc2..3cbe1a819a11 100644 --- a/src/test/java/de/tum/in/www1/artemis/lecture/AttachmentResourceIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/lecture/AttachmentResourceIntegrationTest.java @@ -14,14 +14,14 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.util.LinkedMultiValueMap; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.exercise.ExerciseUtilService; import de.tum.in.www1.artemis.exercise.textexercise.TextExerciseUtilService; import de.tum.in.www1.artemis.repository.*; import de.tum.in.www1.artemis.user.UserUtilService; -class AttachmentResourceIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class AttachmentResourceIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "attachmentresourceintegrationtest"; diff --git a/src/test/java/de/tum/in/www1/artemis/lecture/AttachmentUnitIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/lecture/AttachmentUnitIntegrationTest.java index c0f29bd5e4b3..859e98c44c64 100644 --- a/src/test/java/de/tum/in/www1/artemis/lecture/AttachmentUnitIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/lecture/AttachmentUnitIntegrationTest.java @@ -28,7 +28,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Attachment; import de.tum.in.www1.artemis.domain.Lecture; import de.tum.in.www1.artemis.domain.lecture.AttachmentUnit; @@ -38,7 +38,7 @@ import de.tum.in.www1.artemis.security.SecurityUtils; import de.tum.in.www1.artemis.user.UserUtilService; -class AttachmentUnitIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class AttachmentUnitIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "attachmentunitintegrationtest"; // only lower case is supported diff --git a/src/test/java/de/tum/in/www1/artemis/lecture/AttachmentUnitsIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/lecture/AttachmentUnitsIntegrationTest.java index dea2195856dd..16ee82a1dbe2 100644 --- a/src/test/java/de/tum/in/www1/artemis/lecture/AttachmentUnitsIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/lecture/AttachmentUnitsIntegrationTest.java @@ -20,7 +20,7 @@ import org.springframework.mock.web.MockMultipartFile; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Lecture; import de.tum.in.www1.artemis.domain.lecture.AttachmentUnit; import de.tum.in.www1.artemis.repository.AttachmentUnitRepository; @@ -30,7 +30,7 @@ import de.tum.in.www1.artemis.web.rest.dto.LectureUnitInformationDTO; import de.tum.in.www1.artemis.web.rest.dto.LectureUnitSplitDTO; -class AttachmentUnitsIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class AttachmentUnitsIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "attachmentunitsintegrationtest"; diff --git a/src/test/java/de/tum/in/www1/artemis/lecture/CompetencyIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/lecture/CompetencyIntegrationTest.java index ee3c632b2a28..eb3a1cefd33e 100644 --- a/src/test/java/de/tum/in/www1/artemis/lecture/CompetencyIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/lecture/CompetencyIntegrationTest.java @@ -19,7 +19,7 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.util.LinkedMultiValueMap; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationLocalCILocalVCTest; import de.tum.in.www1.artemis.competency.CompetencyUtilService; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; @@ -45,7 +45,7 @@ import de.tum.in.www1.artemis.util.PageableSearchUtilService; import de.tum.in.www1.artemis.web.rest.dto.CourseCompetencyProgressDTO; -class CompetencyIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class CompetencyIntegrationTest extends AbstractSpringIntegrationLocalCILocalVCTest { private static final String TEST_PREFIX = "competencyintegrationtest"; diff --git a/src/test/java/de/tum/in/www1/artemis/lecture/ExerciseUnitIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/lecture/ExerciseUnitIntegrationTest.java index 19386db708ac..aab5f77c5bbd 100644 --- a/src/test/java/de/tum/in/www1/artemis/lecture/ExerciseUnitIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/lecture/ExerciseUnitIntegrationTest.java @@ -12,7 +12,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.lecture.ExerciseUnit; @@ -21,7 +21,7 @@ import de.tum.in.www1.artemis.repository.*; import de.tum.in.www1.artemis.user.UserUtilService; -class ExerciseUnitIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ExerciseUnitIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "exerciseunitintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/lecture/LectureIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/lecture/LectureIntegrationTest.java index 176374aa3f27..39c7bad09090 100644 --- a/src/test/java/de/tum/in/www1/artemis/lecture/LectureIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/lecture/LectureIntegrationTest.java @@ -14,7 +14,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.lecture.*; @@ -25,7 +25,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.util.PageableSearchUtilService; -class LectureIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class LectureIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "lectureintegrationtest"; diff --git a/src/test/java/de/tum/in/www1/artemis/lecture/LectureUnitIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/lecture/LectureUnitIntegrationTest.java index dbd732522b5e..4a89a196cbdd 100644 --- a/src/test/java/de/tum/in/www1/artemis/lecture/LectureUnitIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/lecture/LectureUnitIntegrationTest.java @@ -12,7 +12,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.competency.CompetencyUtilService; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; @@ -23,7 +23,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.web.rest.dto.lectureunit.LectureUnitForLearningPathNodeDetailsDTO; -class LectureUnitIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class LectureUnitIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "lectureunitintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/lecture/OnlineUnitIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/lecture/OnlineUnitIntegrationTest.java index 3447da7411a1..a09199424c15 100644 --- a/src/test/java/de/tum/in/www1/artemis/lecture/OnlineUnitIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/lecture/OnlineUnitIntegrationTest.java @@ -20,7 +20,7 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.util.LinkedMultiValueMap; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Lecture; import de.tum.in.www1.artemis.domain.lecture.LectureUnit; import de.tum.in.www1.artemis.domain.lecture.OnlineUnit; @@ -29,7 +29,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.web.rest.dto.OnlineResourceDTO; -class OnlineUnitIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class OnlineUnitIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "onlineunitintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/lecture/TextUnitIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/lecture/TextUnitIntegrationTest.java index 99eb0e2328c3..09715dba3702 100644 --- a/src/test/java/de/tum/in/www1/artemis/lecture/TextUnitIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/lecture/TextUnitIntegrationTest.java @@ -10,7 +10,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Lecture; import de.tum.in.www1.artemis.domain.lecture.LectureUnit; import de.tum.in.www1.artemis.domain.lecture.TextUnit; @@ -18,7 +18,7 @@ import de.tum.in.www1.artemis.repository.TextUnitRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class TextUnitIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class TextUnitIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "textunitintegrationtest"; diff --git a/src/test/java/de/tum/in/www1/artemis/lecture/VideoUnitIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/lecture/VideoUnitIntegrationTest.java index 01b3e1efd40b..aea03a64a163 100644 --- a/src/test/java/de/tum/in/www1/artemis/lecture/VideoUnitIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/lecture/VideoUnitIntegrationTest.java @@ -10,7 +10,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Lecture; import de.tum.in.www1.artemis.domain.lecture.LectureUnit; import de.tum.in.www1.artemis.domain.lecture.VideoUnit; @@ -18,7 +18,7 @@ import de.tum.in.www1.artemis.repository.VideoUnitRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class VideoUnitIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class VideoUnitIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "videounitintegrationtest"; diff --git a/src/test/java/de/tum/in/www1/artemis/metis/AbstractConversationTest.java b/src/test/java/de/tum/in/www1/artemis/metis/AbstractConversationTest.java index 6707bc6680d7..e26368f0e914 100644 --- a/src/test/java/de/tum/in/www1/artemis/metis/AbstractConversationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/metis/AbstractConversationTest.java @@ -1,7 +1,6 @@ package de.tum.in.www1.artemis.metis; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.Arrays; @@ -12,7 +11,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.User; @@ -36,7 +35,7 @@ /** * Contains useful methods for testing the conversations futures */ -abstract class AbstractConversationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +abstract class AbstractConversationTest extends AbstractSpringIntegrationIndependentTest { @Autowired CourseRepository courseRepository; diff --git a/src/test/java/de/tum/in/www1/artemis/metis/AnswerMessageIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/metis/AnswerMessageIntegrationTest.java index 927c34d2e253..aefa041fef28 100644 --- a/src/test/java/de/tum/in/www1/artemis/metis/AnswerMessageIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/metis/AnswerMessageIntegrationTest.java @@ -11,7 +11,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.enumeration.CourseInformationSharingConfiguration; @@ -24,7 +24,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.web.websocket.dto.metis.PostDTO; -class AnswerMessageIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class AnswerMessageIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "answermessageint"; diff --git a/src/test/java/de/tum/in/www1/artemis/metis/AnswerPostIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/metis/AnswerPostIntegrationTest.java index 70866f2704dd..fc9a1ba726bc 100644 --- a/src/test/java/de/tum/in/www1/artemis/metis/AnswerPostIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/metis/AnswerPostIntegrationTest.java @@ -12,7 +12,7 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.util.LinkedMultiValueMap; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.User; @@ -28,7 +28,7 @@ import de.tum.in.www1.artemis.repository.metis.PostRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class AnswerPostIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class AnswerPostIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "answerpostintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/metis/MessageIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/metis/MessageIntegrationTest.java index b20df00ae957..551fb0134afb 100644 --- a/src/test/java/de/tum/in/www1/artemis/metis/MessageIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/metis/MessageIntegrationTest.java @@ -33,7 +33,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.enumeration.CourseInformationSharingConfiguration; @@ -55,7 +55,7 @@ import de.tum.in.www1.artemis.web.rest.dto.PostContextFilter; import de.tum.in.www1.artemis.web.websocket.dto.metis.PostDTO; -class MessageIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class MessageIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "messageintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/metis/PostIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/metis/PostIntegrationTest.java index 6f7c2963d94f..2565bbae5729 100644 --- a/src/test/java/de/tum/in/www1/artemis/metis/PostIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/metis/PostIntegrationTest.java @@ -22,7 +22,7 @@ import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationLocalCILocalVCTest; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.CourseInformationSharingConfiguration; import de.tum.in.www1.artemis.domain.enumeration.DisplayPriority; @@ -40,7 +40,7 @@ import de.tum.in.www1.artemis.web.rest.dto.PostContextFilter; import de.tum.in.www1.artemis.web.websocket.dto.metis.PostDTO; -class PostIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class PostIntegrationTest extends AbstractSpringIntegrationLocalCILocalVCTest { private static final String TEST_PREFIX = "postintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/metis/ReactionIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/metis/ReactionIntegrationTest.java index 5d19715f8d7e..1484c025dd32 100644 --- a/src/test/java/de/tum/in/www1/artemis/metis/ReactionIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/metis/ReactionIntegrationTest.java @@ -20,7 +20,7 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.util.LinkedMultiValueMap; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.User; @@ -35,7 +35,7 @@ import de.tum.in.www1.artemis.repository.metis.ReactionRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class ReactionIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ReactionIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "reactionintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/migration/MigrationIntegrityTest.java b/src/test/java/de/tum/in/www1/artemis/migration/MigrationIntegrityTest.java index 334a38704447..e54b9155663b 100644 --- a/src/test/java/de/tum/in/www1/artemis/migration/MigrationIntegrityTest.java +++ b/src/test/java/de/tum/in/www1/artemis/migration/MigrationIntegrityTest.java @@ -7,12 +7,12 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.config.migration.MigrationEntry; import de.tum.in.www1.artemis.config.migration.MigrationRegistry; import de.tum.in.www1.artemis.config.migration.MigrationService; -class MigrationIntegrityTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class MigrationIntegrityTest extends AbstractSpringIntegrationIndependentTest { @Autowired private MigrationRegistry migrationRegistry; diff --git a/src/test/java/de/tum/in/www1/artemis/migration/MigrationServiceTest.java b/src/test/java/de/tum/in/www1/artemis/migration/MigrationServiceTest.java index 80cd24fe66c4..baeecfeea6c8 100644 --- a/src/test/java/de/tum/in/www1/artemis/migration/MigrationServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/migration/MigrationServiceTest.java @@ -20,7 +20,7 @@ import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Profiles; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.config.migration.MigrationEntry; import de.tum.in.www1.artemis.config.migration.MigrationIntegrityException; import de.tum.in.www1.artemis.config.migration.MigrationRegistry; @@ -31,7 +31,7 @@ import de.tum.in.www1.artemis.migration.entries.TestChangeEntry20211216_231800; import de.tum.in.www1.artemis.repository.MigrationChangeRepository; -class MigrationServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class MigrationServiceTest extends AbstractSpringIntegrationIndependentTest { @Autowired private MigrationRegistry registry; diff --git a/src/test/java/de/tum/in/www1/artemis/notification/GroupNotificationServiceTest.java b/src/test/java/de/tum/in/www1/artemis/notification/GroupNotificationServiceTest.java index 763e5cdf0842..23c1f6f6e5ac 100644 --- a/src/test/java/de/tum/in/www1/artemis/notification/GroupNotificationServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/notification/GroupNotificationServiceTest.java @@ -17,7 +17,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.QuizMode; @@ -34,7 +34,7 @@ import de.tum.in.www1.artemis.service.notifications.GroupNotificationScheduleService; import de.tum.in.www1.artemis.user.UserUtilService; -class GroupNotificationServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class GroupNotificationServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "groupnotificationservice"; diff --git a/src/test/java/de/tum/in/www1/artemis/notification/NotificationResourceIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/notification/NotificationResourceIntegrationTest.java index 9a03abf776b6..3b77aaf360d7 100644 --- a/src/test/java/de/tum/in/www1/artemis/notification/NotificationResourceIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/notification/NotificationResourceIntegrationTest.java @@ -12,7 +12,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.NotificationSetting; import de.tum.in.www1.artemis.domain.User; @@ -26,7 +26,7 @@ import de.tum.in.www1.artemis.repository.*; import de.tum.in.www1.artemis.user.UserUtilService; -class NotificationResourceIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class NotificationResourceIntegrationTest extends AbstractSpringIntegrationIndependentTest { @Autowired private CourseRepository courseRepository; @@ -37,9 +37,6 @@ class NotificationResourceIntegrationTest extends AbstractSpringIntegrationBambo @Autowired private NotificationRepository notificationRepository; - @Autowired - private SystemNotificationRepository systemNotificationRepository; - @Autowired private NotificationSettingRepository notificationSettingRepository; @@ -60,7 +57,7 @@ void initTestCase() { userUtilService.addUsers(TEST_PREFIX, 2, 1, 1, 1); course1 = textExerciseUtilService.addCourseWithOneReleasedTextExercise(); course2 = textExerciseUtilService.addCourseWithOneReleasedTextExercise(); - systemNotificationRepository.deleteAll(); + notificationRepository.deleteAll(); User student1 = userUtilService.getUserByLogin(TEST_PREFIX + "student1"); student1.setLastNotificationRead(ZonedDateTime.now().minusDays(1)); @@ -69,7 +66,6 @@ void initTestCase() { @AfterEach void tearDown() { - systemNotificationRepository.deleteAll(); notificationRepository.deleteAll(); } diff --git a/src/test/java/de/tum/in/www1/artemis/notification/NotificationScheduleServiceTest.java b/src/test/java/de/tum/in/www1/artemis/notification/NotificationScheduleServiceTest.java index 1db66bc4a57d..6571cb625394 100644 --- a/src/test/java/de/tum/in/www1/artemis/notification/NotificationScheduleServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/notification/NotificationScheduleServiceTest.java @@ -12,24 +12,20 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationLocalCILocalVCTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.AssessmentType; -import de.tum.in.www1.artemis.exercise.ExerciseUtilService; +import de.tum.in.www1.artemis.exercise.textexercise.TextExerciseFactory; import de.tum.in.www1.artemis.participation.ParticipationUtilService; -import de.tum.in.www1.artemis.repository.ExerciseRepository; -import de.tum.in.www1.artemis.repository.NotificationRepository; -import de.tum.in.www1.artemis.repository.NotificationSettingRepository; -import de.tum.in.www1.artemis.repository.ResultRepository; +import de.tum.in.www1.artemis.repository.*; import de.tum.in.www1.artemis.service.messaging.InstanceMessageReceiveService; import de.tum.in.www1.artemis.user.UserUtilService; -class NotificationScheduleServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class NotificationScheduleServiceTest extends AbstractSpringIntegrationLocalCILocalVCTest { private static final String TEST_PREFIX = "notificationschedserv"; @@ -54,9 +50,6 @@ class NotificationScheduleServiceTest extends AbstractSpringIntegrationBambooBit @Autowired private CourseUtilService courseUtilService; - @Autowired - private ExerciseUtilService exerciseUtilService; - @Autowired private ParticipationUtilService participationUtilService; @@ -64,35 +57,42 @@ class NotificationScheduleServiceTest extends AbstractSpringIntegrationBambooBit private User user; + private long sizeBefore; + + // TODO: This could be improved by e.g. manually setting the system time instead of waiting for actual time to pass. + private static final long DELAY_MS = 200; + + private static final long TIMEOUT_MS = 5000; + @BeforeEach void init() { userUtilService.addUsers(TEST_PREFIX, 1, 1, 1, 1); user = userUtilService.getUserByLogin(TEST_PREFIX + "student1"); - final Course course = courseUtilService.addCourseWithModelingAndTextExercise(); - exercise = exerciseUtilService.getFirstExerciseWithType(course, TextExercise.class); - exercise.setReleaseDate(now().plus(500, ChronoUnit.MILLIS)); - exercise.setAssessmentDueDate(now().plus(2, ChronoUnit.SECONDS)); - exerciseRepository.save(exercise); + final Course course = courseUtilService.addEmptyCourse(); + exercise = TextExerciseFactory.generateTextExercise(null, null, null, course); + exercise.setMaxPoints(5.0); + exerciseRepository.saveAndFlush(exercise); + doNothing().when(javaMailSender).send(any(MimeMessage.class)); + sizeBefore = notificationRepository.count(); } @Test - @Timeout(10) @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR") void shouldCreateNotificationAndEmailAtReleaseDate() { - long sizeBefore = notificationRepository.count(); - notificationSettingRepository.save(new NotificationSetting(user, true, true, true, NOTIFICATION__EXERCISE_NOTIFICATION__EXERCISE_RELEASED)); + notificationSettingRepository.saveAndFlush(new NotificationSetting(user, true, true, true, NOTIFICATION__EXERCISE_NOTIFICATION__EXERCISE_RELEASED)); + exercise.setReleaseDate(now().plus(DELAY_MS, ChronoUnit.MILLIS)); + exerciseRepository.saveAndFlush(exercise); + instanceMessageReceiveService.processScheduleExerciseReleasedNotification(exercise.getId()); await().until(() -> notificationRepository.count() > sizeBefore); - verify(groupNotificationService, timeout(4000)).notifyAllGroupsAboutReleasedExercise(exercise); - verify(mailService, timeout(4000).atLeastOnce()).sendNotification(any(), anySet(), any()); + verify(groupNotificationService, timeout(TIMEOUT_MS)).notifyAllGroupsAboutReleasedExercise(exercise); + verify(mailService, timeout(TIMEOUT_MS).atLeastOnce()).sendNotification(any(), anySet(), any()); } @Test - @Timeout(10) @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR") void shouldCreateNotificationAndEmailAtAssessmentDueDate() { - long sizeBefore = notificationRepository.count(); TextSubmission textSubmission = new TextSubmission(); textSubmission.text("Text"); textSubmission.submitted(true); @@ -101,14 +101,15 @@ void shouldCreateNotificationAndEmailAtAssessmentDueDate() { Result manualResult = participationUtilService.createParticipationSubmissionAndResult(exercise.getId(), userUtilService.getUserByLogin(TEST_PREFIX + "student1"), 10.0, 10.0, 50, true); manualResult.setAssessmentType(AssessmentType.MANUAL); - resultRepository.save(manualResult); - - notificationSettingRepository.save(new NotificationSetting(user, true, true, true, NOTIFICATION__EXERCISE_NOTIFICATION__EXERCISE_SUBMISSION_ASSESSED)); + resultRepository.saveAndFlush(manualResult); + notificationSettingRepository.saveAndFlush(new NotificationSetting(user, true, true, true, NOTIFICATION__EXERCISE_NOTIFICATION__EXERCISE_SUBMISSION_ASSESSED)); + exercise.setAssessmentDueDate(now().plus(DELAY_MS, ChronoUnit.MILLIS)); + exerciseRepository.saveAndFlush(exercise); instanceMessageReceiveService.processScheduleAssessedExerciseSubmittedNotification(exercise.getId()); await().until(() -> notificationRepository.count() > sizeBefore); - verify(singleUserNotificationService, timeout(4000)).notifyUsersAboutAssessedExerciseSubmission(exercise); - verify(javaMailSender, timeout(4000)).send(any(MimeMessage.class)); + verify(singleUserNotificationService, timeout(TIMEOUT_MS)).notifyUsersAboutAssessedExerciseSubmission(exercise); + verify(javaMailSender, timeout(TIMEOUT_MS)).send(any(MimeMessage.class)); } } diff --git a/src/test/java/de/tum/in/www1/artemis/notification/NotificationSettingsResourceIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/notification/NotificationSettingsResourceIntegrationTest.java index 10124449f739..781366b1c1ab 100644 --- a/src/test/java/de/tum/in/www1/artemis/notification/NotificationSettingsResourceIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/notification/NotificationSettingsResourceIntegrationTest.java @@ -12,13 +12,13 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.NotificationSetting; import de.tum.in.www1.artemis.domain.User; import de.tum.in.www1.artemis.repository.*; import de.tum.in.www1.artemis.user.UserUtilService; -class NotificationSettingsResourceIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class NotificationSettingsResourceIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "notificationsettingsresourrce"; diff --git a/src/test/java/de/tum/in/www1/artemis/notification/NotificationSettingsServiceTest.java b/src/test/java/de/tum/in/www1/artemis/notification/NotificationSettingsServiceTest.java index 234e5d810c54..210025e43b83 100644 --- a/src/test/java/de/tum/in/www1/artemis/notification/NotificationSettingsServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/notification/NotificationSettingsServiceTest.java @@ -13,7 +13,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.NotificationSetting; import de.tum.in.www1.artemis.domain.User; import de.tum.in.www1.artemis.domain.enumeration.NotificationType; @@ -26,7 +26,7 @@ import de.tum.in.www1.artemis.service.notifications.NotificationSettingsService; import de.tum.in.www1.artemis.user.UserUtilService; -class NotificationSettingsServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class NotificationSettingsServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "notificationsettingsservice"; diff --git a/src/test/java/de/tum/in/www1/artemis/notification/PushNotificationResourceTest.java b/src/test/java/de/tum/in/www1/artemis/notification/PushNotificationResourceTest.java index 29480a01bc34..cc285c3a5a51 100644 --- a/src/test/java/de/tum/in/www1/artemis/notification/PushNotificationResourceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/notification/PushNotificationResourceTest.java @@ -13,7 +13,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.User; import de.tum.in.www1.artemis.domain.push_notification.PushNotificationDeviceConfiguration; import de.tum.in.www1.artemis.domain.push_notification.PushNotificationDeviceType; @@ -25,7 +25,7 @@ import de.tum.in.www1.artemis.web.rest.push_notification.PushNotificationUnregisterRequest; @TestInstance(TestInstance.Lifecycle.PER_CLASS) -class PushNotificationResourceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class PushNotificationResourceTest extends AbstractSpringIntegrationIndependentTest { @Autowired UserRepository userRepository; diff --git a/src/test/java/de/tum/in/www1/artemis/notification/SingleUserNotificationServiceTest.java b/src/test/java/de/tum/in/www1/artemis/notification/SingleUserNotificationServiceTest.java index 85b8bd5a1aaa..527781793ed0 100644 --- a/src/test/java/de/tum/in/www1/artemis/notification/SingleUserNotificationServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/notification/SingleUserNotificationServiceTest.java @@ -29,7 +29,7 @@ import org.mockito.Captor; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.AssessmentType; @@ -60,7 +60,7 @@ import de.tum.in.www1.artemis.service.notifications.SingleUserNotificationService; import de.tum.in.www1.artemis.user.UserUtilService; -class SingleUserNotificationServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class SingleUserNotificationServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "singleusernotification"; diff --git a/src/test/java/de/tum/in/www1/artemis/notification/SystemNotificationIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/notification/SystemNotificationIntegrationTest.java index f2339c306a2d..caad0cffd0af 100644 --- a/src/test/java/de/tum/in/www1/artemis/notification/SystemNotificationIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/notification/SystemNotificationIntegrationTest.java @@ -13,11 +13,11 @@ import org.springframework.security.test.context.support.WithAnonymousUser; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.notification.SystemNotification; import de.tum.in.www1.artemis.repository.SystemNotificationRepository; -class SystemNotificationIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class SystemNotificationIntegrationTest extends AbstractSpringIntegrationIndependentTest { @Autowired private SystemNotificationRepository systemNotificationRepo; diff --git a/src/test/java/de/tum/in/www1/artemis/participation/ParticipationIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/participation/ParticipationIntegrationTest.java index 9ce2281ef9b4..4a3a054f64cc 100644 --- a/src/test/java/de/tum/in/www1/artemis/participation/ParticipationIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/participation/ParticipationIntegrationTest.java @@ -7,21 +7,16 @@ import java.time.ZonedDateTime; import java.util.*; import java.util.stream.IntStream; -import java.util.stream.Stream; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.parallel.Isolated; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.EnumSource; -import org.junit.jupiter.params.provider.MethodSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.util.LinkedMultiValueMap; @@ -45,9 +40,9 @@ import de.tum.in.www1.artemis.exercise.textexercise.TextExerciseFactory; import de.tum.in.www1.artemis.exercise.textexercise.TextExerciseUtilService; import de.tum.in.www1.artemis.repository.*; -import de.tum.in.www1.artemis.security.SecurityUtils; import de.tum.in.www1.artemis.service.GradingScaleService; import de.tum.in.www1.artemis.service.ParticipationService; +import de.tum.in.www1.artemis.service.QuizBatchService; import de.tum.in.www1.artemis.service.feature.Feature; import de.tum.in.www1.artemis.service.feature.FeatureToggleService; import de.tum.in.www1.artemis.service.scheduled.cache.quiz.QuizScheduleService; @@ -83,7 +78,7 @@ class ParticipationIntegrationTest extends AbstractSpringIntegrationBambooBitbuc private ParticipationService participationService; @Autowired - private QuizExerciseUtilService quizUtilService; + private QuizBatchService quizBatchService; @Autowired protected QuizScheduleService quizScheduleService; @@ -1239,20 +1234,6 @@ void getParticipation_quizExerciseStartedAndNoParticipation(QuizMode quizMode) t request.getNullable("/api/exercises/" + quizEx.getId() + "/participation", HttpStatus.NO_CONTENT, StudentParticipation.class); } - @ParameterizedTest(name = "{displayName} [{index}] {argumentsWithNames}") - @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER") - @EnumSource(QuizMode.class) - void getParticipation_quizExerciseStartedAndSubmissionAllowed(QuizMode quizMode) throws Exception { - var quizEx = QuizExerciseFactory.generateQuizExercise(ZonedDateTime.now().minusMinutes(1), ZonedDateTime.now().plusMinutes(5), quizMode, course).duration(360); - quizEx = exerciseRepo.save(quizEx); - quizUtilService.prepareBatchForSubmitting(quizEx, SecurityUtils.makeAuthorizationObject(TEST_PREFIX + "instructor1"), - SecurityContextHolder.getContext().getAuthentication()); - var participation = request.get("/api/exercises/" + quizEx.getId() + "/participation", HttpStatus.OK, StudentParticipation.class); - assertThat(participation.getExercise()).as("Participation contains exercise").isEqualTo(quizEx); - assertThat(participation.getResults()).as("New result was added to the participation").hasSize(1); - assertThat(participation.getInitializationState()).as("Participation was initialized").isEqualTo(InitializationState.INITIALIZED); - } - @Test @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER") void getParticipation_quizBatchNotPresent() throws Exception { @@ -1292,17 +1273,14 @@ void getParticipation_notStudentInCourse() throws Exception { @ParameterizedTest @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER") - @MethodSource("getGetParticipationsubmittedNotEndedQuizParameters") - void getParticipation_submittedNotEndedQuiz(QuizMode quizMode, boolean isSubmissionAllowed) throws Exception { - QuizExercise quizExercise = QuizExerciseFactory.generateQuizExercise(ZonedDateTime.now().minusMinutes(10), ZonedDateTime.now().plusMinutes(10), quizMode, course); + @EnumSource(QuizMode.class) + void testCheckQuizParticipation(QuizMode quizMode) throws Exception { + QuizExercise quizExercise = QuizExerciseFactory.generateQuizExercise(ZonedDateTime.now().minusMinutes(10), ZonedDateTime.now().minusMinutes(8), quizMode, course); quizExercise.addQuestions(QuizExerciseFactory.createShortAnswerQuestion()); quizExercise.setDuration(600); quizExercise.setQuizPointStatistic(new QuizPointStatistic()); quizExercise = exerciseRepo.save(quizExercise); - quizUtilService.prepareBatchForSubmitting(quizExercise, SecurityUtils.makeAuthorizationObject(TEST_PREFIX + "instructor1"), - SecurityContextHolder.getContext().getAuthentication()); - ShortAnswerQuestion saQuestion = (ShortAnswerQuestion) quizExercise.getQuizQuestions().get(0); List spots = saQuestion.getSpots(); ShortAnswerSubmittedAnswer submittedAnswer = new ShortAnswerSubmittedAnswer(); @@ -1315,24 +1293,15 @@ void getParticipation_submittedNotEndedQuiz(QuizMode quizMode, boolean isSubmiss QuizSubmission quizSubmission = new QuizSubmission(); quizSubmission.addSubmittedAnswers(submittedAnswer); - request.postWithResponseBody("/api/exercises/" + quizExercise.getId() + "/submissions/live", quizSubmission, QuizSubmission.class, HttpStatus.OK); - - quizScheduleService.processCachedQuizSubmissions(); - - if (!isSubmissionAllowed) { - // Duration is set to 0 so that QuizBatch.isSubmissionAllowed() will be false - quizExercise.setDuration(0); - quizExercise = exerciseRepo.save(quizExercise); - } + quizSubmission.submitted(true); + participationUtilService.addSubmission(quizExercise, quizSubmission, TEST_PREFIX + "student1"); + participationUtilService.addResultToSubmission(quizSubmission, AssessmentType.AUTOMATIC, null, quizExercise.getScoreForSubmission(quizSubmission), true); var actualParticipation = request.get("/api/exercises/" + quizExercise.getId() + "/participation", HttpStatus.OK, StudentParticipation.class); - assertThat(actualParticipation.getInitializationState()).isEqualTo(InitializationState.FINISHED); - var actualResults = actualParticipation.getResults(); assertThat(actualResults).hasSize(1); var actualSubmission = (QuizSubmission) actualResults.stream().findFirst().get().getSubmission(); - assertThat(actualSubmission.getType()).isEqualTo(SubmissionType.MANUAL); assertThat(actualSubmission.isSubmitted()).isTrue(); var actualSubmittedAnswers = actualSubmission.getSubmittedAnswers(); @@ -1347,8 +1316,25 @@ void getParticipation_submittedNotEndedQuiz(QuizMode quizMode, boolean isSubmiss assertThat(actualSubmittedAnswerText.isIsCorrect()).isFalse(); } - private static Stream getGetParticipationsubmittedNotEndedQuizParameters() { - return Stream.of(Arguments.of(QuizMode.SYNCHRONIZED, true), Arguments.of(QuizMode.SYNCHRONIZED, false), Arguments.of(QuizMode.BATCHED, true), - Arguments.of(QuizMode.BATCHED, false), Arguments.of(QuizMode.INDIVIDUAL, true), Arguments.of(QuizMode.INDIVIDUAL, false)); + @Nested + @Isolated + class ParticipationIntegrationIsolatedTest { + + @ParameterizedTest(name = "{displayName} [{index}] {argumentsWithNames}") + @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER") + @EnumSource(QuizMode.class) + void getParticipation_quizExerciseStartedAndSubmissionAllowed(QuizMode quizMode) throws Exception { + var quizEx = QuizExerciseFactory.generateQuizExercise(ZonedDateTime.now().minusMinutes(1), ZonedDateTime.now().plusMinutes(5), quizMode, course).duration(360); + quizEx = exerciseRepo.save(quizEx); + + if (quizMode != QuizMode.SYNCHRONIZED) { + var batch = quizBatchService.save(QuizExerciseFactory.generateQuizBatch(quizEx, ZonedDateTime.now().minusSeconds(10))); + quizExerciseUtilService.joinQuizBatch(quizEx, batch, TEST_PREFIX + "student1"); + } + var participation = request.get("/api/exercises/" + quizEx.getId() + "/participation", HttpStatus.OK, StudentParticipation.class); + assertThat(participation.getExercise()).as("Participation contains exercise").isEqualTo(quizEx); + assertThat(participation.getResults()).as("New result was added to the participation").hasSize(1); + assertThat(participation.getInitializationState()).as("Participation was initialized").isEqualTo(InitializationState.INITIALIZED); + } } } diff --git a/src/test/java/de/tum/in/www1/artemis/participation/ParticipationSubmissionIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/participation/ParticipationSubmissionIntegrationTest.java index 199aaa45dfd2..7fdbd64f88e2 100644 --- a/src/test/java/de/tum/in/www1/artemis/participation/ParticipationSubmissionIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/participation/ParticipationSubmissionIntegrationTest.java @@ -10,7 +10,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.exercise.ExerciseUtilService; import de.tum.in.www1.artemis.exercise.textexercise.TextExerciseUtilService; @@ -18,7 +18,7 @@ import de.tum.in.www1.artemis.repository.SubmissionRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class ParticipationSubmissionIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ParticipationSubmissionIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "psitest"; // only lower case is supported diff --git a/src/test/java/de/tum/in/www1/artemis/participation/SubmissionExportIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/participation/SubmissionExportIntegrationTest.java index e78f6b6a03c5..aed64f17d927 100644 --- a/src/test/java/de/tum/in/www1/artemis/participation/SubmissionExportIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/participation/SubmissionExportIntegrationTest.java @@ -16,7 +16,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.Language; @@ -29,7 +29,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.web.rest.dto.SubmissionExportOptionsDTO; -class SubmissionExportIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class SubmissionExportIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "submissionexportintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/participation/SubmissionIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/participation/SubmissionIntegrationTest.java index bcc04db80603..b51e9e75d7e2 100644 --- a/src/test/java/de/tum/in/www1/artemis/participation/SubmissionIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/participation/SubmissionIntegrationTest.java @@ -8,7 +8,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.AssessmentType; @@ -22,7 +22,7 @@ import de.tum.in.www1.artemis.util.PageableSearchUtilService; import de.tum.in.www1.artemis.web.rest.dto.PageableSearchDTO; -class SubmissionIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class SubmissionIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "submissionintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/plagiarism/PlagiarismCaseIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/plagiarism/PlagiarismCaseIntegrationTest.java index 1e31ee3e488a..c73610e57567 100644 --- a/src/test/java/de/tum/in/www1/artemis/plagiarism/PlagiarismCaseIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/plagiarism/PlagiarismCaseIntegrationTest.java @@ -13,7 +13,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.exam.Exam; @@ -30,7 +30,7 @@ import de.tum.in.www1.artemis.web.rest.dto.PlagiarismCaseInfoDTO; import de.tum.in.www1.artemis.web.rest.dto.PlagiarismVerdictDTO; -class PlagiarismCaseIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class PlagiarismCaseIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "plagiarismcaseintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/plagiarism/PlagiarismCheckIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/plagiarism/PlagiarismCheckIntegrationTest.java index eee25e61421d..55bf34dbf463 100644 --- a/src/test/java/de/tum/in/www1/artemis/plagiarism/PlagiarismCheckIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/plagiarism/PlagiarismCheckIntegrationTest.java @@ -11,7 +11,7 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.util.LinkedMultiValueMap; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.TextExercise; import de.tum.in.www1.artemis.domain.modeling.ModelingExercise; @@ -20,7 +20,7 @@ import de.tum.in.www1.artemis.exercise.ExerciseUtilService; import de.tum.in.www1.artemis.util.FileUtils; -class PlagiarismCheckIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class PlagiarismCheckIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "plagiarismcheck"; diff --git a/src/test/java/de/tum/in/www1/artemis/plagiarism/PlagiarismIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/plagiarism/PlagiarismIntegrationTest.java index b93cd24f6567..6be418637f43 100644 --- a/src/test/java/de/tum/in/www1/artemis/plagiarism/PlagiarismIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/plagiarism/PlagiarismIntegrationTest.java @@ -11,7 +11,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.TextExercise; @@ -31,7 +31,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.web.rest.dto.PlagiarismComparisonStatusDTO; -class PlagiarismIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class PlagiarismIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "plagiarismintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/repository/StatisticsRepositoryTest.java b/src/test/java/de/tum/in/www1/artemis/repository/StatisticsRepositoryTest.java index 4b5ef06893e4..5634ce479334 100644 --- a/src/test/java/de/tum/in/www1/artemis/repository/StatisticsRepositoryTest.java +++ b/src/test/java/de/tum/in/www1/artemis/repository/StatisticsRepositoryTest.java @@ -15,7 +15,7 @@ import org.junit.jupiter.params.provider.EnumSource; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.PersistentAuditEvent; import de.tum.in.www1.artemis.domain.enumeration.GraphType; import de.tum.in.www1.artemis.domain.enumeration.SpanType; @@ -24,7 +24,7 @@ import de.tum.in.www1.artemis.security.SecurityUtils; import de.tum.in.www1.artemis.user.UserUtilService; -class StatisticsRepositoryTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class StatisticsRepositoryTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "statisticsrepository"; diff --git a/src/test/java/de/tum/in/www1/artemis/service/AssessmentServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/AssessmentServiceTest.java index 53895cf69960..822ee8487c62 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/AssessmentServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/AssessmentServiceTest.java @@ -15,7 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseFactory; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.DiagramType; @@ -36,7 +36,7 @@ import de.tum.in.www1.artemis.repository.ResultRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class AssessmentServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class AssessmentServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "assessmentservice"; diff --git a/src/test/java/de/tum/in/www1/artemis/service/BuildLogEntryServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/BuildLogEntryServiceTest.java index cbd61c178b7d..65831858ec52 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/BuildLogEntryServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/BuildLogEntryServiceTest.java @@ -14,11 +14,11 @@ import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.BuildLogEntry; import de.tum.in.www1.artemis.domain.enumeration.ProgrammingLanguage; -class BuildLogEntryServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class BuildLogEntryServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String GRADLE_SCENARIO = """ Build ABC23H01E01 - AB12345 - Default Job #5 (MY-JOB) started building on agent ls1Agent-test.artemistest.in.tum.de, bamboo version: 8.2.5 diff --git a/src/test/java/de/tum/in/www1/artemis/service/ComplaintResponseServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/ComplaintResponseServiceTest.java index 879ac8ad47da..f14b3f369639 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/ComplaintResponseServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/ComplaintResponseServiceTest.java @@ -9,7 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.assessment.ComplaintUtilService; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; @@ -22,7 +22,7 @@ import de.tum.in.www1.artemis.team.TeamUtilService; import de.tum.in.www1.artemis.user.UserUtilService; -class ComplaintResponseServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ComplaintResponseServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "complaintresponseservice"; diff --git a/src/test/java/de/tum/in/www1/artemis/service/CourseScoreCalculationServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/CourseScoreCalculationServiceTest.java index eff0610fdfcb..9b7b549de9ba 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/CourseScoreCalculationServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/CourseScoreCalculationServiceTest.java @@ -12,7 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.assessment.GradingScaleFactory; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; @@ -28,7 +28,7 @@ import de.tum.in.www1.artemis.web.rest.dto.CourseScoresDTO; import de.tum.in.www1.artemis.web.rest.dto.StudentScoresDTO; -class CourseScoreCalculationServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class CourseScoreCalculationServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "cscservicetest"; diff --git a/src/test/java/de/tum/in/www1/artemis/service/EmailSummaryServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/EmailSummaryServiceTest.java index 1a74cc9d8646..0945cd521c5f 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/EmailSummaryServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/EmailSummaryServiceTest.java @@ -17,7 +17,7 @@ import org.mockito.ArgumentCaptor; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.DifficultyLevel; @@ -27,7 +27,7 @@ import de.tum.in.www1.artemis.repository.NotificationSettingRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class EmailSummaryServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class EmailSummaryServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "emailsummaryservice"; diff --git a/src/test/java/de/tum/in/www1/artemis/service/ExerciseDateServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/ExerciseDateServiceTest.java index 6ea4e0ca6eb4..fc452f2ba014 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/ExerciseDateServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/ExerciseDateServiceTest.java @@ -11,7 +11,7 @@ import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.enumeration.DiagramType; import de.tum.in.www1.artemis.domain.exam.Exam; @@ -31,7 +31,7 @@ import de.tum.in.www1.artemis.security.SecurityUtils; import de.tum.in.www1.artemis.user.UserUtilService; -class ExerciseDateServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ExerciseDateServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "exercisedateservice"; diff --git a/src/test/java/de/tum/in/www1/artemis/service/ExerciseLifecycleServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/ExerciseLifecycleServiceTest.java index 50232ec49d7c..1c2b035a781f 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/ExerciseLifecycleServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/ExerciseLifecycleServiceTest.java @@ -11,12 +11,12 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Exercise; import de.tum.in.www1.artemis.domain.TextExercise; import de.tum.in.www1.artemis.domain.enumeration.ExerciseLifecycle; -class ExerciseLifecycleServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ExerciseLifecycleServiceTest extends AbstractSpringIntegrationIndependentTest { @Autowired private ExerciseLifecycleService exerciseLifecycleService; diff --git a/src/test/java/de/tum/in/www1/artemis/service/FeatureToggleServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/FeatureToggleServiceTest.java index 758b8fc2e204..4e07f0b2153a 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/FeatureToggleServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/FeatureToggleServiceTest.java @@ -9,11 +9,11 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.service.feature.Feature; import de.tum.in.www1.artemis.service.feature.FeatureToggleService; -class FeatureToggleServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class FeatureToggleServiceTest extends AbstractSpringIntegrationIndependentTest { @Autowired private FeatureToggleService featureToggleService; diff --git a/src/test/java/de/tum/in/www1/artemis/service/FeedbackServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/FeedbackServiceTest.java index 5259def297ac..a9e48217c5e1 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/FeedbackServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/FeedbackServiceTest.java @@ -5,13 +5,13 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.config.Constants; import de.tum.in.www1.artemis.domain.Feedback; import de.tum.in.www1.artemis.domain.LongFeedbackText; import de.tum.in.www1.artemis.repository.FeedbackRepository; -class FeedbackServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class FeedbackServiceTest extends AbstractSpringIntegrationIndependentTest { @Autowired private FeedbackService feedbackService; diff --git a/src/test/java/de/tum/in/www1/artemis/service/FileServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/FileServiceTest.java index 81f6c6d4cef7..c38321adb4a1 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/FileServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/FileServiceTest.java @@ -5,7 +5,9 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; -import java.io.*; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -25,9 +27,9 @@ import org.springframework.util.ResourceUtils; import org.springframework.web.multipart.MultipartFile; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; -class FileServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class FileServiceTest extends AbstractSpringIntegrationIndependentTest { @Autowired private ResourceLoaderService resourceLoaderService; diff --git a/src/test/java/de/tum/in/www1/artemis/service/GradingScaleServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/GradingScaleServiceTest.java index c8d7df1d058d..fb0aca636f3b 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/GradingScaleServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/GradingScaleServiceTest.java @@ -15,7 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.assessment.GradingScaleUtilService; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; @@ -30,7 +30,7 @@ import de.tum.in.www1.artemis.web.rest.errors.BadRequestAlertException; import de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException; -class GradingScaleServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class GradingScaleServiceTest extends AbstractSpringIntegrationIndependentTest { @Autowired private GradingScaleService gradingScaleService; diff --git a/src/test/java/de/tum/in/www1/artemis/service/LectureImportServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/LectureImportServiceTest.java index 28f20a5ccd45..264fa1646105 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/LectureImportServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/LectureImportServiceTest.java @@ -10,7 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Attachment; import de.tum.in.www1.artemis.domain.Course; @@ -22,7 +22,7 @@ import de.tum.in.www1.artemis.repository.LectureRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class LectureImportServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class LectureImportServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "lectureimport"; diff --git a/src/test/java/de/tum/in/www1/artemis/service/LectureServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/LectureServiceTest.java index bed4e1855747..b5fe10cefade 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/LectureServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/LectureServiceTest.java @@ -13,7 +13,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.lecture.LectureFactory; import de.tum.in.www1.artemis.lecture.LectureUtilService; @@ -24,7 +24,7 @@ import de.tum.in.www1.artemis.web.rest.dto.PageableSearchDTO; import de.tum.in.www1.artemis.web.rest.dto.SearchResultPageDTO; -class LectureServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class LectureServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "lservicetest"; diff --git a/src/test/java/de/tum/in/www1/artemis/service/ParticipationAuthorizationCheckServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/ParticipationAuthorizationCheckServiceTest.java index ac2fc33c1825..44009ed315dc 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/ParticipationAuthorizationCheckServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/ParticipationAuthorizationCheckServiceTest.java @@ -9,7 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.ProgrammingExercise; import de.tum.in.www1.artemis.domain.TextExercise; import de.tum.in.www1.artemis.domain.participation.ParticipationInterface; @@ -22,7 +22,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.web.rest.errors.AccessForbiddenException; -class ParticipationAuthorizationCheckServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ParticipationAuthorizationCheckServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "participationauthservice"; diff --git a/src/test/java/de/tum/in/www1/artemis/service/ParticipationLifecycleServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/ParticipationLifecycleServiceTest.java index eba717ea7718..61d5b54735f5 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/ParticipationLifecycleServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/ParticipationLifecycleServiceTest.java @@ -12,7 +12,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.ProgrammingExercise; import de.tum.in.www1.artemis.domain.enumeration.ParticipationLifecycle; @@ -23,7 +23,7 @@ import de.tum.in.www1.artemis.security.SecurityUtils; import de.tum.in.www1.artemis.user.UserUtilService; -class ParticipationLifecycleServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ParticipationLifecycleServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "partlcservice"; diff --git a/src/test/java/de/tum/in/www1/artemis/service/ParticipationTeamWebsocketServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/ParticipationTeamWebsocketServiceTest.java index 73bd3015cca2..0bf22e90f7c3 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/ParticipationTeamWebsocketServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/ParticipationTeamWebsocketServiceTest.java @@ -13,7 +13,7 @@ import org.springframework.messaging.simp.stomp.StompHeaderAccessor; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.modeling.ModelingExercise; import de.tum.in.www1.artemis.domain.participation.Participation; @@ -24,7 +24,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.web.websocket.team.ParticipationTeamWebsocketService; -class ParticipationTeamWebsocketServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ParticipationTeamWebsocketServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "participationteamwebsocket"; diff --git a/src/test/java/de/tum/in/www1/artemis/service/PresentationPointsCalculationServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/PresentationPointsCalculationServiceTest.java index 09e1f34130b5..5cea54fee584 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/PresentationPointsCalculationServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/PresentationPointsCalculationServiceTest.java @@ -7,7 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.assessment.GradingScaleFactory; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; @@ -22,7 +22,7 @@ import de.tum.in.www1.artemis.repository.StudentParticipationRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class PresentationPointsCalculationServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class PresentationPointsCalculationServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "ppcservicetest"; diff --git a/src/test/java/de/tum/in/www1/artemis/service/ResourceLoaderServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/ResourceLoaderServiceTest.java index a22c0ca0d053..549d78dd50c6 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/ResourceLoaderServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/ResourceLoaderServiceTest.java @@ -25,9 +25,9 @@ import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; -class ResourceLoaderServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ResourceLoaderServiceTest extends AbstractSpringIntegrationIndependentTest { @Autowired private ResourceLoaderService resourceLoaderService; diff --git a/src/test/java/de/tum/in/www1/artemis/service/ResultServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/ResultServiceTest.java index eeafd1404e59..a595692b57b2 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/ResultServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/ResultServiceTest.java @@ -12,7 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.Feedback; import de.tum.in.www1.artemis.domain.ProgrammingExercise; @@ -31,7 +31,7 @@ import de.tum.in.www1.artemis.repository.ProgrammingExerciseStudentParticipationRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class ResultServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ResultServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "resultservice"; diff --git a/src/test/java/de/tum/in/www1/artemis/service/SubmissionServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/SubmissionServiceTest.java index 4b039d29e335..e2f74d8cbed4 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/SubmissionServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/SubmissionServiceTest.java @@ -13,7 +13,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.assessment.ComplaintUtilService; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; @@ -31,7 +31,7 @@ import de.tum.in.www1.artemis.web.rest.dto.SubmissionWithComplaintDTO; import de.tum.in.www1.artemis.web.rest.errors.AccessForbiddenException; -class SubmissionServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class SubmissionServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "submissionservicetest"; // only lower case is supported diff --git a/src/test/java/de/tum/in/www1/artemis/service/TeamWebsocketServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/TeamWebsocketServiceTest.java index 45d150a0f2c8..9152aae542dd 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/TeamWebsocketServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/TeamWebsocketServiceTest.java @@ -14,7 +14,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.ExerciseMode; @@ -27,7 +27,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.web.websocket.dto.TeamAssignmentPayload; -class TeamWebsocketServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class TeamWebsocketServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "teamwebsocketservice"; diff --git a/src/test/java/de/tum/in/www1/artemis/service/TitleCacheEvictionServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/TitleCacheEvictionServiceTest.java index 5b9fe49d9702..ee2faa517e08 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/TitleCacheEvictionServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/TitleCacheEvictionServiceTest.java @@ -9,7 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.CacheManager; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.ProgrammingExercise; import de.tum.in.www1.artemis.domain.enumeration.DiagramType; @@ -30,7 +30,7 @@ * The service is not directly injected / used here as it listens to Hibernate events, so we just apply * CRUD operations on the entities it supports. */ -class TitleCacheEvictionServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class TitleCacheEvictionServiceTest extends AbstractSpringIntegrationIndependentTest { @Autowired private CacheManager cacheManager; diff --git a/src/test/java/de/tum/in/www1/artemis/service/UrlServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/UrlServiceTest.java index 29554d104d68..3c80424663c4 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/UrlServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/UrlServiceTest.java @@ -8,14 +8,14 @@ import org.junit.jupiter.api.Test; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.VcsRepositoryUrl; import de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation; import de.tum.in.www1.artemis.domain.participation.SolutionProgrammingExerciseParticipation; import de.tum.in.www1.artemis.domain.participation.TemplateProgrammingExerciseParticipation; import de.tum.in.www1.artemis.exception.VersionControlException; -class UrlServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class UrlServiceTest extends AbstractSpringIntegrationIndependentTest { private final VcsRepositoryUrl repositoryUrl1 = new VcsRepositoryUrl("https://ab12cde@bitbucket.ase.in.tum.de/scm/EIST2016RME/RMEXERCISE-ab12cde"); diff --git a/src/test/java/de/tum/in/www1/artemis/service/ZipFileServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/ZipFileServiceTest.java index d067e994ac28..b296f3eb4e9c 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/ZipFileServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/ZipFileServiceTest.java @@ -12,9 +12,9 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; -class ZipFileServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ZipFileServiceTest extends AbstractSpringIntegrationIndependentTest { @Autowired private ZipFileService zipFileService; diff --git a/src/test/java/de/tum/in/www1/artemis/service/exam/ExamAccessServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/exam/ExamAccessServiceTest.java index c949623d621f..7879349a1bb7 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/exam/ExamAccessServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/exam/ExamAccessServiceTest.java @@ -13,7 +13,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.User; @@ -31,7 +31,7 @@ import de.tum.in.www1.artemis.web.rest.errors.ConflictException; import de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException; -class ExamAccessServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ExamAccessServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "examaccessservicetest"; // only lower case is supported diff --git a/src/test/java/de/tum/in/www1/artemis/service/exam/ExamQuizServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/exam/ExamQuizServiceTest.java index 6b256958b001..4ebf28198f31 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/exam/ExamQuizServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/exam/ExamQuizServiceTest.java @@ -14,7 +14,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.enumeration.InitializationState; @@ -29,7 +29,7 @@ import de.tum.in.www1.artemis.service.QuizExerciseService; import de.tum.in.www1.artemis.user.UserUtilService; -class ExamQuizServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ExamQuizServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "eqservicetest"; diff --git a/src/test/java/de/tum/in/www1/artemis/service/exam/ExamServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/exam/ExamServiceTest.java index d4f24384c817..0b067e1267b9 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/exam/ExamServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/exam/ExamServiceTest.java @@ -13,7 +13,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.TextExercise; @@ -29,7 +29,7 @@ import de.tum.in.www1.artemis.web.rest.dto.ExamChecklistDTO; import de.tum.in.www1.artemis.web.rest.errors.BadRequestAlertException; -class ExamServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ExamServiceTest extends AbstractSpringIntegrationIndependentTest { @Autowired private ExamService examService; diff --git a/src/test/java/de/tum/in/www1/artemis/service/exam/ExamSubmissionServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/exam/ExamSubmissionServiceTest.java index dbd138dcb7e8..f2217fb1b452 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/exam/ExamSubmissionServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/exam/ExamSubmissionServiceTest.java @@ -10,7 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.Exercise; @@ -32,7 +32,7 @@ import de.tum.in.www1.artemis.web.rest.errors.AccessForbiddenException; import de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException; -class ExamSubmissionServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ExamSubmissionServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "esstest"; // only lower case is supported diff --git a/src/test/java/de/tum/in/www1/artemis/service/exam/StudentExamAccessServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/exam/StudentExamAccessServiceTest.java index b5200442b455..27de96ba7b44 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/exam/StudentExamAccessServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/exam/StudentExamAccessServiceTest.java @@ -10,7 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.User; @@ -24,7 +24,7 @@ import de.tum.in.www1.artemis.web.rest.errors.ConflictException; import de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException; -class StudentExamAccessServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class StudentExamAccessServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "seastest"; // only lower case is supported diff --git a/src/test/java/de/tum/in/www1/artemis/service/notifications/ConversationNotificationServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/notifications/ConversationNotificationServiceTest.java index 614c41470b7e..3af87124c965 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/notifications/ConversationNotificationServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/notifications/ConversationNotificationServiceTest.java @@ -15,7 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.DomainObject; @@ -33,7 +33,7 @@ import de.tum.in.www1.artemis.repository.metis.conversation.ConversationRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class ConversationNotificationServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ConversationNotificationServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "conversationnotificationservice"; diff --git a/src/test/java/de/tum/in/www1/artemis/service/notifications/TutorialGroupNotificationServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/notifications/TutorialGroupNotificationServiceTest.java index 6e2ea3d4930c..a6dd74b3baca 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/notifications/TutorialGroupNotificationServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/notifications/TutorialGroupNotificationServiceTest.java @@ -21,7 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.Language; @@ -38,7 +38,7 @@ import de.tum.in.www1.artemis.repository.tutorialgroups.TutorialGroupRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class TutorialGroupNotificationServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class TutorialGroupNotificationServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "tutorialgroupnotifservice"; diff --git a/src/test/java/de/tum/in/www1/artemis/service/programming/ProgrammingExerciseFeedbackCreationServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/programming/ProgrammingExerciseFeedbackCreationServiceTest.java index b198dbd50b7f..460fd2662a6f 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/programming/ProgrammingExerciseFeedbackCreationServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/programming/ProgrammingExerciseFeedbackCreationServiceTest.java @@ -9,7 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.config.Constants; import de.tum.in.www1.artemis.domain.Feedback; import de.tum.in.www1.artemis.domain.enumeration.ProgrammingLanguage; @@ -18,7 +18,7 @@ import de.tum.in.www1.artemis.exercise.programmingexercise.ProgrammingExerciseFactory; import de.tum.in.www1.artemis.service.dto.StaticCodeAnalysisReportDTO; -class ProgrammingExerciseFeedbackCreationServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class ProgrammingExerciseFeedbackCreationServiceTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "progexfeedbackcreaiontest"; diff --git a/src/test/java/de/tum/in/www1/artemis/service/scheduled/PushNotificationDeviceConfigurationCleanupServiceTest.java b/src/test/java/de/tum/in/www1/artemis/service/scheduled/PushNotificationDeviceConfigurationCleanupServiceTest.java index 67695bdffd5a..70f760a28185 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/scheduled/PushNotificationDeviceConfigurationCleanupServiceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/scheduled/PushNotificationDeviceConfigurationCleanupServiceTest.java @@ -10,14 +10,14 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.domain.User; import de.tum.in.www1.artemis.domain.push_notification.PushNotificationDeviceConfiguration; import de.tum.in.www1.artemis.domain.push_notification.PushNotificationDeviceType; import de.tum.in.www1.artemis.repository.PushNotificationDeviceConfigurationRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class PushNotificationDeviceConfigurationCleanupServiceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class PushNotificationDeviceConfigurationCleanupServiceTest extends AbstractSpringIntegrationIndependentTest { @Autowired private PushNotificationDeviceConfigurationRepository deviceConfigurationRepository; diff --git a/src/test/java/de/tum/in/www1/artemis/service/scheduled/cache/quiz/QuizCacheTest.java b/src/test/java/de/tum/in/www1/artemis/service/scheduled/cache/quiz/QuizCacheTest.java index 37ae07649b47..4789b09607f9 100644 --- a/src/test/java/de/tum/in/www1/artemis/service/scheduled/cache/quiz/QuizCacheTest.java +++ b/src/test/java/de/tum/in/www1/artemis/service/scheduled/cache/quiz/QuizCacheTest.java @@ -1,14 +1,22 @@ package de.tum.in.www1.artemis.service.scheduled.cache.quiz; import static de.tum.in.www1.artemis.service.scheduled.cache.quiz.QuizCache.HAZELCAST_CACHED_EXERCISE_UPDATE_TOPIC; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.verify; +import java.security.Principal; import java.time.ZonedDateTime; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Isolated; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.EnumSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -16,21 +24,26 @@ import com.hazelcast.core.HazelcastInstance; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.Result; import de.tum.in.www1.artemis.domain.enumeration.QuizMode; +import de.tum.in.www1.artemis.domain.quiz.QuizBatch; import de.tum.in.www1.artemis.domain.quiz.QuizExercise; import de.tum.in.www1.artemis.domain.quiz.QuizSubmission; import de.tum.in.www1.artemis.exercise.quizexercise.QuizExerciseFactory; import de.tum.in.www1.artemis.exercise.quizexercise.QuizExerciseUtilService; +import de.tum.in.www1.artemis.participation.ParticipationUtilService; import de.tum.in.www1.artemis.repository.QuizExerciseRepository; +import de.tum.in.www1.artemis.repository.QuizSubmissionRepository; import de.tum.in.www1.artemis.service.QuizBatchService; import de.tum.in.www1.artemis.service.QuizExerciseService; import de.tum.in.www1.artemis.user.UserUtilService; +import de.tum.in.www1.artemis.web.websocket.QuizSubmissionWebsocketService; -class QuizCacheTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +@Isolated +class QuizCacheTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "quizcachetest"; @@ -55,6 +68,15 @@ class QuizCacheTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { @Autowired private QuizExerciseRepository quizExerciseRepository; + @Autowired + QuizSubmissionWebsocketService quizSubmissionWebsocketService; + + @Autowired + QuizSubmissionRepository submissionRepository; + + @Autowired + ParticipationUtilService participationUtilService; + @BeforeEach void init() { // do not use the schedule service based on a time interval in the tests, because this would result in flaky tests that run much slower @@ -97,4 +119,55 @@ void testQuizSubmitNoDatabaseRequests(QuizMode quizMode) throws Exception { assertThatDb(() -> request.postWithResponseBody("/api/exercises/" + exerciseId + "/submissions/live", quizSubmission, Result.class, HttpStatus.OK)) .hasBeenCalledTimes(quizMode == QuizMode.SYNCHRONIZED ? 0 : 1); } + + @ParameterizedTest(name = "{displayName} [{index}] {argumentsWithNames}") + @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER") + @CsvSource({ "true,true", "true,false", "false,true", "false,false" }) + void testProcessSubmission(boolean submitted, boolean deleted) { + QuizExercise quizExercise = quizExerciseUtilService.createQuiz(ZonedDateTime.now().minusMinutes(1), null, QuizMode.SYNCHRONIZED); + quizExercise.duration(240); + quizExerciseRepository.save(quizExercise); + + QuizSubmission quizSubmission = QuizExerciseFactory.generateSubmissionForThreeQuestions(quizExercise, 1, submitted, null); + String username = TEST_PREFIX + "student1"; + Principal principal = () -> username; + + quizSubmissionWebsocketService.saveSubmission(quizExercise.getId(), quizSubmission, principal); + if (deleted) { + quizExerciseRepository.delete(quizExercise); + } + quizScheduleService.processCachedQuizSubmissions(); + assertThat(submissionRepository.findByParticipation_Exercise_Id(quizExercise.getId())).hasSize(submitted && !deleted ? 1 : 0); + } + + @ParameterizedTest(name = "{displayName} [{index}] {argumentsWithNames}") + @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER") + @CsvSource({ "true,true", "true,false", "false,true", "false,false" }) + void testQuizBatchEnded(boolean quizEnded, boolean batchEnded) { + QuizExercise quizExercise = quizExerciseUtilService.createQuiz(ZonedDateTime.now().minusMinutes(2), quizEnded ? ZonedDateTime.now().minusMinutes(1) : null, + QuizMode.BATCHED); + quizExercise.duration(batchEnded ? 5 : 3600); + quizExerciseRepository.save(quizExercise); + + var batch = quizBatchService.save(QuizExerciseFactory.generateQuizBatch(quizExercise, ZonedDateTime.now().minusMinutes(1))); + quizExerciseUtilService.joinQuizBatch(quizExercise, batch, TEST_PREFIX + "student1"); + + quizScheduleService.processCachedQuizSubmissions(); + + assertThat(submissionRepository.findByParticipation_Exercise_Id(quizExercise.getId())).hasSize(batchEnded ? 1 : 0); + } + + @Test + @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER") + void testQuizNewParticipationAndStatistics() { + QuizExercise quizExercise = quizExerciseUtilService.createQuiz(ZonedDateTime.now().minusMinutes(2), ZonedDateTime.now().minusMinutes(1), QuizMode.SYNCHRONIZED); + quizExercise.duration(5); + quizExerciseService.save(quizExercise); + + QuizBatch batch = quizBatchService.save(QuizExerciseFactory.generateQuizBatch(quizExercise, ZonedDateTime.now().minusMinutes(1))); + quizExerciseUtilService.joinQuizBatch(quizExercise, batch, TEST_PREFIX + "student1"); + + quizScheduleService.processCachedQuizSubmissions(); + verify(websocketMessagingService, timeout(3000)).sendMessageToUser(any(), any(), any()); + } } diff --git a/src/test/java/de/tum/in/www1/artemis/team/TeamImportIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/team/TeamImportIntegrationTest.java index 5a8d8fe9cab5..2efa091f3fc5 100644 --- a/src/test/java/de/tum/in/www1/artemis/team/TeamImportIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/team/TeamImportIntegrationTest.java @@ -14,7 +14,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.ExerciseMode; @@ -23,7 +23,7 @@ import de.tum.in.www1.artemis.repository.*; import de.tum.in.www1.artemis.user.UserUtilService; -class TeamImportIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class TeamImportIntegrationTest extends AbstractSpringIntegrationIndependentTest { @Autowired private CourseRepository courseRepo; diff --git a/src/test/java/de/tum/in/www1/artemis/team/TeamIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/team/TeamIntegrationTest.java index 4480cd86a5f3..b692c72f7f97 100644 --- a/src/test/java/de/tum/in/www1/artemis/team/TeamIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/team/TeamIntegrationTest.java @@ -13,7 +13,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.ExerciseMode; @@ -30,7 +30,7 @@ import de.tum.in.www1.artemis.user.UserUtilService; import de.tum.in.www1.artemis.web.rest.dto.CourseForDashboardDTO; -class TeamIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class TeamIntegrationTest extends AbstractSpringIntegrationIndependentTest { @Autowired private CourseRepository courseRepo; diff --git a/src/test/java/de/tum/in/www1/artemis/text/AssessmentEventIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/text/AssessmentEventIntegrationTest.java index ce9541bb838b..febe53d52064 100644 --- a/src/test/java/de/tum/in/www1/artemis/text/AssessmentEventIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/text/AssessmentEventIntegrationTest.java @@ -10,7 +10,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.Course; import de.tum.in.www1.artemis.domain.Exercise; @@ -26,7 +26,7 @@ import de.tum.in.www1.artemis.repository.UserRepository; import de.tum.in.www1.artemis.user.UserUtilService; -class AssessmentEventIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class AssessmentEventIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "assessmentevent"; diff --git a/src/test/java/de/tum/in/www1/artemis/text/TextExerciseIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/text/TextExerciseIntegrationTest.java index 75c1cd83c89c..f7db1a2b9e44 100644 --- a/src/test/java/de/tum/in/www1/artemis/text/TextExerciseIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/text/TextExerciseIntegrationTest.java @@ -19,7 +19,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.*; @@ -48,7 +48,7 @@ import de.tum.in.www1.artemis.web.rest.dto.CourseForDashboardDTO; import de.tum.in.www1.artemis.web.rest.dto.PlagiarismComparisonStatusDTO; -class TextExerciseIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class TextExerciseIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "textexerciseintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/text/TextSubmissionIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/text/TextSubmissionIntegrationTest.java index 8f98694994fb..214c1028a87c 100644 --- a/src/test/java/de/tum/in/www1/artemis/text/TextSubmissionIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/text/TextSubmissionIntegrationTest.java @@ -15,7 +15,7 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; import de.tum.in.www1.artemis.config.Constants; import de.tum.in.www1.artemis.domain.*; import de.tum.in.www1.artemis.domain.enumeration.AssessmentType; @@ -41,7 +41,7 @@ import de.tum.in.www1.artemis.web.rest.errors.BadRequestAlertException; import de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException; -class TextSubmissionIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class TextSubmissionIntegrationTest extends AbstractSpringIntegrationIndependentTest { private static final String TEST_PREFIX = "textsubmissionintegration"; diff --git a/src/test/java/de/tum/in/www1/artemis/tutorialgroups/AbstractTutorialGroupIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/tutorialgroups/AbstractTutorialGroupIntegrationTest.java index 1ecd0ae8f185..4d8b9266e026 100644 --- a/src/test/java/de/tum/in/www1/artemis/tutorialgroups/AbstractTutorialGroupIntegrationTest.java +++ b/src/test/java/de/tum/in/www1/artemis/tutorialgroups/AbstractTutorialGroupIntegrationTest.java @@ -14,7 +14,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationLocalCILocalVCTest; import de.tum.in.www1.artemis.course.CourseTestService; import de.tum.in.www1.artemis.course.CourseUtilService; import de.tum.in.www1.artemis.domain.User; @@ -35,7 +35,7 @@ /** * Contains useful methods for testing the tutorial groups feature. */ -abstract class AbstractTutorialGroupIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +abstract class AbstractTutorialGroupIntegrationTest extends AbstractSpringIntegrationLocalCILocalVCTest { @Autowired CourseTestService courseTestService; diff --git a/src/test/java/de/tum/in/www1/artemis/util/junit_extensions/ParallelLoggingExtension.java b/src/test/java/de/tum/in/www1/artemis/util/junit_extensions/ParallelLoggingExtension.java new file mode 100644 index 000000000000..12da0d403cb0 --- /dev/null +++ b/src/test/java/de/tum/in/www1/artemis/util/junit_extensions/ParallelLoggingExtension.java @@ -0,0 +1,42 @@ +package de.tum.in.www1.artemis.util.junit_extensions; + +import static org.awaitility.Awaitility.await; + +import org.junit.jupiter.api.extension.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import de.tum.in.www1.artemis.util.junit_parallel_logging.ParallelConsoleAppender; + +/** + * A JUnit 5 extension that uses {@link ParallelConsoleAppender} to collect logs from parallel test execution. + *

+ * This extension is used to add structural information to the logs, e.g. to indicate the start and end of a test class. At the end of the test class, the collected logs from + * {@link ParallelConsoleAppender} get printed to the console. + */ +public class ParallelLoggingExtension implements BeforeAllCallback, BeforeEachCallback, AfterAllCallback { + + @Override + public void beforeAll(ExtensionContext context) { + Class testClass = context.getRequiredTestClass(); + ParallelConsoleAppender.registerActiveTestGroup(testClass); + ParallelConsoleAppender.addStringToLogsForGroup("\nStarting logs for " + testClass.getSimpleName() + "\n"); + + // Wait until the logger is initialized + await().until(() -> LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME) instanceof ch.qos.logback.classic.Logger); + } + + @Override + public void beforeEach(ExtensionContext context) throws Exception { + ParallelConsoleAppender.addStringToLogsForGroup("\n Starting logs for " + context.getRequiredTestClass().getSimpleName() + " > " + context.getDisplayName() + "\n"); + } + + @Override + public void afterAll(ExtensionContext context) { + Class testClass = context.getRequiredTestClass(); + ParallelConsoleAppender.addStringToLogsForGroup("\nFinished logs for " + testClass.getSimpleName() + "\n"); + ParallelConsoleAppender.printLogsForGroup(testClass); + ParallelConsoleAppender.unregisterActiveTestGroup(testClass); + } + +} diff --git a/src/test/java/de/tum/in/www1/artemis/util/junit_parallel_logging/ParallelConsoleAppender.java b/src/test/java/de/tum/in/www1/artemis/util/junit_parallel_logging/ParallelConsoleAppender.java new file mode 100644 index 000000000000..c22c66e90dff --- /dev/null +++ b/src/test/java/de/tum/in/www1/artemis/util/junit_parallel_logging/ParallelConsoleAppender.java @@ -0,0 +1,159 @@ +package de.tum.in.www1.artemis.util.junit_parallel_logging; + +import static org.assertj.core.api.Assertions.fail; + +import java.io.ByteArrayOutputStream; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import ch.qos.logback.classic.encoder.PatternLayoutEncoder; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.AppenderBase; +import de.tum.in.www1.artemis.*; +import de.tum.in.www1.artemis.util.AbstractArtemisIntegrationTest; + +/** + * This custom appender is used to capture the logs of multiple tests running in parallel. + *

+ * It captures the logs for each test group separately and prints them to the console at the end of the test class. + * The test group is determined by the test's class. Each test class can only be assigned to one test group. + * If a log cannot be assigned to a test group, the logs are printed for all active test groups. + */ +public class ParallelConsoleAppender extends AppenderBase { + + private PatternLayoutEncoder encoder; + + private static final InheritableThreadLocal> LOCAL_TEST_GROUP = new InheritableThreadLocal<>(); + + private static final ConcurrentMap, ByteArrayOutputStream> TEST_GROUP_TO_ENCODED_LOGS = new ConcurrentHashMap<>(); + + private static final Set> TEST_GROUPS = Set.of(AbstractSpringIntegrationBambooBitbucketJiraTest.class, AbstractSpringIntegrationGitlabCIGitlabSamlTest.class, + AbstractSpringIntegrationJenkinsGitlabTest.class, AbstractSpringIntegrationLocalCILocalVCTest.class, AbstractSpringIntegrationIndependentTest.class); + + @Override + protected synchronized void append(ILoggingEvent loggingEvent) { + Class testClass = LOCAL_TEST_GROUP.get(); + + // Add the logging Event to the corresponding List in the Map + if (testClass != null && !loggingEvent.getThreadName().contains("event")) { + if (TEST_GROUP_TO_ENCODED_LOGS.containsKey(testClass)) { + TEST_GROUP_TO_ENCODED_LOGS.get(testClass).writeBytes(encoder.encode(loggingEvent)); + } + else { + ByteArrayOutputStream logs = new ByteArrayOutputStream(); + logs.writeBytes(encoder.encode(loggingEvent)); + TEST_GROUP_TO_ENCODED_LOGS.put(testClass, logs); + } + return; + } + + // If the thread id is not assigned to a TestGroup, we add the logging event for all active TestGroups + for (ByteArrayOutputStream logs : TEST_GROUP_TO_ENCODED_LOGS.values()) { + logs.writeBytes(encoder.encode(loggingEvent)); + } + } + + /** + * Prints the logs for the given test group to the console and removes them. + * This method should be called at the end of a test class. + * + * @param testClass the test's class for which the logs should be printed + */ + public static synchronized void printLogsForGroup(Class testClass) { + Class testGroupClass = groupFromClass(testClass); + ByteArrayOutputStream logs = TEST_GROUP_TO_ENCODED_LOGS.remove(testGroupClass); + if (logs == null) { + return; + } + + System.out.writeBytes(logs.toByteArray()); + logs.reset(); + System.out.flush(); + } + + /** + * Adds the given string to the logs for the current test group. + * + * @param string the string to add to the logs + */ + public static synchronized void addStringToLogsForGroup(String string) { + Class testClass = LOCAL_TEST_GROUP.get(); + + // Add the logging Event to the corresponding List in the Map + if (testClass != null) { + if (TEST_GROUP_TO_ENCODED_LOGS.containsKey(testClass)) { + TEST_GROUP_TO_ENCODED_LOGS.get(testClass).writeBytes(string.getBytes()); + } + else { + ByteArrayOutputStream logs = new ByteArrayOutputStream(); + logs.writeBytes(string.getBytes()); + TEST_GROUP_TO_ENCODED_LOGS.put(testClass, logs); + } + return; + } + + // If the thread id is not assigned to a TestGroup, we add the logging event for all active TestGroups + for (ByteArrayOutputStream logs : TEST_GROUP_TO_ENCODED_LOGS.values()) { + logs.writeBytes(string.getBytes()); + } + + } + + /** + * Registers the test group for the given test class. + * This method should be called at the beginning of a test class. + * + * @param testClass the test's class + */ + public static void registerActiveTestGroup(Class testClass) { + LOCAL_TEST_GROUP.set(groupFromClass(testClass)); + } + + /** + * Unregisters the test group for the given test class. + * This method should be called at the end of a test class. + * + * @param testClass the test's class + */ + public static void unregisterActiveTestGroup(Class testClass) { + TEST_GROUP_TO_ENCODED_LOGS.remove(testClass); + LOCAL_TEST_GROUP.remove(); + } + + /** + * Sets the encoder for this appender. This method is used by logback and should not be removed. + * This method is used to set the encoder's pattern in the logback.xml file. + * + * @param encoder the encoder used to encode the logging events + */ + @SuppressWarnings("unused") + public void setEncoder(PatternLayoutEncoder encoder) { + this.encoder = encoder; + } + + /** + * Returns the test group's class for the given class. + * If none of the groups' classes is assignable from the given class, the class itself is returned. + * + * @param clazz the class for which the test group's class should be returned + * @return the test group's class for the given class + */ + private static Class groupFromClass(Class clazz) { + if (clazz == null) { + return null; + } + + for (Class group : TEST_GROUPS) { + if (group.isAssignableFrom(clazz)) { + return group; + } + } + + if (AbstractArtemisIntegrationTest.class.isAssignableFrom(clazz)) { + fail("Test class " + clazz.getName() + " extends ArtemisIntegrationTest but is not assigned to a test group"); + } + + return clazz; + } +} diff --git a/src/test/java/de/tum/in/www1/artemis/util/junit_parallel_logging/ThreadIdConverter.java b/src/test/java/de/tum/in/www1/artemis/util/junit_parallel_logging/ThreadIdConverter.java new file mode 100644 index 000000000000..cfd9d1653db7 --- /dev/null +++ b/src/test/java/de/tum/in/www1/artemis/util/junit_parallel_logging/ThreadIdConverter.java @@ -0,0 +1,17 @@ +package de.tum.in.www1.artemis.util.junit_parallel_logging; + +import ch.qos.logback.classic.pattern.ClassicConverter; +import ch.qos.logback.classic.spi.ILoggingEvent; + +/** + * A custom Logback converter that can be used to display the thread id in the logs. + *

+ * This converter is used to distinguish logs from different threads when running tests in parallel. + */ +public class ThreadIdConverter extends ClassicConverter { + + @Override + public String convert(ILoggingEvent iLoggingEvent) { + return String.valueOf(Thread.currentThread().getId()); + } +} diff --git a/src/test/java/de/tum/in/www1/artemis/web/rest/AndroidAppSiteAssociationResourceTest.java b/src/test/java/de/tum/in/www1/artemis/web/rest/AndroidAppSiteAssociationResourceTest.java index 3798e8fb431e..6762f1ab3503 100644 --- a/src/test/java/de/tum/in/www1/artemis/web/rest/AndroidAppSiteAssociationResourceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/web/rest/AndroidAppSiteAssociationResourceTest.java @@ -7,9 +7,9 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; -class AndroidAppSiteAssociationResourceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class AndroidAppSiteAssociationResourceTest extends AbstractSpringIntegrationIndependentTest { @Autowired AndroidAppSiteAssociationResource androidAppSiteAssociationResource; diff --git a/src/test/java/de/tum/in/www1/artemis/web/rest/AppleAppSiteAssociationResourceTest.java b/src/test/java/de/tum/in/www1/artemis/web/rest/AppleAppSiteAssociationResourceTest.java index 74ad5fe60bea..fc89211686d4 100644 --- a/src/test/java/de/tum/in/www1/artemis/web/rest/AppleAppSiteAssociationResourceTest.java +++ b/src/test/java/de/tum/in/www1/artemis/web/rest/AppleAppSiteAssociationResourceTest.java @@ -5,9 +5,9 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest; +import de.tum.in.www1.artemis.AbstractSpringIntegrationIndependentTest; -class AppleAppSiteAssociationResourceTest extends AbstractSpringIntegrationBambooBitbucketJiraTest { +class AppleAppSiteAssociationResourceTest extends AbstractSpringIntegrationIndependentTest { @Autowired AppleAppSiteAssociationResource appleAppSiteAssociationResource; diff --git a/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension b/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension index 7fc53e343616..8dfc3c5b68c1 100644 --- a/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension +++ b/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension @@ -1 +1,2 @@ de.tum.in.www1.artemis.util.junit_extensions.AwaitilityExtension +de.tum.in.www1.artemis.util.junit_extensions.ParallelLoggingExtension diff --git a/src/test/resources/junit-platform.properties b/src/test/resources/junit-platform.properties index bbcb24682b30..a2754a0609bb 100644 --- a/src/test/resources/junit-platform.properties +++ b/src/test/resources/junit-platform.properties @@ -1,6 +1,8 @@ -#junit.jupiter.execution.parallel.enabled = true -#junit.jupiter.execution.parallel.mode.default = concurrent -#junit.jupiter.execution.parallel.mode.classes.default = same_thread +# Enables junit5 parallel test execution. Tests are run on one JVM instance. +junit.jupiter.execution.parallel.enabled = true + +# Enables ordering test-classes with JUnit5 by class name. +junit.jupiter.testclass.order.default = org.junit.jupiter.api.ClassOrderer$ClassName # Enables JUnit5 automatic detection of extensions. junit.jupiter.extensions.autodetection.enabled = true diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml index 0adc98c942a1..f51816ce443b 100644 --- a/src/test/resources/logback.xml +++ b/src/test/resources/logback.xml @@ -2,7 +2,15 @@ - + + + + + + + %16.16d{HH:mm:ss.SSS} | %3.3threadId %-16.16thread | %-5level | %-36.36logger{36} : %msg%n + + @@ -37,7 +45,7 @@ WARN - + diff --git a/supporting_scripts/flaky_test_detection.sh b/supporting_scripts/flaky_test_detection.sh new file mode 100644 index 000000000000..ec941b0b240e --- /dev/null +++ b/supporting_scripts/flaky_test_detection.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +# Check for the number of test runs argument. +if [ $# -eq 0 ]; then + echo "Usage: $0 " + exit 1 +fi + +# Get the number of test runs from the command line argument. +NUM_RUNS="$1" + +# Define spring profiles. +SPRING_PROFILES=("none" "mysql" "postgres") + +DIRECTORY='./build/flaky-test-detection-results' + +# Create the directory, if it doesn't exist. +mkdir -p ${DIRECTORY} + +# ==================== # +# FLAKY TEST DETECTION # +# ==================== # + +for ((run = 1; run <= NUM_RUNS; run++)); do + # Generate a random number between 1 and 13. + spring_profile_chance=$((RANDOM % 13 + 1)) + + # Determine the active spring profile based on the random number: + # 10/13 chance of no profile, 2/13 chance of MYSQL, 1/13 chance of POSTGRES. + # (Should result in similar execution times for each profile). + profile_index=0 + if [[ $spring_profile_chance -gt 10 ]]; then + profile_index=1 + fi + + if [[ $spring_profile_chance -gt 12 ]]; then + profile_index=2 + fi + active_profile="${SPRING_PROFILES[$profile_index]}" + + # Generate output file name + TIME=$(date +"%Y-%m-%d_%H:%M:%S") + output_file="${active_profile}_${TIME}_run${run}.log" + + # Run tests with gradlew + echo "Running tests with Spring Profile: $active_profile (Run $run)" + set -o pipefail && SPRING_PROFILES_INCLUDE="$active_profile" ./gradlew --console=plain \ + test --rerun jacocoTestReport -x webapp jacocoTestCoverageVerification > "${DIRECTORY}/$output_file" + + # Check if tests were successful. If not, rename the output file to indicate failure. Delete the output file if tests were successful. + if grep -q "BUILD SUCCESSFUL" "${DIRECTORY}/$output_file"; then + rm "${DIRECTORY}/$output_file" + else + mv "${DIRECTORY}/$output_file" "${DIRECTORY}/FAILURE_${output_file}" + fi + + # Wait a bit before the next run + sleep 10 +done + +# ================== # +# FLAKY TEST SUMMARY # +# ================== # + +echo "Generating flaky test summary..." + +SUMMARY_DIRECTORY="${DIRECTORY}/summary" +mkdir -p "$SUMMARY_DIRECTORY" + +SUMMARY_FILE="${SUMMARY_DIRECTORY}/run-summary.txt" +printf "Logfile and Failed Tests\n" > "$SUMMARY_FILE" +for file in "$DIRECTORY"/*.log; do + if [ -f "$file" ]; then + printf "\nFailed tests in $(basename "$file"):\n" >> "$SUMMARY_FILE" + grep "Test >.* FAILED" "$file" >> "$SUMMARY_FILE" + fi +done + +COUNT_FILE="${SUMMARY_DIRECTORY}/failure-count.txt" +printf "Count of Failed Tests\n" > "$COUNT_FILE" +grep "Test >.* FAILED" "$SUMMARY_FILE" | sort | uniq -c | sort -nr >> "$COUNT_FILE" + +echo "Tests completed for $NUM_RUNS run(s)."