Skip to content

Commit

Permalink
Feature/programming exercise/simplify submission and result generatio…
Browse files Browse the repository at this point in the history
…n in the local setup (ls1intum#1292)
  • Loading branch information
F4lka authored Apr 20, 2020
1 parent 3892bbc commit 713e87c
Show file tree
Hide file tree
Showing 30 changed files with 1,202 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,10 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import de.tum.in.www1.artemis.domain.Course;
import de.tum.in.www1.artemis.domain.ProgrammingExercise;
import de.tum.in.www1.artemis.domain.Repository;
import de.tum.in.www1.artemis.domain.User;
import de.tum.in.www1.artemis.domain.enumeration.InitializationState;
import de.tum.in.www1.artemis.domain.enumeration.ProgrammingLanguage;
import de.tum.in.www1.artemis.domain.enumeration.RepositoryType;
import de.tum.in.www1.artemis.domain.enumeration.SortingOrder;
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.SolutionProgrammingExerciseParticipation;
import de.tum.in.www1.artemis.domain.participation.TemplateProgrammingExerciseParticipation;
import de.tum.in.www1.artemis.repository.ProgrammingExerciseRepository;
import de.tum.in.www1.artemis.repository.ResultRepository;
import de.tum.in.www1.artemis.repository.SolutionProgrammingExerciseParticipationRepository;
import de.tum.in.www1.artemis.repository.TemplateProgrammingExerciseParticipationRepository;
import de.tum.in.www1.artemis.domain.*;
import de.tum.in.www1.artemis.domain.enumeration.*;
import de.tum.in.www1.artemis.domain.participation.*;
import de.tum.in.www1.artemis.repository.*;
import de.tum.in.www1.artemis.service.connectors.CIPermission;
import de.tum.in.www1.artemis.service.connectors.ContinuousIntegrationService;
import de.tum.in.www1.artemis.service.connectors.GitService;
Expand Down Expand Up @@ -183,7 +171,11 @@ private void setupBuildPlansForNewExercise(ProgrammingExercise programmingExerci
giveCIProjectPermissions(programmingExercise);
}

private void connectBaseParticipationsToExerciseAndSave(ProgrammingExercise programmingExercise) {
/**
* This method connects the new programming exercise with the template and solution participation
* @param programmingExercise the new programming exercise
*/
public void connectBaseParticipationsToExerciseAndSave(ProgrammingExercise programmingExercise) {
final var templateParticipation = programmingExercise.getTemplateParticipation();
final var solutionParticipation = programmingExercise.getSolutionParticipation();
templateParticipation.setProgrammingExercise(programmingExercise);
Expand Down Expand Up @@ -385,7 +377,6 @@ private void setupTestTemplateAndPush(Repository repository, Resource[] resource

/**
* Replace placeholders in repository files (e.g. ${placeholder}).
*
* @param programmingExercise The related programming exercise
* @param repository The repository in which the placeholders should get replaced
* @throws IOException If replacing the directory name, or file variables throws an exception
Expand Down Expand Up @@ -418,7 +409,6 @@ public void replacePlaceholders(ProgrammingExercise programmingExercise, Reposit

/**
* Stage, commit and push.
*
* @param repository The repository to which the changes should get pushed
* @param templateName The template name which should be put in the commit message
* @throws GitAPIException If committing, or pushing to the repo throws an exception
Expand Down Expand Up @@ -452,7 +442,6 @@ public ProgrammingExercise getExercise(SolutionProgrammingExerciseParticipation

/**
* Find a programming exercise by its id.
*
* @param programmingExerciseId of the programming exercise.
* @return The programming exercise related to the given id
* @throws EntityNotFoundException the programming exercise could not be found.
Expand Down Expand Up @@ -526,7 +515,6 @@ public ProgrammingExercise findWithTestCasesById(Long exerciseId) throws EntityN

/**
* Combine all commits of the given repository into one.
*
* @param repoUrl of the repository to combine.
* @throws InterruptedException If the checkout fails
* @throws GitAPIException If the checkout fails
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package de.tum.in.www1.artemis.service;

import static de.tum.in.www1.artemis.domain.enumeration.BuildPlanType.SOLUTION;
import static de.tum.in.www1.artemis.domain.enumeration.BuildPlanType.TEMPLATE;

import java.util.Optional;

import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import de.tum.in.www1.artemis.domain.ProgrammingExercise;
import de.tum.in.www1.artemis.domain.ProgrammingSubmission;
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.RepositoryType;
import de.tum.in.www1.artemis.domain.enumeration.SubmissionType;
import de.tum.in.www1.artemis.domain.participation.SolutionProgrammingExerciseParticipation;
import de.tum.in.www1.artemis.domain.participation.TemplateProgrammingExerciseParticipation;
import de.tum.in.www1.artemis.repository.*;
import de.tum.in.www1.artemis.service.scheduled.ProgrammingExerciseScheduleService;
import de.tum.in.www1.artemis.service.util.VCSSimulationUtils;

/**
* Only for local development
* This class simulates a programming exercises without a connection to a vcs and ci server
* This functionality is only for testing purposes (noVersionControlAndContinuousIntegrationAvailable)
*/

@Profile("dev")
@Service
public class ProgrammingExerciseSimulationService {

private final ProgrammingExerciseRepository programmingExerciseRepository;

private final ProgrammingExerciseScheduleService programmingExerciseScheduleService;

private final GroupNotificationService groupNotificationService;

private final ProgrammingExerciseService programmingExerciseService;

private final TemplateProgrammingExerciseParticipationRepository templateProgrammingExerciseParticipationRepository;

private final SolutionProgrammingExerciseParticipationRepository solutionProgrammingExerciseParticipationRepository;

private final ProgrammingSubmissionRepository programmingSubmissionRepository;

private final ResultRepository resultRepository;

public final String domain = "artemislocalhost:7990/scm/";

public ProgrammingExerciseSimulationService(ProgrammingExerciseRepository programmingExerciseRepository, ProgrammingExerciseScheduleService programmingExerciseScheduleService,
GroupNotificationService groupNotificationService, ProgrammingExerciseService programmingExerciseService,
TemplateProgrammingExerciseParticipationRepository templateProgrammingExerciseParticipationRepository,
SolutionProgrammingExerciseParticipationRepository solutionProgrammingExerciseParticipationRepository, ProgrammingSubmissionRepository programmingSubmissionRepository,
ResultRepository resultRepository) {
this.programmingExerciseRepository = programmingExerciseRepository;
this.programmingExerciseScheduleService = programmingExerciseScheduleService;
this.groupNotificationService = groupNotificationService;
this.programmingExerciseService = programmingExerciseService;
this.templateProgrammingExerciseParticipationRepository = templateProgrammingExerciseParticipationRepository;
this.solutionProgrammingExerciseParticipationRepository = solutionProgrammingExerciseParticipationRepository;
this.programmingSubmissionRepository = programmingSubmissionRepository;
this.resultRepository = resultRepository;
}

/**
* Setups the context of a new programming exercise.
* @param programmingExercise the exercise which should be stored in the database
* @return returns the modified and stored programming exercise
* This functionality is only for testing purposes (noVersionControlAndContinuousIntegrationAvailable)
*/
@Transactional
public ProgrammingExercise setupProgrammingExerciseWithoutVersionControlAndContinuousIntegrationAvailable(ProgrammingExercise programmingExercise) {
programmingExercise.generateAndSetProjectKey();
final var projectKey = programmingExercise.getProjectKey();
// TODO: the following code is used quite often and should be done in only one place
final var exerciseRepoName = projectKey.toLowerCase() + "-" + RepositoryType.TEMPLATE.getName();
final var testRepoName = projectKey.toLowerCase() + "-" + RepositoryType.TESTS.getName();
final var solutionRepoName = projectKey.toLowerCase() + "-" + RepositoryType.SOLUTION.getName();

programmingExerciseService.initParticipations(programmingExercise);
setURLsAndBuildPlanIDsForNewExerciseWithoutVersionControlAndContinuousIntegrationAvailable(programmingExercise, exerciseRepoName, testRepoName, solutionRepoName);
// Save participations to get the ids required for the webhooks
programmingExerciseService.connectBaseParticipationsToExerciseAndSave(programmingExercise);

// save to get the id required for the webhook
programmingExercise = programmingExerciseRepository.save(programmingExercise);

// The creation of the webhooks must occur after the initial push, because the participation is
// not yet saved in the database, so we cannot save the submission accordingly (see ProgrammingSubmissionService.notifyPush)
programmingExerciseScheduleService.scheduleExerciseIfRequired(programmingExercise);
groupNotificationService.notifyTutorGroupAboutExerciseCreated(programmingExercise);

return programmingExercise;
}

/**
* Sets the url and buildplan ids for the new exercise
* @param programmingExercise the new exercise
* @param exerciseRepoName the repo name of the new exercise
* @param testRepoName the test repo name of the new exercise
* @param solutionRepoName the solution repo name of the new exercise
* This functionality is only for testing purposes (noVersionControlAndContinuousIntegrationAvailable)
*/
private void setURLsAndBuildPlanIDsForNewExerciseWithoutVersionControlAndContinuousIntegrationAvailable(ProgrammingExercise programmingExercise, String exerciseRepoName,
String testRepoName, String solutionRepoName) {
final var projectKey = programmingExercise.getProjectKey();
final var templateParticipation = programmingExercise.getTemplateParticipation();
final var solutionParticipation = programmingExercise.getSolutionParticipation();
final var templatePlanName = TEMPLATE.getName();
final var solutionPlanName = SOLUTION.getName();
final var exerciseRepoUrl = "http://" + domain + projectKey + "/" + exerciseRepoName + ".git";
final var testsRepoUrl = "http://" + domain + projectKey + "/" + testRepoName + ".git";
final var solutionRepoUrl = "http://" + domain + projectKey + "/" + solutionRepoName + ".git";
templateParticipation.setBuildPlanId(projectKey + "-" + templatePlanName);
templateParticipation.setRepositoryUrl(exerciseRepoUrl);
solutionParticipation.setBuildPlanId(projectKey + "-" + solutionPlanName);
solutionParticipation.setRepositoryUrl(solutionRepoUrl);
programmingExercise.setTestRepositoryUrl(testsRepoUrl);
}

/**
* This method creates the template and solution submissions and results for the new exercise
* These submissions and results are SIMULATIONS for the testing of programming exercises without a connection to
* the VCS and Continuous Integration server
* @param programmingExercise the new exercise
* This functionality is only for testing purposes (noVersionControlAndContinuousIntegrationAvailable)
*/
public void setupInitialSubmissionsAndResults(ProgrammingExercise programmingExercise) {
Optional<TemplateProgrammingExerciseParticipation> templateProgrammingExerciseParticipation = this.templateProgrammingExerciseParticipationRepository
.findByProgrammingExerciseId(programmingExercise.getId());
Optional<SolutionProgrammingExerciseParticipation> solutionProgrammingExerciseParticipation = this.solutionProgrammingExerciseParticipationRepository
.findByProgrammingExerciseId(programmingExercise.getId());
String commitHashBase = VCSSimulationUtils.simulateCommitHash();
ProgrammingSubmission templateProgrammingSubmission = new ProgrammingSubmission();
templateProgrammingSubmission.setParticipation(templateProgrammingExerciseParticipation.get());
templateProgrammingSubmission.setSubmitted(true);
templateProgrammingSubmission.setType(SubmissionType.OTHER);
templateProgrammingSubmission.setCommitHash(commitHashBase);
templateProgrammingSubmission.setSubmissionDate(templateProgrammingExerciseParticipation.get().getInitializationDate());
programmingSubmissionRepository.save(templateProgrammingSubmission);
Result templateResult = new Result();
templateResult.setParticipation(templateProgrammingExerciseParticipation.get());
templateResult.setSubmission(templateProgrammingSubmission);
templateResult.setRated(true);
templateResult.resultString("0 of 13 passed");
templateResult.setAssessmentType(AssessmentType.AUTOMATIC);
templateResult.score(0L);
templateResult.setCompletionDate(templateProgrammingExerciseParticipation.get().getInitializationDate());
resultRepository.save(templateResult);

ProgrammingSubmission solutionProgrammingSubmission = new ProgrammingSubmission();
String commitHashSolution = VCSSimulationUtils.simulateCommitHash();
solutionProgrammingSubmission.setParticipation(solutionProgrammingExerciseParticipation.get());
solutionProgrammingSubmission.setSubmitted(true);
solutionProgrammingSubmission.setType(SubmissionType.OTHER);
solutionProgrammingSubmission.setCommitHash(commitHashSolution);
solutionProgrammingSubmission.setSubmissionDate(solutionProgrammingExerciseParticipation.get().getInitializationDate());
programmingSubmissionRepository.save(solutionProgrammingSubmission);
Result solutionResult = new Result();
solutionResult.setParticipation(solutionProgrammingExerciseParticipation.get());
solutionResult.setSubmission(solutionProgrammingSubmission);
solutionResult.setRated(true);
solutionResult.resultString("13 of 13 passed");
solutionResult.score(100L);
solutionResult.setAssessmentType(AssessmentType.AUTOMATIC);
solutionResult.setCompletionDate(solutionProgrammingExerciseParticipation.get().getInitializationDate());
resultRepository.save(solutionResult);
}

}
Loading

0 comments on commit 713e87c

Please sign in to comment.