Search in sources :

Example 1 with ProgrammingExerciseStudentParticipation

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

the class ProgrammingExerciseExportService method createZipForRepositoryWithParticipation.

/**
 * Checks out the repository for the given participation, zips it and adds the path to the given list of already
 * zipped repos.
 *
 * @param programmingExercise     The programming exercise for the participation
 * @param participation           The participation, for which the repository should get zipped
 * @param repositoryExportOptions The options, that should get applied to the zipped repo
 * @param outputDir The directory used for downloading and zipping the repository
 * @return The checked out and zipped repository
 * @throws IOException if zip file creation failed
 */
private Path createZipForRepositoryWithParticipation(final ProgrammingExercise programmingExercise, final ProgrammingExerciseStudentParticipation participation, final RepositoryExportOptionsDTO repositoryExportOptions, Path outputDir) throws IOException, UncheckedIOException {
    if (participation.getVcsRepositoryUrl() == null) {
        log.warn("Ignore participation {} for export, because its repository URL is null", participation.getId());
        return null;
    }
    try {
        // Checkout the repository
        Repository repository = gitService.getOrCheckoutRepository(participation, outputDir.toString());
        if (repository == null) {
            log.warn("Cannot checkout repository for participation id: {}", participation.getId());
            return null;
        }
        gitService.resetToOriginHead(repository);
        if (repositoryExportOptions.isFilterLateSubmissions()) {
            filterLateSubmissions(repositoryExportOptions, participation, repository);
        }
        if (repositoryExportOptions.isAddParticipantName()) {
            log.debug("Adding student or team name to participation {}", participation);
            addParticipantIdentifierToProjectName(repository, programmingExercise, participation);
        }
        if (repositoryExportOptions.isCombineStudentCommits()) {
            log.debug("Combining commits for participation {}", participation);
            gitService.combineAllStudentCommits(repository, programmingExercise, repositoryExportOptions.isAnonymizeStudentCommits());
        }
        if (repositoryExportOptions.isAnonymizeStudentCommits()) {
            log.debug("Anonymizing commits for participation {}", participation);
            gitService.anonymizeStudentCommits(repository, programmingExercise);
        }
        if (repositoryExportOptions.isNormalizeCodeStyle()) {
            try {
                log.debug("Normalizing code style for participation {}", participation);
                fileService.normalizeLineEndingsDirectory(repository.getLocalPath().toString());
                fileService.convertToUTF8Directory(repository.getLocalPath().toString());
            } catch (IOException ex) {
                log.warn("Cannot normalize code style in the repository {} due to the following exception: {}", repository.getLocalPath(), ex.getMessage());
            }
        }
        log.debug("Create temporary zip file for repository {}", repository.getLocalPath().toString());
        return gitService.zipRepositoryWithParticipation(repository, outputDir.toString(), repositoryExportOptions.isHideStudentNameInZippedFolder());
    } catch (GitAPIException | GitException ex) {
        log.error("Failed to create zip for participation id {} with exercise id {} because of the following exception ", participation.getId(), participation.getProgrammingExercise().getId(), ex);
        return null;
    }
}
Also used : GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) StudentParticipationRepository(de.tum.in.www1.artemis.repository.StudentParticipationRepository) AuxiliaryRepositoryRepository(de.tum.in.www1.artemis.repository.AuxiliaryRepositoryRepository) ProgrammingExerciseRepository(de.tum.in.www1.artemis.repository.ProgrammingExerciseRepository) GitException(de.tum.in.www1.artemis.exception.GitException) UncheckedIOException(java.io.UncheckedIOException) IOException(java.io.IOException)

Example 2 with ProgrammingExerciseStudentParticipation

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

the class ProgrammingSubmissionResultSimulationService method createSubmission.

/**
 * This method creates a new submission for the provided user
 * @param exerciseId the exerciseId of the exercise for which a submission should be created
 * This functionality is only for testing purposes (noVersionControlAndContinuousIntegrationAvailable)
 * @return the newly created and stored submission
 */
public ProgrammingSubmission createSubmission(Long exerciseId) {
    User user = userRepository.getUserWithGroupsAndAuthorities();
    Participant participant = user;
    ProgrammingExerciseStudentParticipation programmingExerciseStudentParticipation;
    ProgrammingExercise programmingExercise = programmingExerciseRepository.findByIdWithStudentParticipationsAndLegalSubmissionsElseThrow(exerciseId);
    Optional<StudentParticipation> optionalStudentParticipation = participationService.findOneByExerciseAndStudentLoginWithEagerSubmissionsAnyState(programmingExercise, user.getLogin());
    if (optionalStudentParticipation.isEmpty()) {
        programmingExerciseStudentParticipation = createParticipation(programmingExercise, participant, user);
    } else {
        programmingExerciseStudentParticipation = (ProgrammingExerciseStudentParticipation) optionalStudentParticipation.get();
    }
    ProgrammingSubmission programmingSubmission = new ProgrammingSubmission();
    programmingSubmission.setCommitHash(VCSSimulationUtils.simulateCommitHash());
    programmingSubmission.setSubmitted(true);
    programmingSubmission.setSubmissionDate(ZonedDateTime.now());
    programmingSubmission.setType(SubmissionType.MANUAL);
    programmingExerciseStudentParticipation.addSubmission(programmingSubmission);
    programmingSubmissionRepository.save(programmingSubmission);
    return programmingSubmission;
}
Also used : Participant(de.tum.in.www1.artemis.domain.participation.Participant) ProgrammingExerciseStudentParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation) ProgrammingExerciseStudentParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation) StudentParticipation(de.tum.in.www1.artemis.domain.participation.StudentParticipation)

Example 3 with ProgrammingExerciseStudentParticipation

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

the class AutomaticProgrammingExerciseCleanupService method deleteBuildPlans.

private void deleteBuildPlans(Set<ProgrammingExerciseStudentParticipation> participationsWithBuildPlanToDelete) {
    // Limit to 5000 deletions per night
    List<ProgrammingExerciseStudentParticipation> actualParticipationsToClean = participationsWithBuildPlanToDelete.stream().limit(5000).toList();
    List<String> buildPlanIds = actualParticipationsToClean.stream().map(ProgrammingExerciseStudentParticipation::getBuildPlanId).toList();
    log.info("Build plans to cleanup: {}", buildPlanIds);
    int index = 0;
    for (ProgrammingExerciseStudentParticipation participation : actualParticipationsToClean) {
        if (index > 0 && index % externalSystemRequestBatchSize == 0) {
            try {
                log.info("Sleep for {}s during cleanupBuildPlansOnContinuousIntegrationServer", externalSystemRequestBatchWaitingTime / 1000);
                Thread.sleep(externalSystemRequestBatchWaitingTime);
            } catch (InterruptedException ex) {
                log.error("Exception encountered when pausing before cleaning up build plans", ex);
            }
        }
        try {
            participationService.cleanupBuildPlan(participation);
        } catch (Exception ex) {
            log.error("Could not cleanup build plan in participation " + participation.getId(), ex);
        }
        index++;
    }
    log.info("{} build plans have been cleaned", actualParticipationsToClean.size());
}
Also used : ProgrammingExerciseStudentParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation)

Example 4 with ProgrammingExerciseStudentParticipation

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

the class AutomaticProgrammingExerciseCleanupService method cleanupBuildPlansOnContinuousIntegrationServer.

/**
 *  Cleans up old build plans on the continuous integration server
 */
public void cleanupBuildPlansOnContinuousIntegrationServer() {
    log.info("Find build plans for potential cleanup");
    AtomicLong countAfterBuildAndTestDate = new AtomicLong();
    AtomicLong countNoResult = new AtomicLong();
    AtomicLong countSuccessfulLatestResult = new AtomicLong();
    AtomicLong countUnsuccessfulLatestResult = new AtomicLong();
    Set<ProgrammingExerciseStudentParticipation> participationsWithBuildPlanToDelete = new HashSet<>();
    var participationsWithBuildPlans = programmingExerciseStudentParticipationRepository.findAllWithBuildPlanIdWithResults();
    log.info("Found {} potential build plans to delete", participationsWithBuildPlans.size());
    participationsWithBuildPlans.forEach(participation -> {
        if (participation.getBuildPlanId() == null || participation.getParticipant() == null) {
            // already cleaned up or we only want to clean up build plans of students or teams (NOT template or solution build plans)
            return;
        }
        if (participation.getProgrammingExercise() != null && Hibernate.isInitialized(participation.getProgrammingExercise())) {
            var programmingExercise = participation.getProgrammingExercise();
            if (checkFutureExamExercises(programmingExercise)) {
                return;
            }
            if (checkBuildAndTestExercises(programmingExercise, participation, participationsWithBuildPlanToDelete, countAfterBuildAndTestDate)) {
                return;
            }
            if (Boolean.TRUE.equals(programmingExercise.isPublishBuildPlanUrl())) {
                // this was an exercise where students needed to configure the build plan, therefore we should not clean it up
                return;
            }
        }
        checkLastResults(participation, participationsWithBuildPlanToDelete, countNoResult, countSuccessfulLatestResult, countUnsuccessfulLatestResult);
    });
    log.info("Found {} old build plans to delete", participationsWithBuildPlanToDelete.size());
    log.info("  Found {} build plans at least 1 day older than 'build and test submissions after due date", countAfterBuildAndTestDate);
    log.info("  Found {} build plans without results 3 days after initialization", countNoResult);
    log.info("  Found {} build plans with successful latest result is older than 1 day", countSuccessfulLatestResult);
    log.info("  Found {} build plans with unsuccessful latest result is older than 5 days", countUnsuccessfulLatestResult);
    deleteBuildPlans(participationsWithBuildPlanToDelete);
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) ProgrammingExerciseStudentParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation)

Example 5 with ProgrammingExerciseStudentParticipation

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

the class ProgrammingExerciseScheduleService method scheduleBuildAndTestAfterDueDateForParticipation.

private void scheduleBuildAndTestAfterDueDateForParticipation(ProgrammingExerciseStudentParticipation participation) {
    scheduleService.scheduleParticipationTask(participation, ParticipationLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE, () -> {
        final ProgrammingExercise exercise = participation.getProgrammingExercise();
        SecurityUtils.setAuthorizationObject();
        try {
            log.info("Invoking scheduled task for participation {} in programming exercise with id {}.", participation.getId(), exercise.getId());
            programmingSubmissionService.triggerBuildForParticipations(List.of(participation));
        } catch (EntityNotFoundException ex) {
            log.error("Programming participation with id {} in exercise {} is no longer available in database for use in scheduled task.", participation.getId(), exercise.getId());
        }
    });
}
Also used : ProgrammingExercise(de.tum.in.www1.artemis.domain.ProgrammingExercise) EntityNotFoundException(de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException)

Aggregations

ProgrammingExerciseStudentParticipation (de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation)58 StudentParticipation (de.tum.in.www1.artemis.domain.participation.StudentParticipation)26 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)24 WithMockUser (org.springframework.security.test.context.support.WithMockUser)24 ProgrammingExercise (de.tum.in.www1.artemis.domain.ProgrammingExercise)20 Test (org.junit.jupiter.api.Test)20 Result (de.tum.in.www1.artemis.domain.Result)18 BeforeEach (org.junit.jupiter.api.BeforeEach)18 AbstractSpringIntegrationBambooBitbucketJiraTest (de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest)16 ZonedDateTime (java.time.ZonedDateTime)16 EnumSource (org.junit.jupiter.params.provider.EnumSource)16 Feedback (de.tum.in.www1.artemis.domain.Feedback)14 ProgrammingExerciseRepository (de.tum.in.www1.artemis.repository.ProgrammingExerciseRepository)14 ModelFactory (de.tum.in.www1.artemis.util.ModelFactory)14 EntityNotFoundException (de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException)14 List (java.util.List)14 Assertions.assertThat (org.assertj.core.api.Assertions.assertThat)14 AfterEach (org.junit.jupiter.api.AfterEach)14 Autowired (org.springframework.beans.factory.annotation.Autowired)14 AssessmentType (de.tum.in.www1.artemis.domain.enumeration.AssessmentType)12