Search in sources :

Example 1 with ProgrammingLanguage

use of de.tum.in.www1.artemis.domain.enumeration.ProgrammingLanguage in project Artemis by ls1intum.

the class JenkinsService method addFeedbackToResult.

@Override
protected void addFeedbackToResult(Result result, AbstractBuildResultNotificationDTO buildResult) {
    final ProgrammingExercise programmingExercise = (ProgrammingExercise) result.getParticipation().getExercise();
    final ProgrammingLanguage programmingLanguage = programmingExercise.getProgrammingLanguage();
    final var jobs = ((TestResultsDTO) buildResult).getResults();
    // Extract test case feedback
    for (final var job : jobs) {
        for (final var testCase : job.getTestCases()) {
            var feedbackMessages = extractMessageFromTestCase(testCase).map(List::of).orElse(List.of());
            var feedback = feedbackRepository.createFeedbackFromTestCase(testCase.getName(), feedbackMessages, testCase.isSuccessful(), programmingLanguage);
            result.addFeedback(feedback);
        }
    }
    // Extract static code analysis feedback if option was enabled
    var staticCodeAnalysisReports = ((TestResultsDTO) buildResult).getStaticCodeAnalysisReports();
    if (Boolean.TRUE.equals(programmingExercise.isStaticCodeAnalysisEnabled()) && staticCodeAnalysisReports != null && !staticCodeAnalysisReports.isEmpty()) {
        var scaFeedback = feedbackRepository.createFeedbackFromStaticCodeAnalysisReports(staticCodeAnalysisReports);
        result.addFeedbacks(scaFeedback);
    }
    // Relevant feedback is negative, or positive with a message
    result.setHasFeedback(result.getFeedbacks().stream().anyMatch(fb -> !fb.isPositive() || fb.getDetailText() != null));
}
Also used : ContinuousIntegrationException(de.tum.in.www1.artemis.exception.ContinuousIntegrationException) ProgrammingLanguage(de.tum.in.www1.artemis.domain.enumeration.ProgrammingLanguage) ProgrammingSubmissionRepository(de.tum.in.www1.artemis.repository.ProgrammingSubmissionRepository) ExerciseDateService(de.tum.in.www1.artemis.service.ExerciseDateService) LoggerFactory(org.slf4j.LoggerFactory) AbstractContinuousIntegrationService(de.tum.in.www1.artemis.service.connectors.AbstractContinuousIntegrationService) TestResultsDTO(de.tum.in.www1.artemis.service.connectors.jenkins.dto.TestResultsDTO) Value(org.springframework.beans.factory.annotation.Value) CollectionUtils(org.apache.commons.collections.CollectionUtils) Service(org.springframework.stereotype.Service) RepositoryType(de.tum.in.www1.artemis.domain.enumeration.RepositoryType) ProgrammingExerciseParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation) JenkinsJobService(de.tum.in.www1.artemis.service.connectors.jenkins.jobs.JenkinsJobService) Map(java.util.Map) Qualifier(org.springframework.beans.factory.annotation.Qualifier) RestTemplate(org.springframework.web.client.RestTemplate) FeedbackRepository(de.tum.in.www1.artemis.repository.FeedbackRepository) Logger(org.slf4j.Logger) BuildPlanType(de.tum.in.www1.artemis.domain.enumeration.BuildPlanType) TestCaseDTO(de.tum.in.www1.artemis.service.connectors.jenkins.dto.TestCaseDTO) IOException(java.io.IOException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) Profile(org.springframework.context.annotation.Profile) JenkinsServer(com.offbytwo.jenkins.JenkinsServer) JenkinsException(de.tum.in.www1.artemis.exception.JenkinsException) AbstractBuildResultNotificationDTO(de.tum.in.www1.artemis.service.dto.AbstractBuildResultNotificationDTO) List(java.util.List) Stream(java.util.stream.Stream) de.tum.in.www1.artemis.domain(de.tum.in.www1.artemis.domain) CIPermission(de.tum.in.www1.artemis.service.connectors.CIPermission) BuildLogEntryService(de.tum.in.www1.artemis.service.BuildLogEntryService) ConnectorHealth(de.tum.in.www1.artemis.service.connectors.ConnectorHealth) Optional(java.util.Optional) ResponseEntity(org.springframework.http.ResponseEntity) Jsoup(org.jsoup.Jsoup) TestResultsDTO(de.tum.in.www1.artemis.service.connectors.jenkins.dto.TestResultsDTO) ProgrammingLanguage(de.tum.in.www1.artemis.domain.enumeration.ProgrammingLanguage)

Example 2 with ProgrammingLanguage

use of de.tum.in.www1.artemis.domain.enumeration.ProgrammingLanguage 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 ProgrammingLanguage

use of de.tum.in.www1.artemis.domain.enumeration.ProgrammingLanguage 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 ProgrammingLanguage

use of de.tum.in.www1.artemis.domain.enumeration.ProgrammingLanguage in project ArTEMiS by ls1intum.

the class JenkinsService method addFeedbackToResult.

@Override
protected void addFeedbackToResult(Result result, AbstractBuildResultNotificationDTO buildResult) {
    final ProgrammingExercise programmingExercise = (ProgrammingExercise) result.getParticipation().getExercise();
    final ProgrammingLanguage programmingLanguage = programmingExercise.getProgrammingLanguage();
    final var jobs = ((TestResultsDTO) buildResult).getResults();
    // Extract test case feedback
    for (final var job : jobs) {
        for (final var testCase : job.getTestCases()) {
            var feedbackMessages = extractMessageFromTestCase(testCase).map(List::of).orElse(List.of());
            var feedback = feedbackRepository.createFeedbackFromTestCase(testCase.getName(), feedbackMessages, testCase.isSuccessful(), programmingLanguage);
            result.addFeedback(feedback);
        }
    }
    // Extract static code analysis feedback if option was enabled
    var staticCodeAnalysisReports = ((TestResultsDTO) buildResult).getStaticCodeAnalysisReports();
    if (Boolean.TRUE.equals(programmingExercise.isStaticCodeAnalysisEnabled()) && staticCodeAnalysisReports != null && !staticCodeAnalysisReports.isEmpty()) {
        var scaFeedback = feedbackRepository.createFeedbackFromStaticCodeAnalysisReports(staticCodeAnalysisReports);
        result.addFeedbacks(scaFeedback);
    }
    // Relevant feedback is negative, or positive with a message
    result.setHasFeedback(result.getFeedbacks().stream().anyMatch(fb -> !fb.isPositive() || fb.getDetailText() != null));
}
Also used : ContinuousIntegrationException(de.tum.in.www1.artemis.exception.ContinuousIntegrationException) ProgrammingLanguage(de.tum.in.www1.artemis.domain.enumeration.ProgrammingLanguage) ProgrammingSubmissionRepository(de.tum.in.www1.artemis.repository.ProgrammingSubmissionRepository) ExerciseDateService(de.tum.in.www1.artemis.service.ExerciseDateService) LoggerFactory(org.slf4j.LoggerFactory) AbstractContinuousIntegrationService(de.tum.in.www1.artemis.service.connectors.AbstractContinuousIntegrationService) TestResultsDTO(de.tum.in.www1.artemis.service.connectors.jenkins.dto.TestResultsDTO) Value(org.springframework.beans.factory.annotation.Value) CollectionUtils(org.apache.commons.collections.CollectionUtils) Service(org.springframework.stereotype.Service) RepositoryType(de.tum.in.www1.artemis.domain.enumeration.RepositoryType) ProgrammingExerciseParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation) JenkinsJobService(de.tum.in.www1.artemis.service.connectors.jenkins.jobs.JenkinsJobService) Map(java.util.Map) Qualifier(org.springframework.beans.factory.annotation.Qualifier) RestTemplate(org.springframework.web.client.RestTemplate) FeedbackRepository(de.tum.in.www1.artemis.repository.FeedbackRepository) Logger(org.slf4j.Logger) BuildPlanType(de.tum.in.www1.artemis.domain.enumeration.BuildPlanType) TestCaseDTO(de.tum.in.www1.artemis.service.connectors.jenkins.dto.TestCaseDTO) IOException(java.io.IOException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) Profile(org.springframework.context.annotation.Profile) JenkinsServer(com.offbytwo.jenkins.JenkinsServer) JenkinsException(de.tum.in.www1.artemis.exception.JenkinsException) AbstractBuildResultNotificationDTO(de.tum.in.www1.artemis.service.dto.AbstractBuildResultNotificationDTO) List(java.util.List) Stream(java.util.stream.Stream) de.tum.in.www1.artemis.domain(de.tum.in.www1.artemis.domain) CIPermission(de.tum.in.www1.artemis.service.connectors.CIPermission) BuildLogEntryService(de.tum.in.www1.artemis.service.BuildLogEntryService) ConnectorHealth(de.tum.in.www1.artemis.service.connectors.ConnectorHealth) Optional(java.util.Optional) ResponseEntity(org.springframework.http.ResponseEntity) Jsoup(org.jsoup.Jsoup) TestResultsDTO(de.tum.in.www1.artemis.service.connectors.jenkins.dto.TestResultsDTO) ProgrammingLanguage(de.tum.in.www1.artemis.domain.enumeration.ProgrammingLanguage)

Example 5 with ProgrammingLanguage

use of de.tum.in.www1.artemis.domain.enumeration.ProgrammingLanguage 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)

Aggregations

ProgrammingLanguage (de.tum.in.www1.artemis.domain.enumeration.ProgrammingLanguage)14 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)10 ProgrammingExercise (de.tum.in.www1.artemis.domain.ProgrammingExercise)8 IOException (java.io.IOException)8 WithMockUser (org.springframework.security.test.context.support.WithMockUser)8 JenkinsException (de.tum.in.www1.artemis.exception.JenkinsException)6 MethodSource (org.junit.jupiter.params.provider.MethodSource)6 de.tum.in.www1.artemis.domain (de.tum.in.www1.artemis.domain)4 ProjectType (de.tum.in.www1.artemis.domain.enumeration.ProjectType)4 ProgrammingExerciseParticipation (de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation)4 URISyntaxException (java.net.URISyntaxException)4 Stream (java.util.stream.Stream)4 Logger (org.slf4j.Logger)3 LoggerFactory (org.slf4j.LoggerFactory)3 PreAuthorize (org.springframework.security.access.prepost.PreAuthorize)3 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)2 JenkinsServer (com.offbytwo.jenkins.JenkinsServer)2 AbstractSpringIntegrationBambooBitbucketJiraTest (de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest)2 ProgrammingExerciseTestCase (de.tum.in.www1.artemis.domain.ProgrammingExerciseTestCase)2 BuildPlanType (de.tum.in.www1.artemis.domain.enumeration.BuildPlanType)2