Skip to content

Commit

Permalink
Development: Enable parallel server test execution (#6796)
Browse files Browse the repository at this point in the history
  • Loading branch information
DominikRemo authored Sep 22, 2023
1 parent 6543ec6 commit 5ba2676
Show file tree
Hide file tree
Showing 158 changed files with 1,429 additions and 851 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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';

Expand Down Expand Up @@ -40,9 +39,6 @@ export class ExamExerciseImportComponent implements OnInit {

// Icons
faCheckDouble = faCheckDouble;
faFileUpload = faFileUpload;
faProjectDiagram = faProjectDiagram;
faKeyboard = faKeyboard;
faFont = faFont;

getExerciseIcon = getIcon;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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" })
Expand Down
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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" })
Expand Down
Loading

0 comments on commit 5ba2676

Please sign in to comment.