Search in sources :

Example 1 with ProgrammingExerciseParticipation

use of de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation in project Artemis by ls1intum.

the class AbstractContinuousIntegrationService method createFallbackSubmission.

/**
 * There can be two reasons for the case that there is no programmingSubmission:
 * 1) Manual build triggered from CI (e.g. by the instructor)
 * 2) An unknown error that caused the programming submission not to be created when the code commits have been pushed.
 * we can still get the commit hash from the payload of the CI build result and "reverse engineer" the programming submission object to be consistent
 */
@NotNull
protected ProgrammingSubmission createFallbackSubmission(ProgrammingExerciseParticipation participation, ZonedDateTime submissionDate, String commitHash) {
    ProgrammingSubmission submission = new ProgrammingSubmission();
    submission.setParticipation((Participation) participation);
    submission.setSubmitted(true);
    // We set this to manual because all programming submissions should correspond to a student commit in the git history.
    // In case we cannot find the appropriate submission, it means something has not worked before, but there will still be a commit in the student repository
    submission.setType(SubmissionType.MANUAL);
    submission.setCommitHash(commitHash);
    submission.setSubmissionDate(submissionDate);
    return submission;
}
Also used : ProgrammingSubmission(de.tum.in.www1.artemis.domain.ProgrammingSubmission) NotNull(javax.validation.constraints.NotNull)

Example 2 with ProgrammingExerciseParticipation

use of de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation in project Artemis by ls1intum.

the class JenkinsService method onBuildCompleted.

@Override
public Result onBuildCompleted(ProgrammingExerciseParticipation participation, Object requestBody) {
    final var buildResult = TestResultsDTO.convert(requestBody);
    var newResult = createResultFromBuildResult(buildResult, participation);
    // Fetch submission or create a fallback
    var latestSubmission = super.getSubmissionForBuildResult(participation.getId(), buildResult).orElseGet(() -> createAndSaveFallbackSubmission(participation, buildResult));
    latestSubmission.setBuildFailed("No tests found".equals(newResult.getResultString()));
    // Parse, filter, and save the build logs if they exist
    if (buildResult.getLogs() != null) {
        ProgrammingLanguage programmingLanguage = participation.getProgrammingExercise().getProgrammingLanguage();
        List<BuildLogEntry> buildLogEntries = JenkinsBuildLogParseUtils.parseBuildLogsFromJenkinsLogs(buildResult.getLogs());
        buildLogEntries = filterUnnecessaryLogs(buildLogEntries, programmingLanguage);
        buildLogEntries = buildLogService.saveBuildLogs(buildLogEntries, latestSubmission);
        // Set the received logs in order to avoid duplicate entries (this removes existing logs)
        latestSubmission.setBuildLogEntries(buildLogEntries);
    }
    // Note: we only set one side of the relationship because we don't know yet whether the result will actually be saved
    newResult.setSubmission(latestSubmission);
    newResult.setRatedIfNotExceeded(exerciseDateService.getDueDate(participation).orElse(null), latestSubmission);
    return newResult;
}
Also used : ProgrammingLanguage(de.tum.in.www1.artemis.domain.enumeration.ProgrammingLanguage)

Example 3 with ProgrammingExerciseParticipation

use of de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation in project ArTEMiS by ls1intum.

the class JenkinsService method onBuildCompleted.

@Override
public Result onBuildCompleted(ProgrammingExerciseParticipation participation, Object requestBody) {
    final var buildResult = TestResultsDTO.convert(requestBody);
    var newResult = createResultFromBuildResult(buildResult, participation);
    // Fetch submission or create a fallback
    var latestSubmission = super.getSubmissionForBuildResult(participation.getId(), buildResult).orElseGet(() -> createAndSaveFallbackSubmission(participation, buildResult));
    latestSubmission.setBuildFailed("No tests found".equals(newResult.getResultString()));
    // Parse, filter, and save the build logs if they exist
    if (buildResult.getLogs() != null) {
        ProgrammingLanguage programmingLanguage = participation.getProgrammingExercise().getProgrammingLanguage();
        List<BuildLogEntry> buildLogEntries = JenkinsBuildLogParseUtils.parseBuildLogsFromJenkinsLogs(buildResult.getLogs());
        buildLogEntries = filterUnnecessaryLogs(buildLogEntries, programmingLanguage);
        buildLogEntries = buildLogService.saveBuildLogs(buildLogEntries, latestSubmission);
        // Set the received logs in order to avoid duplicate entries (this removes existing logs)
        latestSubmission.setBuildLogEntries(buildLogEntries);
    }
    // Note: we only set one side of the relationship because we don't know yet whether the result will actually be saved
    newResult.setSubmission(latestSubmission);
    newResult.setRatedIfNotExceeded(exerciseDateService.getDueDate(participation).orElse(null), latestSubmission);
    return newResult;
}
Also used : ProgrammingLanguage(de.tum.in.www1.artemis.domain.enumeration.ProgrammingLanguage)

Example 4 with ProgrammingExerciseParticipation

use of de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation in project ArTEMiS by ls1intum.

the class JenkinsService method getLatestBuildLogs.

@Override
public List<BuildLogEntry> getLatestBuildLogs(ProgrammingSubmission programmingSubmission) {
    ProgrammingExerciseParticipation programmingExerciseParticipation = (ProgrammingExerciseParticipation) programmingSubmission.getParticipation();
    String projectKey = programmingExerciseParticipation.getProgrammingExercise().getProjectKey();
    String buildPlanId = programmingExerciseParticipation.getBuildPlanId();
    ProgrammingLanguage programmingLanguage = programmingExerciseParticipation.getProgrammingExercise().getProgrammingLanguage();
    try {
        final var build = jenkinsJobService.getJobInFolder(projectKey, buildPlanId).getLastBuild();
        List<BuildLogEntry> buildLogEntries;
        // Attempt to parse pipeline logs
        final String pipelineLogs = build.details().getConsoleOutputText();
        if (pipelineLogs != null && pipelineLogs.contains("[Pipeline] Start of Pipeline")) {
            buildLogEntries = JenkinsBuildLogParseUtils.parseBuildLogsFromJenkinsLogs(List.of(pipelineLogs.split("\n")));
        } else {
            // Fallback to legacy logs
            final var logHtml = Jsoup.parse(build.details().getConsoleOutputHtml()).body();
            buildLogEntries = JenkinsBuildLogParseUtils.parseLogsLegacy(logHtml);
        }
        // Filter and save build logs
        buildLogEntries = filterUnnecessaryLogs(buildLogEntries, programmingLanguage);
        buildLogEntries = buildLogService.saveBuildLogs(buildLogEntries, programmingSubmission);
        programmingSubmission.setBuildLogEntries(buildLogEntries);
        programmingSubmissionRepository.save(programmingSubmission);
        return buildLogEntries;
    } catch (IOException e) {
        log.error(e.getMessage(), e);
        throw new JenkinsException(e.getMessage(), e);
    }
}
Also used : ProgrammingExerciseParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation) JenkinsException(de.tum.in.www1.artemis.exception.JenkinsException) ProgrammingLanguage(de.tum.in.www1.artemis.domain.enumeration.ProgrammingLanguage) IOException(java.io.IOException)

Example 5 with ProgrammingExerciseParticipation

use of de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation in project ArTEMiS by ls1intum.

the class ResultResource method getLatestResultWithFeedbacks.

/**
 * GET /participations/:participationId/latest-result : get the latest result with feedbacks for the given participation.
 * The order of results is determined by completionDate desc.
 *
 * @param participationId the id of the participation for which to retrieve the latest result.
 * @return the ResponseEntity with status 200 (OK) and with body the result, or with status 404 (Not Found)
 */
@GetMapping("participations/{participationId}/latest-result")
@PreAuthorize("hasRole('TA')")
public ResponseEntity<Result> getLatestResultWithFeedbacks(@PathVariable Long participationId) {
    log.debug("REST request to get latest result for participation : {}", participationId);
    Participation participation = participationRepository.findByIdElseThrow(participationId);
    if (participation instanceof StudentParticipation && !authCheckService.canAccessParticipation((StudentParticipation) participation) || participation instanceof ProgrammingExerciseParticipation && !programmingExerciseParticipationService.canAccessParticipation((ProgrammingExerciseParticipation) participation)) {
        throw new AccessForbiddenException();
    }
    Result result = resultRepository.findFirstWithFeedbacksByParticipationIdOrderByCompletionDateDescElseThrow(participation.getId());
    return new ResponseEntity<>(result, HttpStatus.OK);
}
Also used : Participation(de.tum.in.www1.artemis.domain.participation.Participation) ProgrammingExerciseStudentParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation) ProgrammingExerciseParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation) StudentParticipation(de.tum.in.www1.artemis.domain.participation.StudentParticipation) ResponseEntity(org.springframework.http.ResponseEntity) ProgrammingExerciseParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation) ProgrammingExerciseStudentParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation) StudentParticipation(de.tum.in.www1.artemis.domain.participation.StudentParticipation) AccessForbiddenException(de.tum.in.www1.artemis.web.rest.errors.AccessForbiddenException) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Aggregations

ProgrammingExerciseStudentParticipation (de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation)16 StudentParticipation (de.tum.in.www1.artemis.domain.participation.StudentParticipation)12 ProgrammingExerciseParticipation (de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation)10 Test (org.junit.jupiter.api.Test)10 WithMockUser (org.springframework.security.test.context.support.WithMockUser)10 AbstractSpringIntegrationBambooBitbucketJiraTest (de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest)8 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)8 HttpHeaders (org.springframework.http.HttpHeaders)8 ProgrammingSubmission (de.tum.in.www1.artemis.domain.ProgrammingSubmission)4 ProgrammingLanguage (de.tum.in.www1.artemis.domain.enumeration.ProgrammingLanguage)4 Participation (de.tum.in.www1.artemis.domain.participation.Participation)4 AccessForbiddenException (de.tum.in.www1.artemis.web.rest.errors.AccessForbiddenException)4 Nullable (javax.annotation.Nullable)4 NotNull (javax.validation.constraints.NotNull)4 ResponseEntity (org.springframework.http.ResponseEntity)4 PreAuthorize (org.springframework.security.access.prepost.PreAuthorize)4 JsonNode (com.fasterxml.jackson.databind.JsonNode)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)2 AbstractSpringIntegrationJenkinsGitlabTest (de.tum.in.www1.artemis.AbstractSpringIntegrationJenkinsGitlabTest)2 de.tum.in.www1.artemis.domain (de.tum.in.www1.artemis.domain)2