exerciseHintActivations) {
- this.exerciseHintActivations = exerciseHintActivations;
- }
-
- /**
- * Returns a threshold value that defines when this exercise hint is displayed to student participating in a programming exercise.
- * The algorithm defining if the hint is display is described in {@link ExerciseHintService#getAvailableExerciseHints}
- *
- * @return the display threshold value
- */
- public short getDisplayThreshold() {
- return displayThreshold;
- }
-
- public void setDisplayThreshold(short displayThreshold) {
- this.displayThreshold = displayThreshold;
- }
-
- /**
- * Creates a copy of this hint including basic attributes, but excluding attributes referencing other models
- *
- * @return The copied hint
- */
- public ExerciseHint createCopy() {
- ExerciseHint copiedHint = new ExerciseHint();
-
- copiedHint.setDescription(this.getDescription());
- copiedHint.setContent(this.getContent());
- copiedHint.setTitle(this.getTitle());
- return copiedHint;
- }
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/domain/hestia/ExerciseHintActivation.java b/src/main/java/de/tum/cit/aet/artemis/programming/domain/hestia/ExerciseHintActivation.java
deleted file mode 100644
index 595c90d61abb..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/programming/domain/hestia/ExerciseHintActivation.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package de.tum.cit.aet.artemis.programming.domain.hestia;
-
-import java.time.ZonedDateTime;
-
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.ManyToOne;
-import jakarta.persistence.Table;
-
-import org.hibernate.annotations.Cache;
-import org.hibernate.annotations.CacheConcurrencyStrategy;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-
-import de.tum.cit.aet.artemis.core.domain.DomainObject;
-import de.tum.cit.aet.artemis.core.domain.User;
-
-@Entity
-@Table(name = "exercise_hint_activation")
-@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
-@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public class ExerciseHintActivation extends DomainObject {
-
- @ManyToOne(optional = false)
- private User user;
-
- @ManyToOne(optional = false)
- private ExerciseHint exerciseHint;
-
- @Column(name = "activation_date", nullable = false)
- private ZonedDateTime activationDate;
-
- @Column(name = "rating")
- private Integer rating;
-
- public User getUser() {
- return user;
- }
-
- public void setUser(User user) {
- this.user = user;
- }
-
- public ExerciseHint getExerciseHint() {
- return exerciseHint;
- }
-
- public void setExerciseHint(ExerciseHint exerciseHint) {
- this.exerciseHint = exerciseHint;
- }
-
- public ZonedDateTime getActivationDate() {
- return activationDate;
- }
-
- public void setActivationDate(ZonedDateTime activationDate) {
- this.activationDate = activationDate;
- }
-
- public Integer getRating() {
- return rating;
- }
-
- public void setRating(Integer rating) {
- this.rating = rating;
- }
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/domain/hestia/ProgrammingExerciseSolutionEntry.java b/src/main/java/de/tum/cit/aet/artemis/programming/domain/hestia/ProgrammingExerciseSolutionEntry.java
deleted file mode 100644
index 01cf4ce871b4..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/programming/domain/hestia/ProgrammingExerciseSolutionEntry.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package de.tum.cit.aet.artemis.programming.domain.hestia;
-
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.ManyToOne;
-import jakarta.persistence.Table;
-
-import org.hibernate.annotations.Cache;
-import org.hibernate.annotations.CacheConcurrencyStrategy;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import de.tum.cit.aet.artemis.core.domain.DomainObject;
-import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseTestCase;
-
-/**
- * A ProgrammingExerciseSolutionEntry represents a single change in a file that a students has to make in order to pass the related test.
- * It is structured similarly to a git diff entry.
- * If it replaces existing code it will contain the previous code that it replaces otherwise previousCode will be null.
- * If it is only removing existing code the code attribute will be null.
- * If it encompasses the addition of an entire file, previousLine will be null.
- * If it deletes an entire file, line will be null.
- * previousLine and line will be different when there are other changes higher up in the file.
- *
- * Example:
- * A print statement gets changed:
- *
- * SolutionEntry {
- * filePath = "<...>"
- * previousLine = 12
- * previousCode = System.out.println("Tset");
- * line = 12
- * code = System.out.println("Test");
- * }
- *
- */
-@Entity
-@Table(name = "programming_exercise_solution_entry")
-@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
-@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public class ProgrammingExerciseSolutionEntry extends DomainObject {
-
- @Column(name = "file_path")
- private String filePath;
-
- // The line at which the previous code segment is in the template
- @Column(name = "previous_line")
- private Integer previousLine;
-
- // The line at which the new code segment is in the solution
- @Column(name = "line")
- private Integer line;
-
- // The previous code segment to be replaced by the new code segment
- @Column(name = "previous_code")
- private String previousCode;
-
- // The new code segment that replaces the old code segment
- @Column(name = "code")
- private String code;
-
- // Fetched lazily, as we never need the code hint when fetching solution entries
- @ManyToOne(fetch = FetchType.LAZY)
- @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
- private CodeHint codeHint;
-
- @ManyToOne
- @JsonIgnoreProperties(value = "solutionEntries", allowSetters = true)
- private ProgrammingExerciseTestCase testCase;
-
- public String getFilePath() {
- return filePath;
- }
-
- public void setFilePath(String file) {
- this.filePath = file;
- }
-
- public Integer getPreviousLine() {
- return previousLine;
- }
-
- public void setPreviousLine(Integer previousLine) {
- this.previousLine = previousLine;
- }
-
- public Integer getLine() {
- return line;
- }
-
- public void setLine(Integer line) {
- this.line = line;
- }
-
- public String getPreviousCode() {
- return previousCode;
- }
-
- public void setPreviousCode(String previousCode) {
- this.previousCode = previousCode;
- }
-
- public String getCode() {
- return code;
- }
-
- public void setCode(String code) {
- this.code = code;
- }
-
- public CodeHint getCodeHint() {
- return codeHint;
- }
-
- public void setCodeHint(CodeHint codeHint) {
- this.codeHint = codeHint;
- }
-
- public ProgrammingExerciseTestCase getTestCase() {
- return this.testCase;
- }
-
- public void setTestCase(ProgrammingExerciseTestCase testCase) {
- this.testCase = testCase;
- }
-
- @Override
- public String toString() {
- return "ProgrammingExerciseSolutionEntry{" + "id=" + getId() + '\'' + ", filePath='" + filePath + '\'' + ", previousLine=" + previousLine + ", line=" + line
- + ", previousCode='" + previousCode + '\'' + ", code='" + code + '\'' + '}';
- }
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/domain/hestia/TestwiseCoverageReportEntry.java b/src/main/java/de/tum/cit/aet/artemis/programming/domain/hestia/TestwiseCoverageReportEntry.java
deleted file mode 100644
index 60383357c9dc..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/programming/domain/hestia/TestwiseCoverageReportEntry.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package de.tum.cit.aet.artemis.programming.domain.hestia;
-
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.ManyToOne;
-import jakarta.persistence.Table;
-
-import org.hibernate.annotations.Cache;
-import org.hibernate.annotations.CacheConcurrencyStrategy;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonInclude;
-
-import de.tum.cit.aet.artemis.core.domain.DomainObject;
-import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseTestCase;
-
-/**
- * A single entry from testwise coverage report by file path and consecutive executed code block.
- * A block is represented by the start line and the length (i.e. number of lines) of the block.
- */
-@Entity
-@Table(name = "testwise_coverage_report_entry")
-@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
-@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public class TestwiseCoverageReportEntry extends DomainObject {
-
- @ManyToOne
- @JsonIgnoreProperties("testwiseCoverageEntries")
- private CoverageFileReport fileReport;
-
- @ManyToOne
- @JsonIgnoreProperties("coverageEntries")
- private ProgrammingExerciseTestCase testCase;
-
- @Column(name = "start_line")
- private Integer startLine;
-
- @Column(name = "line_count")
- private Integer lineCount;
-
- public CoverageFileReport getFileReport() {
- return fileReport;
- }
-
- public void setFileReport(CoverageFileReport fileReport) {
- this.fileReport = fileReport;
- }
-
- public ProgrammingExerciseTestCase getTestCase() {
- return testCase;
- }
-
- public void setTestCase(ProgrammingExerciseTestCase testCase) {
- this.testCase = testCase;
- }
-
- public Integer getStartLine() {
- return startLine;
- }
-
- public void setStartLine(Integer startLine) {
- this.startLine = startLine;
- }
-
- public Integer getLineCount() {
- return lineCount;
- }
-
- public void setLineCount(Integer lineCount) {
- this.lineCount = lineCount;
- }
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/dto/BuildJobDTOInterface.java b/src/main/java/de/tum/cit/aet/artemis/programming/dto/BuildJobInterface.java
similarity index 74%
rename from src/main/java/de/tum/cit/aet/artemis/programming/dto/BuildJobDTOInterface.java
rename to src/main/java/de/tum/cit/aet/artemis/programming/dto/BuildJobInterface.java
index 3d838ca6233b..0a8a7362deef 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/dto/BuildJobDTOInterface.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/dto/BuildJobInterface.java
@@ -8,19 +8,19 @@
* Interface for DTOs that represent a build job.
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public interface BuildJobDTOInterface {
+public interface BuildJobInterface {
/**
* Gets the failed tests of the build job.
*
* @return list of failed tests.
*/
- List extends TestCaseBaseDTO> getFailedTests();
+ List extends TestCaseBase> failedTests();
/**
* Gets the successful tests of the build job.
*
* @return list of successful tests.
*/
- List extends TestCaseBaseDTO> getSuccessfulTests();
+ List extends TestCaseBase> successfulTests();
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/dto/AbstractBuildResultNotificationDTO.java b/src/main/java/de/tum/cit/aet/artemis/programming/dto/BuildResultNotification.java
similarity index 54%
rename from src/main/java/de/tum/cit/aet/artemis/programming/dto/AbstractBuildResultNotificationDTO.java
rename to src/main/java/de/tum/cit/aet/artemis/programming/dto/BuildResultNotification.java
index 9435fdf8e463..bfad4eba2de8 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/dto/AbstractBuildResultNotificationDTO.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/dto/BuildResultNotification.java
@@ -11,27 +11,25 @@
import de.tum.cit.aet.artemis.exercise.domain.SubmissionType;
import de.tum.cit.aet.artemis.programming.domain.build.BuildLogEntry;
-import de.tum.cit.aet.artemis.programming.service.ci.notification.dto.TestwiseCoverageReportDTO;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
-// TODO: convert subclasses to records
-public abstract class AbstractBuildResultNotificationDTO {
+public interface BuildResultNotification {
- public abstract ZonedDateTime getBuildRunDate();
+ ZonedDateTime buildRunDate();
@Nullable
- protected abstract String getCommitHashFromAssignmentRepo();
+ String assignmentRepoCommitHash();
@Nullable
- protected abstract String getCommitHashFromTestsRepo();
+ String testsRepoCommitHash();
@Nullable
- public abstract String getBranchNameFromAssignmentRepo();
+ String assignmentRepoBranchName();
- public abstract boolean isBuildSuccessful();
+ boolean isBuildSuccessful();
- public abstract Double getBuildScore();
+ Double buildScore();
/**
* Get the commit hash from the build result, the commit hash will be different for submission types or null.
@@ -40,22 +38,22 @@ public abstract class AbstractBuildResultNotificationDTO {
* @return if the commit hash for the given submission type was found, otherwise empty.
*/
@Nullable
- public String getCommitHash(SubmissionType submissionType) {
+ default String commitHash(SubmissionType submissionType) {
final var isAssignmentSubmission = List.of(SubmissionType.MANUAL, SubmissionType.INSTRUCTOR, SubmissionType.ILLEGAL).contains(submissionType);
if (isAssignmentSubmission) {
- return getCommitHashFromAssignmentRepo();
+ return assignmentRepoCommitHash();
}
else if (submissionType.equals(SubmissionType.TEST)) {
- return getCommitHashFromTestsRepo();
+ return testsRepoCommitHash();
}
return null;
}
- public abstract boolean hasArtifact();
+ boolean hasArtifact();
- public abstract boolean hasLogs();
+ boolean hasLogs();
- public abstract List extractBuildLogs();
+ List extractBuildLogs();
/**
* Gets the build jobs that are part of the build result.
@@ -63,19 +61,12 @@ else if (submissionType.equals(SubmissionType.TEST)) {
* @return list of build jobs.
*/
@JsonIgnore
- public abstract List extends BuildJobDTOInterface> getBuildJobs();
+ List extends BuildJobInterface> jobs();
/**
* Gets the static code analysis reports that are part of the build result.
*
* @return list of static code analysis reports.
*/
- public abstract List getStaticCodeAnalysisReports();
-
- /**
- * Gets the test-wise coverage reports that are part of the build result.
- *
- * @return list of test-wise coverage reports.
- */
- public abstract List getTestwiseCoverageReports();
+ List staticCodeAnalysisReports();
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/dto/ConsistencyErrorDTO.java b/src/main/java/de/tum/cit/aet/artemis/programming/dto/ConsistencyErrorDTO.java
index d200a62e3422..4e4e582cbebe 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/dto/ConsistencyErrorDTO.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/dto/ConsistencyErrorDTO.java
@@ -1,7 +1,5 @@
package de.tum.cit.aet.artemis.programming.dto;
-import java.util.Objects;
-
import com.fasterxml.jackson.annotation.JsonInclude;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise;
@@ -9,63 +7,11 @@
/**
* A DTO representing a consistency error
*/
+// TODO: use a ProgrammingExerciseDTO instead of the whole ProgrammingExercise entity
@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public class ConsistencyErrorDTO {
-
- private ProgrammingExercise programmingExercise;
-
- private ErrorType type;
-
- public ConsistencyErrorDTO(ProgrammingExercise programmingExercise, ErrorType type) {
- this.programmingExercise = programmingExercise;
- this.type = type;
- }
-
- public ProgrammingExercise getProgrammingExercise() {
- return programmingExercise;
- }
-
- public void setProgrammingExercise(ProgrammingExercise programmingExercise) {
- this.programmingExercise = programmingExercise;
- }
-
- public ErrorType getType() {
- return type;
- }
-
- public void setType(ErrorType type) {
- this.type = type;
- }
+public record ConsistencyErrorDTO(ProgrammingExercise programmingExercise, ErrorType type) {
public enum ErrorType {
-
VCS_PROJECT_MISSING, TEMPLATE_REPO_MISSING, SOLUTION_REPO_MISSING, AUXILIARY_REPO_MISSING, TEST_REPO_MISSING, TEMPLATE_BUILD_PLAN_MISSING, SOLUTION_BUILD_PLAN_MISSING;
-
- @Override
- public String toString() {
- return name();
- }
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- ConsistencyErrorDTO that = (ConsistencyErrorDTO) obj;
- return Objects.equals(getProgrammingExercise(), that.getProgrammingExercise()) && getType() == that.getType();
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(getProgrammingExercise(), getType());
- }
-
- @Override
- public String toString() {
- return "ConsistencyErrorDTO{" + "programmingExercise='" + programmingExercise.getTitle() + "', type='" + type.name() + "'}";
}
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/dto/CoverageReportAndSubmissionDateDTO.java b/src/main/java/de/tum/cit/aet/artemis/programming/dto/CoverageReportAndSubmissionDateDTO.java
deleted file mode 100644
index a5ddfd8550d6..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/programming/dto/CoverageReportAndSubmissionDateDTO.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package de.tum.cit.aet.artemis.programming.dto;
-
-import java.time.ZonedDateTime;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-
-import de.tum.cit.aet.artemis.programming.domain.hestia.CoverageReport;
-
-@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public record CoverageReportAndSubmissionDateDTO(CoverageReport coverageReport, ZonedDateTime submissionDate) {
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/dto/ProgrammingExerciseGitDiffEntryDTO.java b/src/main/java/de/tum/cit/aet/artemis/programming/dto/ProgrammingExerciseGitDiffEntryDTO.java
index 6b5f37149cd6..67707c175ab0 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/dto/ProgrammingExerciseGitDiffEntryDTO.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/dto/ProgrammingExerciseGitDiffEntryDTO.java
@@ -2,7 +2,7 @@
import com.fasterxml.jackson.annotation.JsonInclude;
-import de.tum.cit.aet.artemis.programming.domain.hestia.ProgrammingExerciseGitDiffEntry;
+import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseGitDiffEntry;
/**
* DTO for a git diff report entry.
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/dto/ProgrammingExerciseGitDiffReportDTO.java b/src/main/java/de/tum/cit/aet/artemis/programming/dto/ProgrammingExerciseGitDiffReportDTO.java
index 6f027a90326b..04e32ff039d1 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/dto/ProgrammingExerciseGitDiffReportDTO.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/dto/ProgrammingExerciseGitDiffReportDTO.java
@@ -5,7 +5,7 @@
import com.fasterxml.jackson.annotation.JsonInclude;
-import de.tum.cit.aet.artemis.programming.domain.hestia.ProgrammingExerciseGitDiffReport;
+import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseGitDiffReport;
/**
* DTO for a git diff report.
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/dto/TestCaseBaseDTO.java b/src/main/java/de/tum/cit/aet/artemis/programming/dto/TestCaseBase.java
similarity index 85%
rename from src/main/java/de/tum/cit/aet/artemis/programming/dto/TestCaseBaseDTO.java
rename to src/main/java/de/tum/cit/aet/artemis/programming/dto/TestCaseBase.java
index 267caa9256db..fef892e8fb16 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/dto/TestCaseBaseDTO.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/dto/TestCaseBase.java
@@ -9,14 +9,14 @@
* Interface for DTOs that represent a test case.
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public interface TestCaseBaseDTO {
+public interface TestCaseBase {
/**
* Gets the name of the test case
*
* @return the name of the test case
*/
- String getName();
+ String name();
/**
* Gets the messages of the test case (typically error messages)
@@ -24,5 +24,5 @@ public interface TestCaseBaseDTO {
* @return the messages of the test case
*/
@JsonIgnore
- List getTestMessages();
+ List testMessages();
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/Action.java b/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/Action.java
new file mode 100644
index 000000000000..34f2cfb9537f
--- /dev/null
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/Action.java
@@ -0,0 +1,30 @@
+package de.tum.cit.aet.artemis.programming.dto.aeolus;
+
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+/**
+ * Base for the actions that can be defined in a {@link Windfile}
+ * NOTE: you must create a record that implements this interface to specify actions
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_EMPTY)
+public interface Action {
+
+ Map parameters();
+
+ Map environment();
+
+ boolean runAlways();
+
+ String name();
+
+ List results();
+
+ String workdir();
+
+ String platform();
+}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/AeolusRepository.java b/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/AeolusRepository.java
similarity index 85%
rename from src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/AeolusRepository.java
rename to src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/AeolusRepository.java
index 6793fb84db1d..84dc2e893d88 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/AeolusRepository.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/AeolusRepository.java
@@ -1,4 +1,4 @@
-package de.tum.cit.aet.artemis.programming.service.aeolus;
+package de.tum.cit.aet.artemis.programming.dto.aeolus;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/AeolusResult.java b/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/AeolusResult.java
similarity index 83%
rename from src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/AeolusResult.java
rename to src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/AeolusResult.java
index 12f319121957..096e98701702 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/AeolusResult.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/AeolusResult.java
@@ -1,4 +1,4 @@
-package de.tum.cit.aet.artemis.programming.service.aeolus;
+package de.tum.cit.aet.artemis.programming.dto.aeolus;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/DockerConfig.java b/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/DockerConfig.java
similarity index 95%
rename from src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/DockerConfig.java
rename to src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/DockerConfig.java
index 5f5161737a6a..ed8cc72283c1 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/DockerConfig.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/DockerConfig.java
@@ -1,4 +1,4 @@
-package de.tum.cit.aet.artemis.programming.service.aeolus;
+package de.tum.cit.aet.artemis.programming.dto.aeolus;
import java.util.List;
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/PlatformAction.java b/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/PlatformAction.java
new file mode 100644
index 000000000000..d2bde6916175
--- /dev/null
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/PlatformAction.java
@@ -0,0 +1,17 @@
+package de.tum.cit.aet.artemis.programming.dto.aeolus;
+
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+/**
+ * Represents a CI action that is intended to run only on a specific target, can be used in a {@link Windfile}.
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_EMPTY)
+public record PlatformAction(String name, Map parameters, Map environment, List results, String workdir, boolean runAlways,
+ String platform, String kind, String type) implements Action {
+
+}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/ScriptAction.java b/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/ScriptAction.java
similarity index 60%
rename from src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/ScriptAction.java
rename to src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/ScriptAction.java
index 5006e8a850a6..9716b97deac0 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/ScriptAction.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/ScriptAction.java
@@ -1,4 +1,7 @@
-package de.tum.cit.aet.artemis.programming.service.aeolus;
+package de.tum.cit.aet.artemis.programming.dto.aeolus;
+
+import java.util.List;
+import java.util.Map;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
@@ -8,18 +11,9 @@
* independent actions but also to run actions on a single target. (e.q. the parsing of the test results that needs to
* run on Jenkins but not in LocalCI)
*/
-// TODO: convert into Record
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public class ScriptAction extends Action {
-
- private String script;
-
- public String getScript() {
- return script;
- }
+public record ScriptAction(String name, Map parameters, Map environment, List results, String workdir, boolean runAlways,
+ String platform, String script) implements Action {
- public void setScript(String script) {
- this.script = script;
- }
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/Windfile.java b/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/Windfile.java
new file mode 100644
index 000000000000..f975a45acc60
--- /dev/null
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/Windfile.java
@@ -0,0 +1,86 @@
+package de.tum.cit.aet.artemis.programming.dto.aeolus;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+
+import de.tum.cit.aet.artemis.programming.service.aeolus.ActionDeserializer;
+
+/**
+ * Represents a windfile, the definition file for an aeolus build plan that can then be used to generate a Jenkinsfile.
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_EMPTY)
+public record Windfile(String api, WindfileMetadata metadata, List actions, Map repositories) {
+
+ public Windfile {
+ if (actions == null) {
+ actions = new ArrayList<>();
+ }
+ if (repositories == null) {
+ repositories = new HashMap<>();
+ }
+ }
+
+ private static final ObjectMapper mapper = new ObjectMapper();
+
+ /**
+ * Creates a new windfile based on an existing one with updated metadata.
+ *
+ * @param existingWindfile the existing windfile to base the new one on.
+ * @param metadata the metadata of the newly created windfile.
+ */
+ public Windfile(Windfile existingWindfile, WindfileMetadata metadata) {
+ this(existingWindfile.api(), metadata, existingWindfile.actions(), existingWindfile.repositories());
+ }
+
+ /**
+ * Creates a new windfile based on an existing one with updated metadata.
+ *
+ * @param existingWindfile the existing windfile to base the new one on.
+ * @param metadata the metadata of the newly created windfile.
+ * @param repositories the repositories of the newly created windfile.
+ */
+ public Windfile(Windfile existingWindfile, WindfileMetadata metadata, Map repositories) {
+ this(existingWindfile.api(), metadata, existingWindfile.actions(), repositories);
+ }
+
+ /**
+ * Deserializes a windfile from a json string.
+ *
+ * @param json the json string to deserialize.
+ * @return the deserialized windfile.
+ * @throws JsonProcessingException if the json string is not valid.
+ */
+ public static Windfile deserialize(String json) throws JsonProcessingException {
+ SimpleModule module = new SimpleModule();
+ module.addDeserializer(Action.class, new ActionDeserializer());
+ mapper.registerModule(module);
+ return mapper.readValue(json, Windfile.class);
+ }
+
+ /**
+ * Gets the script actions of a windfile.
+ *
+ * @return the script actions of a windfile.
+ */
+ public List scriptActions() {
+ return actions.stream().filter(ScriptAction.class::isInstance).map(ScriptAction.class::cast).toList();
+ }
+
+ /**
+ * Collects the results of all actions of a windfile.
+ *
+ * @return the results of all actions of this windfile
+ */
+ public List results() {
+ return actions.stream().filter(action -> action.results() != null && !action.results().isEmpty()).flatMap(action -> action.results().stream()).toList();
+ }
+}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/WindfileMetadata.java b/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/WindfileMetadata.java
similarity index 90%
rename from src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/WindfileMetadata.java
rename to src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/WindfileMetadata.java
index 5e9d1547ddfa..0c5def63abd7 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/WindfileMetadata.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/dto/aeolus/WindfileMetadata.java
@@ -1,4 +1,4 @@
-package de.tum.cit.aet.artemis.programming.service.aeolus;
+package de.tum.cit.aet.artemis.programming.dto.aeolus;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseGitDiffReportRepository.java b/src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseGitDiffReportRepository.java
similarity index 88%
rename from src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseGitDiffReportRepository.java
rename to src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseGitDiffReportRepository.java
index d1c5b9acf8d0..37b6b9fb3522 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseGitDiffReportRepository.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseGitDiffReportRepository.java
@@ -1,4 +1,4 @@
-package de.tum.cit.aet.artemis.programming.repository.hestia;
+package de.tum.cit.aet.artemis.programming.repository;
import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;
@@ -10,7 +10,7 @@
import org.springframework.transaction.annotation.Transactional;
import de.tum.cit.aet.artemis.core.repository.base.ArtemisJpaRepository;
-import de.tum.cit.aet.artemis.programming.domain.hestia.ProgrammingExerciseGitDiffReport;
+import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseGitDiffReport;
/**
* Spring Data JPA repository for the ProgrammingExerciseGitDiffReport entity.
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java b/src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java
index 73ea3f0cddc3..8641ccd9e48c 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java
@@ -314,11 +314,9 @@ default ProgrammingExercise findOneByProjectKeyOrThrow(String projectKey, boolea
FROM ProgrammingExercise p
LEFT JOIN FETCH p.testCases tc
LEFT JOIN FETCH p.staticCodeAnalysisCategories
- LEFT JOIN FETCH p.exerciseHints
LEFT JOIN FETCH p.templateParticipation
LEFT JOIN FETCH p.solutionParticipation
LEFT JOIN FETCH p.auxiliaryRepositories
- LEFT JOIN FETCH tc.solutionEntries
LEFT JOIN FETCH p.buildConfig
WHERE p.id = :exerciseId
""")
@@ -330,15 +328,13 @@ Optional findByIdWithEagerTestCasesStaticCodeAnalysisCatego
FROM ProgrammingExercise p
LEFT JOIN FETCH p.testCases tc
LEFT JOIN FETCH p.staticCodeAnalysisCategories
- LEFT JOIN FETCH p.exerciseHints
LEFT JOIN FETCH p.templateParticipation
LEFT JOIN FETCH p.solutionParticipation
LEFT JOIN FETCH p.auxiliaryRepositories
- LEFT JOIN FETCH tc.solutionEntries
LEFT JOIN FETCH p.buildConfig
WHERE p.id = :exerciseId
""")
- Optional findByIdWithEagerBuildConfigTestCasesStaticCodeAnalysisCategoriesHintsAndTemplateAndSolutionParticipationsAndAuxReposAndSolutionEntriesAndBuildConfig(
+ Optional findByIdWithEagerBuildConfigTestCasesStaticCodeAnalysisCategoriesAndTemplateAndSolutionParticipationsAndAuxReposAndAndBuildConfig(
@Param("exerciseId") long exerciseId);
@Query("""
@@ -346,11 +342,9 @@ Optional findByIdWithEagerBuildConfigTestCasesStaticCodeAna
FROM ProgrammingExercise p
LEFT JOIN FETCH p.testCases tc
LEFT JOIN FETCH p.staticCodeAnalysisCategories
- LEFT JOIN FETCH p.exerciseHints
LEFT JOIN FETCH p.templateParticipation
LEFT JOIN FETCH p.solutionParticipation
LEFT JOIN FETCH p.auxiliaryRepositories
- LEFT JOIN FETCH tc.solutionEntries
LEFT JOIN FETCH p.buildConfig
LEFT JOIN FETCH p.plagiarismDetectionConfig
WHERE p.id = :exerciseId
@@ -976,7 +970,6 @@ enum ProgrammingExerciseFetchOptions implements FetchOptions {
Tasks(ProgrammingExercise_.TASKS),
StaticCodeAnalysisCategories(ProgrammingExercise_.STATIC_CODE_ANALYSIS_CATEGORIES),
SubmissionPolicy(ProgrammingExercise_.SUBMISSION_POLICY),
- ExerciseHints(ProgrammingExercise_.EXERCISE_HINTS),
CompetencyLinks(ProgrammingExercise_.COMPETENCY_LINKS),
Teams(ProgrammingExercise_.TEAMS),
TutorParticipations(ProgrammingExercise_.TUTOR_PARTICIPATIONS),
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseTaskRepository.java b/src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseTaskRepository.java
similarity index 74%
rename from src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseTaskRepository.java
rename to src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseTaskRepository.java
index 778c0c811374..fb2f47556daf 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseTaskRepository.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseTaskRepository.java
@@ -1,4 +1,4 @@
-package de.tum.cit.aet.artemis.programming.repository.hestia;
+package de.tum.cit.aet.artemis.programming.repository;
import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;
@@ -15,7 +15,7 @@
import de.tum.cit.aet.artemis.core.exception.EntityNotFoundException;
import de.tum.cit.aet.artemis.core.repository.base.ArtemisJpaRepository;
-import de.tum.cit.aet.artemis.programming.domain.hestia.ProgrammingExerciseTask;
+import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseTask;
/**
* Spring Data repository for the ProgrammingExerciseTask entity.
@@ -32,8 +32,8 @@ public interface ProgrammingExerciseTaskRepository extends ArtemisJpaRepository<
* @throws EntityNotFoundException If the exercise with exerciseId does not exist
*/
@NotNull
- default List findByExerciseIdWithTestCaseAndSolutionEntriesElseThrow(long exerciseId) throws EntityNotFoundException {
- return getArbitraryValueElseThrow(findByExerciseIdWithTestCaseAndSolutionEntries(exerciseId), Long.toString(exerciseId));
+ default List findByExerciseIdWithTestCaseElseThrow(long exerciseId) throws EntityNotFoundException {
+ return getArbitraryValueElseThrow(findByExerciseIdWithTestCase(exerciseId), Long.toString(exerciseId));
}
/**
@@ -46,11 +46,10 @@ default List findByExerciseIdWithTestCaseAndSolutionEnt
SELECT t
FROM ProgrammingExerciseTask t
LEFT JOIN FETCH t.testCases tc
- LEFT JOIN FETCH tc.solutionEntries
WHERE t.exercise.id = :exerciseId
AND tc.exercise.id = :exerciseId
""")
- Optional> findByExerciseIdWithTestCaseAndSolutionEntries(@Param("exerciseId") long exerciseId);
+ Optional> findByExerciseIdWithTestCase(@Param("exerciseId") long exerciseId);
/**
* Gets all tasks with its test cases for a programming exercise
@@ -62,17 +61,7 @@ default List findByExerciseIdWithTestCaseAndSolutionEnt
SELECT t
FROM ProgrammingExerciseTask t
LEFT JOIN FETCH t.testCases tc
- LEFT JOIN FETCH tc.solutionEntries
WHERE t.exercise.id = :exerciseId
""")
Set findByExerciseIdWithTestCases(@Param("exerciseId") Long exerciseId);
-
- @Query("""
- SELECT pt
- FROM ProgrammingExerciseTask pt
- LEFT JOIN FETCH pt.exerciseHints h
- LEFT JOIN FETCH pt.testCases tc
- WHERE h.id = :codeHintId
- """)
- Optional findByCodeHintIdWithTestCases(@Param("codeHintId") Long codeHintId);
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseTestCaseRepository.java b/src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseTestCaseRepository.java
index 0ec309e45e8b..3924a5de856a 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseTestCaseRepository.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseTestCaseRepository.java
@@ -2,7 +2,6 @@
import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;
-import java.util.Optional;
import java.util.Set;
import org.springframework.context.annotation.Profile;
@@ -23,40 +22,6 @@ public interface ProgrammingExerciseTestCaseRepository extends ArtemisJpaReposit
Set findByExerciseId(long exerciseId);
- default ProgrammingExerciseTestCase findByIdWithExerciseElseThrow(long testCaseId) {
- return getValueElseThrow(findByIdWithExercise(testCaseId), testCaseId);
- }
-
- /**
- * Returns the test case with the programming exercise
- *
- * @param testCaseId of the test case
- * @return the test case with the programming exercise
- */
- @Query("""
- SELECT tc
- FROM ProgrammingExerciseTestCase tc
- LEFT JOIN FETCH tc.exercise ex
- WHERE tc.id = :testCaseId
- """)
- Optional findByIdWithExercise(@Param("testCaseId") long testCaseId);
-
- /**
- * Returns all test cases with the associated solution entries for a programming exercise
- *
- * @param exerciseId of the exercise
- * @param active status of the test case
- * @return all test cases with the associated solution entries
- */
- @Query("""
- SELECT DISTINCT tc
- FROM ProgrammingExerciseTestCase tc
- LEFT JOIN FETCH tc.solutionEntries se
- WHERE tc.exercise.id = :exerciseId
- AND tc.active = :active
- """)
- Set findByExerciseIdWithSolutionEntriesAndActive(@Param("exerciseId") long exerciseId, @Param("active") Boolean active);
-
Set findByExerciseIdAndActive(long exerciseId, Boolean active);
/**
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/CodeHintRepository.java b/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/CodeHintRepository.java
deleted file mode 100644
index 9c4a03766832..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/CodeHintRepository.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package de.tum.cit.aet.artemis.programming.repository.hestia;
-
-import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;
-
-import java.util.Optional;
-import java.util.Set;
-
-import jakarta.validation.constraints.NotNull;
-
-import org.springframework.context.annotation.Profile;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.query.Param;
-import org.springframework.stereotype.Repository;
-
-import de.tum.cit.aet.artemis.core.exception.EntityNotFoundException;
-import de.tum.cit.aet.artemis.core.repository.base.ArtemisJpaRepository;
-import de.tum.cit.aet.artemis.programming.domain.hestia.CodeHint;
-
-/**
- * Spring Data repository for the CodeHint entity.
- */
-@Profile(PROFILE_CORE)
-@Repository
-public interface CodeHintRepository extends ArtemisJpaRepository {
-
- Set findByExerciseId(Long exerciseId);
-
- @NotNull
- default CodeHint findByIdWithSolutionEntriesElseThrow(long exerciseHintId) throws EntityNotFoundException {
- return getValueElseThrow(findByIdWithSolutionEntries(exerciseHintId), exerciseHintId);
- }
-
- @Query("""
- SELECT h
- FROM CodeHint h
- LEFT JOIN FETCH h.task t
- LEFT JOIN FETCH h.solutionEntries tc
- WHERE h.id = :codeHintId
- """)
- Optional findByIdWithSolutionEntries(@Param("codeHintId") Long codeHintId);
-
- @Query("""
- SELECT h
- FROM CodeHint h
- LEFT JOIN FETCH h.task t
- LEFT JOIN FETCH h.solutionEntries tc
- WHERE t.id = :taskId
- """)
- Set findByTaskIdWithSolutionEntries(@Param("taskId") Long taskId);
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/CoverageFileReportRepository.java b/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/CoverageFileReportRepository.java
deleted file mode 100644
index 69bcac01e5ac..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/CoverageFileReportRepository.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package de.tum.cit.aet.artemis.programming.repository.hestia;
-
-import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;
-
-import org.springframework.context.annotation.Profile;
-import org.springframework.stereotype.Repository;
-
-import de.tum.cit.aet.artemis.core.repository.base.ArtemisJpaRepository;
-import de.tum.cit.aet.artemis.programming.domain.hestia.CoverageFileReport;
-
-@Profile(PROFILE_CORE)
-@Repository
-public interface CoverageFileReportRepository extends ArtemisJpaRepository {
-
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/CoverageReportRepository.java b/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/CoverageReportRepository.java
deleted file mode 100644
index eefc9aeb5848..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/CoverageReportRepository.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package de.tum.cit.aet.artemis.programming.repository.hestia;
-
-import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;
-import static org.springframework.data.jpa.repository.EntityGraph.EntityGraphType.LOAD;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
-
-import org.springframework.context.annotation.Profile;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.repository.EntityGraph;
-import org.springframework.data.jpa.repository.Modifying;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.query.Param;
-import org.springframework.stereotype.Repository;
-import org.springframework.transaction.annotation.Transactional;
-
-import de.tum.cit.aet.artemis.core.domain.DomainObject;
-import de.tum.cit.aet.artemis.core.repository.base.ArtemisJpaRepository;
-import de.tum.cit.aet.artemis.programming.domain.hestia.CoverageReport;
-import de.tum.cit.aet.artemis.programming.dto.CoverageReportAndSubmissionDateDTO;
-
-/**
- * Spring Data JPA repository for the CoverageReport entity.
- */
-@Profile(PROFILE_CORE)
-@Repository
-public interface CoverageReportRepository extends ArtemisJpaRepository {
-
- Boolean existsBySubmissionId(Long submissionId);
-
- @Transactional // ok because of delete
- @Modifying
- void deleteBySubmissionId(Long submissionId);
-
- @Query("""
- SELECT new de.tum.cit.aet.artemis.programming.dto.CoverageReportAndSubmissionDateDTO(r, s.submissionDate)
- FROM CoverageReport r
- JOIN r.submission s
- JOIN ProgrammingExercise pe ON s.participation = pe.solutionParticipation
- WHERE pe.id = :programmingExerciseId
- AND (s.type <> de.tum.cit.aet.artemis.exercise.domain.SubmissionType.ILLEGAL OR s.type IS NULL)
- ORDER BY s.submissionDate DESC
- """)
- List findCoverageReportsByProgrammingExerciseId(@Param("programmingExerciseId") Long programmingExerciseId, Pageable pageable);
-
- @EntityGraph(type = LOAD, attributePaths = "submission")
- List findCoverageReportsWithSubmissionByIdIn(List ids);
-
- /**
- * Retrieves the latest coverage reports with legal submissions for a specific programming exercise, with pagination support.
- * This method avoids in-memory paging by retrieving the coverage report IDs directly from the database.
- *
- * @param programmingExerciseId the ID of the programming exercise to retrieve the coverage reports for
- * @param pageable the pagination information
- * @return a list of {@code CoverageReport} with legal submissions, or an empty list if no reports are found
- */
- default List getLatestCoverageReportsWithLegalSubmissionsForProgrammingExercise(Long programmingExerciseId, Pageable pageable) {
- List ids = findCoverageReportsByProgrammingExerciseId(programmingExerciseId, pageable).stream().map(CoverageReportAndSubmissionDateDTO::coverageReport)
- .map(DomainObject::getId).toList();
- if (ids.isEmpty()) {
- return Collections.emptyList();
- }
- return findCoverageReportsWithSubmissionByIdIn(ids);
- }
-
- @EntityGraph(type = LOAD, attributePaths = { "submission", "fileReports", "fileReports.testwiseCoverageEntries" })
- List findDistinctCoverageReportsWithEagerRelationshipsByIdIn(List ids);
-
- /**
- * Retrieves the latest coverage reports with legal submissions for a specific programming exercise, including eager loading of file reports and entries, with pagination
- * support.
- * This method avoids in-memory paging by retrieving the coverage report IDs directly from the database.
- *
- * @param programmingExerciseId the ID of the programming exercise to retrieve the coverage reports for
- * @param pageable the pagination information
- * @return a list of distinct {@code CoverageReport} with eager relationships, or an empty list if no reports are found
- */
- default List getLatestCoverageReportsForLegalSubmissionsForProgrammingExerciseWithEagerFileReportsAndEntries(Long programmingExerciseId, Pageable pageable) {
- List ids = findCoverageReportsByProgrammingExerciseId(programmingExerciseId, pageable).stream().map(CoverageReportAndSubmissionDateDTO::coverageReport)
- .map(DomainObject::getId).toList();
- if (ids.isEmpty()) {
- return Collections.emptyList();
- }
- return findDistinctCoverageReportsWithEagerRelationshipsByIdIn(ids);
- }
-
- @Query("""
- SELECT DISTINCT r
- FROM CoverageReport r
- LEFT JOIN FETCH r.fileReports f
- LEFT JOIN FETCH f.testwiseCoverageEntries
- WHERE r.id = :coverageReportId
- """)
- Optional findCoverageReportByIdWithEagerFileReportsAndEntries(@Param("coverageReportId") Long coverageReportId);
-
- default CoverageReport findCoverageReportByIdWithEagerFileReportsAndEntriesElseThrow(Long coverageReportId) {
- return getValueElseThrow(findCoverageReportByIdWithEagerFileReportsAndEntries(coverageReportId), coverageReportId);
- }
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ExerciseHintActivationRepository.java b/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ExerciseHintActivationRepository.java
deleted file mode 100644
index c827a9b3052b..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ExerciseHintActivationRepository.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package de.tum.cit.aet.artemis.programming.repository.hestia;
-
-import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;
-
-import java.util.Optional;
-import java.util.Set;
-
-import org.springframework.context.annotation.Profile;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.query.Param;
-import org.springframework.stereotype.Repository;
-
-import de.tum.cit.aet.artemis.core.repository.base.ArtemisJpaRepository;
-import de.tum.cit.aet.artemis.programming.domain.hestia.ExerciseHintActivation;
-
-@Profile(PROFILE_CORE)
-@Repository
-public interface ExerciseHintActivationRepository extends ArtemisJpaRepository {
-
- @Query("""
- SELECT hintActivation
- FROM ExerciseHintActivation hintActivation
- LEFT JOIN FETCH hintActivation.exerciseHint hint
- LEFT JOIN FETCH hint.solutionEntries
- WHERE hintActivation.exerciseHint.exercise.id = :exerciseId
- AND hintActivation.user.id = :userId
- """)
- Set findByExerciseAndUserWithExerciseHintRelations(@Param("exerciseId") long exerciseId, @Param("userId") long userId);
-
- @Query("""
- SELECT hintActivation
- FROM ExerciseHintActivation hintActivation
- WHERE hintActivation.exerciseHint.id = :exerciseHintId
- AND hintActivation.user.id = :userId
- """)
- Optional findByExerciseHintAndUser(@Param("exerciseHintId") long exerciseHintId, @Param("userId") long userId);
-
- default ExerciseHintActivation findByExerciseHintAndUserElseThrow(long exerciseHintId, long userId) {
- return getValueElseThrow(findByExerciseHintAndUser(exerciseHintId, userId));
- }
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ExerciseHintRepository.java b/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ExerciseHintRepository.java
deleted file mode 100644
index a5f0eb4942ca..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ExerciseHintRepository.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package de.tum.cit.aet.artemis.programming.repository.hestia;
-
-import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;
-
-import java.util.Optional;
-import java.util.Set;
-
-import jakarta.validation.constraints.NotNull;
-
-import org.springframework.context.annotation.Profile;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.query.Param;
-import org.springframework.stereotype.Repository;
-
-import de.tum.cit.aet.artemis.core.exception.EntityNotFoundException;
-import de.tum.cit.aet.artemis.core.repository.base.ArtemisJpaRepository;
-import de.tum.cit.aet.artemis.programming.domain.hestia.ExerciseHint;
-
-/**
- * Spring Data repository for the ExerciseHint entity.
- */
-@Profile(PROFILE_CORE)
-@Repository
-public interface ExerciseHintRepository extends ArtemisJpaRepository {
-
- @Query("""
- SELECT h
- FROM ExerciseHint h
- LEFT JOIN FETCH h.solutionEntries se
- WHERE h.id = :hintId
- """)
- Optional findByIdWithRelations(@Param("hintId") Long hintId);
-
- @NotNull
- default ExerciseHint findByIdWithRelationsElseThrow(long hintId) throws EntityNotFoundException {
- return getValueElseThrow(findByIdWithRelations(hintId), hintId);
- }
-
- Set findByExerciseId(Long exerciseId);
-
- @Query("""
- SELECT h
- FROM ExerciseHint h
- LEFT JOIN FETCH h.solutionEntries se
- WHERE h.exercise.id = :exerciseId
- """)
- Set findByExerciseIdWithRelations(@Param("exerciseId") Long exerciseId);
-
- Set findByTaskId(Long taskId);
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseSolutionEntryRepository.java b/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseSolutionEntryRepository.java
deleted file mode 100644
index 14a03ed49c0a..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseSolutionEntryRepository.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package de.tum.cit.aet.artemis.programming.repository.hestia;
-
-import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;
-
-import java.util.Optional;
-import java.util.Set;
-
-import jakarta.validation.constraints.NotNull;
-
-import org.springframework.context.annotation.Profile;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.query.Param;
-import org.springframework.stereotype.Repository;
-
-import de.tum.cit.aet.artemis.core.exception.EntityNotFoundException;
-import de.tum.cit.aet.artemis.core.repository.base.ArtemisJpaRepository;
-import de.tum.cit.aet.artemis.programming.domain.hestia.ProgrammingExerciseSolutionEntry;
-
-/**
- * Spring Data repository for the ProgrammingExerciseSolutionEntry entity.
- */
-@Profile(PROFILE_CORE)
-@Repository
-public interface ProgrammingExerciseSolutionEntryRepository extends ArtemisJpaRepository {
-
- /**
- * Gets a solution entry with its test cases and programming exercise
- *
- * @param entryId The id of the solution entry
- * @return The solution entry with the given ID if found
- * @throws EntityNotFoundException If no solution entry with the given ID was found
- */
- @NotNull
- default ProgrammingExerciseSolutionEntry findByIdWithTestCaseAndProgrammingExerciseElseThrow(long entryId) throws EntityNotFoundException {
- return getValueElseThrow(findByIdWithTestCaseAndProgrammingExercise(entryId), entryId);
- }
-
- @Query("""
- SELECT se
- FROM ProgrammingExerciseSolutionEntry se
- LEFT JOIN FETCH se.testCase tc
- LEFT JOIN FETCH tc.exercise pe
- WHERE pe.id = :exerciseId
- """)
- Set findByExerciseIdWithTestCases(@Param("exerciseId") long exerciseId);
-
- /**
- * Gets a solution entry with its test cases and programming exercise
- *
- * @param entryId The id of the solution entry
- * @return The solution entry with the given ID
- */
- @Query("""
- SELECT se
- FROM ProgrammingExerciseSolutionEntry se
- LEFT JOIN FETCH se.testCase tc
- LEFT JOIN FETCH tc.exercise pe
- WHERE se.id = :entryId
- """)
- Optional findByIdWithTestCaseAndProgrammingExercise(@Param("entryId") long entryId);
-
- @Query("""
- SELECT h.solutionEntries
- FROM CodeHint h
- WHERE h.id = :codeHintId
- """)
- Set findByCodeHintId(@Param("codeHintId") Long codeHintId);
-
- @Query("""
- SELECT t.solutionEntries
- FROM ProgrammingExerciseTestCase t
- WHERE t.id = :testCaseId
- """)
- Set findByTestCaseId(@Param("testCaseId") Long testCaseId);
-
- @Query("""
- SELECT se
- FROM ProgrammingExerciseSolutionEntry se
- LEFT JOIN FETCH se.codeHint
- WHERE se.testCase.id = :testCaseId
- """)
- Set findByTestCaseIdWithCodeHint(@Param("testCaseId") Long testCaseId);
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/TestwiseCoverageReportEntryRepository.java b/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/TestwiseCoverageReportEntryRepository.java
deleted file mode 100644
index 253adf77f45a..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/TestwiseCoverageReportEntryRepository.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package de.tum.cit.aet.artemis.programming.repository.hestia;
-
-import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;
-
-import org.springframework.context.annotation.Profile;
-import org.springframework.stereotype.Repository;
-
-import de.tum.cit.aet.artemis.core.repository.base.ArtemisJpaRepository;
-import de.tum.cit.aet.artemis.programming.domain.hestia.TestwiseCoverageReportEntry;
-
-/**
- * Spring Data JPA repository for the TestwiseCoverageReportEntry entity.
- */
-@Profile(PROFILE_CORE)
-@Repository
-public interface TestwiseCoverageReportEntryRepository extends ArtemisJpaRepository {
-
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/BuildScriptProviderService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/BuildScriptProviderService.java
index 487c92b3c21d..2d6e9bff2786 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/BuildScriptProviderService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/BuildScriptProviderService.java
@@ -103,13 +103,11 @@ public String getCachedScript(String key) {
* @param projectType the project type for which the template file should be returned. If omitted, a default depending on the language will be used.
* @param staticAnalysis whether the static analysis template should be used
* @param sequentialRuns whether the sequential runs template should be used
- * @param testCoverage whether the test coverage template should be used
* @return the requested template as a bash script
* @throws IOException if the file does not exist
*/
- public String getScriptFor(ProgrammingLanguage programmingLanguage, Optional projectType, Boolean staticAnalysis, Boolean sequentialRuns, Boolean testCoverage)
- throws IOException {
- String templateFileName = buildTemplateName(projectType, staticAnalysis, sequentialRuns, testCoverage, "sh");
+ public String getScriptFor(ProgrammingLanguage programmingLanguage, Optional projectType, Boolean staticAnalysis, Boolean sequentialRuns) throws IOException {
+ String templateFileName = buildTemplateName(projectType, staticAnalysis, sequentialRuns, "sh");
String uniqueKey = programmingLanguage.name().toLowerCase() + "_" + templateFileName;
if (scriptCache.containsKey(uniqueKey)) {
log.debug("Returning cached script for {}", uniqueKey);
@@ -139,7 +137,7 @@ public String getScriptFor(ProgrammingExercise exercise) {
try {
ProgrammingExerciseBuildConfig buildConfig = exercise.getBuildConfig();
return getScriptFor(exercise.getProgrammingLanguage(), Optional.ofNullable(exercise.getProjectType()), exercise.isStaticCodeAnalysisEnabled(),
- buildConfig.hasSequentialTestRuns(), buildConfig.isTestwiseCoverageEnabled());
+ buildConfig.hasSequentialTestRuns());
}
catch (IOException e) {
log.error("Failed to provide build script for programming exercise " + exercise.getId(), e);
@@ -153,11 +151,10 @@ public String getScriptFor(ProgrammingExercise exercise) {
* @param projectType The project type for which the template file should be returned. If omitted, a default depending on the language will be used.
* @param staticAnalysis whether the static analysis template should be used
* @param sequentialRuns whether the sequential runs template should be used
- * @param testCoverage whether the test coverage template should be used
* @param fileExtension the file extension of the template file
* @return The filename of the requested configuration
*/
- public String buildTemplateName(Optional projectType, Boolean staticAnalysis, Boolean sequentialRuns, Boolean testCoverage, String fileExtension) {
+ public String buildTemplateName(Optional projectType, Boolean staticAnalysis, Boolean sequentialRuns, String fileExtension) {
List fileNameComponents = new ArrayList<>();
if (ProjectType.MAVEN_BLACKBOX.equals(projectType.orElse(null))) {
@@ -173,9 +170,6 @@ public String buildTemplateName(Optional projectType, Boolean stati
if (sequentialRuns) {
fileNameComponents.add("sequential");
}
- if (testCoverage) {
- fileNameComponents.add("coverage");
- }
return String.join("_", fileNameComponents) + "." + fileExtension;
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/CommitHistoryService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/CommitHistoryService.java
index 9ee663c55c96..bf4f8496cd93 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/CommitHistoryService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/CommitHistoryService.java
@@ -19,11 +19,10 @@
import org.springframework.stereotype.Service;
import de.tum.cit.aet.artemis.core.service.ProfileService;
+import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseGitDiffEntry;
+import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseGitDiffReport;
import de.tum.cit.aet.artemis.programming.domain.Repository;
import de.tum.cit.aet.artemis.programming.domain.VcsRepositoryUri;
-import de.tum.cit.aet.artemis.programming.domain.hestia.ProgrammingExerciseGitDiffEntry;
-import de.tum.cit.aet.artemis.programming.domain.hestia.ProgrammingExerciseGitDiffReport;
-import de.tum.cit.aet.artemis.programming.web.GitDiffReportParserService;
@Profile(PROFILE_CORE)
@Service
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/GenericBuildScriptGenerationService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/GenericBuildScriptGenerationService.java
index adabad775f23..5d8008d0c833 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/GenericBuildScriptGenerationService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/GenericBuildScriptGenerationService.java
@@ -34,7 +34,7 @@ public String getScript(ProgrammingExercise programmingExercise) {
try {
ProgrammingExerciseBuildConfig buildConfig = programmingExercise.getBuildConfig();
return buildScriptProviderService.getScriptFor(programmingExercise.getProgrammingLanguage(), Optional.ofNullable(programmingExercise.getProjectType()),
- programmingExercise.isStaticCodeAnalysisEnabled(), buildConfig.hasSequentialTestRuns(), buildConfig.isTestwiseCoverageEnabled());
+ programmingExercise.isStaticCodeAnalysisEnabled(), buildConfig.hasSequentialTestRuns());
}
catch (IOException e) {
log.error("Failed to generate build script for programming exercise " + programmingExercise.getId(), e);
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/web/GitDiffReportParserService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/GitDiffReportParserService.java
similarity index 98%
rename from src/main/java/de/tum/cit/aet/artemis/programming/web/GitDiffReportParserService.java
rename to src/main/java/de/tum/cit/aet/artemis/programming/service/GitDiffReportParserService.java
index 37042b8cdb06..f66d85d65544 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/web/GitDiffReportParserService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/GitDiffReportParserService.java
@@ -1,4 +1,4 @@
-package de.tum.cit.aet.artemis.programming.web;
+package de.tum.cit.aet.artemis.programming.service;
import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;
@@ -13,7 +13,7 @@
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
-import de.tum.cit.aet.artemis.programming.domain.hestia.ProgrammingExerciseGitDiffEntry;
+import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseGitDiffEntry;
@Profile(PROFILE_CORE)
@Service
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseExportService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseExportService.java
index 20d98af84bc8..76a140eb2147 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseExportService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseExportService.java
@@ -74,7 +74,6 @@
import de.tum.cit.aet.artemis.programming.repository.AuxiliaryRepositoryRepository;
import de.tum.cit.aet.artemis.programming.repository.BuildPlanRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseRepository;
-import de.tum.cit.aet.artemis.programming.service.hestia.ProgrammingExerciseTaskService;
/**
* Service for exporting programming exercises.
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseFeedbackCreationService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseFeedbackCreationService.java
index d22c13ebe3d8..a75efa7bf1c2 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseFeedbackCreationService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseFeedbackCreationService.java
@@ -37,18 +37,17 @@
import de.tum.cit.aet.artemis.core.config.StaticCodeAnalysisConfigurer;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseTestCase;
+import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseTestCaseType;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage;
import de.tum.cit.aet.artemis.programming.domain.StaticCodeAnalysisCategory;
import de.tum.cit.aet.artemis.programming.domain.StaticCodeAnalysisDefaultCategory;
import de.tum.cit.aet.artemis.programming.domain.StaticCodeAnalysisTool;
-import de.tum.cit.aet.artemis.programming.domain.hestia.ProgrammingExerciseTestCaseType;
-import de.tum.cit.aet.artemis.programming.dto.AbstractBuildResultNotificationDTO;
+import de.tum.cit.aet.artemis.programming.dto.BuildResultNotification;
import de.tum.cit.aet.artemis.programming.dto.StaticCodeAnalysisIssue;
import de.tum.cit.aet.artemis.programming.dto.StaticCodeAnalysisReportDTO;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseTestCaseRepository;
import de.tum.cit.aet.artemis.programming.repository.StaticCodeAnalysisCategoryRepository;
-import de.tum.cit.aet.artemis.programming.service.hestia.ProgrammingExerciseTaskService;
/**
* Service for creating feedback for programming exercises.
@@ -278,7 +277,7 @@ else if (!testMessages.isEmpty()) {
* @param buildResult from which to extract the test cases.
* @param exercise the programming exercise for which the test cases should be extracted from the new result
*/
- public void extractTestCasesFromResultAndBroadcastUpdates(AbstractBuildResultNotificationDTO buildResult, ProgrammingExercise exercise) {
+ public void extractTestCasesFromResultAndBroadcastUpdates(BuildResultNotification buildResult, ProgrammingExercise exercise) {
boolean haveTestCasesChanged = generateTestCasesFromBuildResult(buildResult, exercise);
if (haveTestCasesChanged) {
// Notify the client about the updated testCases
@@ -296,7 +295,7 @@ public void extractTestCasesFromResultAndBroadcastUpdates(AbstractBuildResultNot
* @param exercise programming exercise.
* @return Returns true if the test cases have changed, false if they haven't.
*/
- public boolean generateTestCasesFromBuildResult(AbstractBuildResultNotificationDTO buildResult, ProgrammingExercise exercise) {
+ public boolean generateTestCasesFromBuildResult(BuildResultNotification buildResult, ProgrammingExercise exercise) {
Set existingTestCases = testCaseRepository.findByExerciseId(exercise.getId());
// Do not generate test cases for static code analysis feedback
Set testCasesFromFeedbacks = getTestCasesFromBuildResult(buildResult, exercise);
@@ -375,12 +374,12 @@ public void setTestCaseType(Set testCases, Programm
});
}
- private Set getTestCasesFromBuildResult(AbstractBuildResultNotificationDTO buildResult, ProgrammingExercise exercise) {
+ private Set getTestCasesFromBuildResult(BuildResultNotification buildResult, ProgrammingExercise exercise) {
Visibility defaultVisibility = exercise.getDefaultTestCaseVisibility();
- return buildResult.getBuildJobs().stream().flatMap(job -> Stream.concat(job.getFailedTests().stream(), job.getSuccessfulTests().stream()))
+ return buildResult.jobs().stream().flatMap(job -> Stream.concat(job.failedTests().stream(), job.successfulTests().stream()))
// we use default values for weight, bonus multiplier and bonus points
- .map(testCase -> new ProgrammingExerciseTestCase().testName(testCase.getName()).weight(1.0).bonusMultiplier(1.0).bonusPoints(0.0).exercise(exercise).active(true)
+ .map(testCase -> new ProgrammingExerciseTestCase().testName(testCase.name()).weight(1.0).bonusMultiplier(1.0).bonusPoints(0.0).exercise(exercise).active(true)
.visibility(defaultVisibility))
.collect(Collectors.toSet());
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/hestia/ProgrammingExerciseGitDiffReportService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseGitDiffReportService.java
similarity index 97%
rename from src/main/java/de/tum/cit/aet/artemis/programming/service/hestia/ProgrammingExerciseGitDiffReportService.java
rename to src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseGitDiffReportService.java
index 6950e1216df5..785d200ad349 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/hestia/ProgrammingExerciseGitDiffReportService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseGitDiffReportService.java
@@ -1,4 +1,4 @@
-package de.tum.cit.aet.artemis.programming.service.hestia;
+package de.tum.cit.aet.artemis.programming.service;
import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;
@@ -24,21 +24,19 @@
import de.tum.cit.aet.artemis.core.exception.InternalServerErrorException;
import de.tum.cit.aet.artemis.core.service.FileService;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise;
+import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseGitDiffEntry;
+import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseGitDiffReport;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseParticipation;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingSubmission;
import de.tum.cit.aet.artemis.programming.domain.Repository;
import de.tum.cit.aet.artemis.programming.domain.SolutionProgrammingExerciseParticipation;
import de.tum.cit.aet.artemis.programming.domain.TemplateProgrammingExerciseParticipation;
import de.tum.cit.aet.artemis.programming.domain.VcsRepositoryUri;
-import de.tum.cit.aet.artemis.programming.domain.hestia.ProgrammingExerciseGitDiffEntry;
-import de.tum.cit.aet.artemis.programming.domain.hestia.ProgrammingExerciseGitDiffReport;
+import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseGitDiffReportRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingSubmissionRepository;
import de.tum.cit.aet.artemis.programming.repository.SolutionProgrammingExerciseParticipationRepository;
import de.tum.cit.aet.artemis.programming.repository.TemplateProgrammingExerciseParticipationRepository;
-import de.tum.cit.aet.artemis.programming.repository.hestia.ProgrammingExerciseGitDiffReportRepository;
-import de.tum.cit.aet.artemis.programming.service.GitService;
-import de.tum.cit.aet.artemis.programming.web.GitDiffReportParserService;
/**
* The service handling ProgrammingExerciseGitDiffReport and their ProgrammingExerciseGitDiffEntries.
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseGradingService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseGradingService.java
index 7738b6615b2f..1aff8fca66f0 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseGradingService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseGradingService.java
@@ -61,7 +61,7 @@
import de.tum.cit.aet.artemis.programming.domain.submissionpolicy.LockRepositoryPolicy;
import de.tum.cit.aet.artemis.programming.domain.submissionpolicy.SubmissionPenaltyPolicy;
import de.tum.cit.aet.artemis.programming.domain.submissionpolicy.SubmissionPolicy;
-import de.tum.cit.aet.artemis.programming.dto.AbstractBuildResultNotificationDTO;
+import de.tum.cit.aet.artemis.programming.dto.BuildResultNotification;
import de.tum.cit.aet.artemis.programming.dto.ProgrammingExerciseGradingStatisticsDTO;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseTestCaseRepository;
@@ -218,9 +218,8 @@ public Result processNewProgrammingExerciseResult(@NotNull ProgrammingExercisePa
* @param buildResult The build result received from the CI system.
* @throws IllegalArgumentException Thrown if the result does not belong to the default branch of the exercise.
*/
- private void checkCorrectBranchElseThrow(final ProgrammingExerciseParticipation participation, final AbstractBuildResultNotificationDTO buildResult)
- throws IllegalArgumentException {
- var branchName = buildResult.getBranchNameFromAssignmentRepo();
+ private void checkCorrectBranchElseThrow(final ProgrammingExerciseParticipation participation, final BuildResultNotification buildResult) throws IllegalArgumentException {
+ var branchName = buildResult.assignmentRepoBranchName();
// If the branch is not present, it might be because the assignment repo did not change because only the test repo was changed
if (!ObjectUtils.isEmpty(branchName)) {
String participationDefaultBranch = null;
@@ -243,8 +242,8 @@ private void checkCorrectBranchElseThrow(final ProgrammingExerciseParticipation
*
* @param buildResult The build result received from the CI system.
*/
- private void checkHasCommitHashElseThrow(final AbstractBuildResultNotificationDTO buildResult) {
- if (StringUtils.isEmpty(buildResult.getCommitHash(SubmissionType.MANUAL))) {
+ private void checkHasCommitHashElseThrow(final BuildResultNotification buildResult) {
+ if (StringUtils.isEmpty(buildResult.commitHash(SubmissionType.MANUAL))) {
throw new IllegalArgumentException("The provided result does not specify the assignment commit hash. The result will not get processed.");
}
}
@@ -256,28 +255,28 @@ private void checkHasCommitHashElseThrow(final AbstractBuildResultNotificationDT
* @param buildResult The build result
* @return The submission or empty if no submissions exist
*/
- protected Optional getSubmissionForBuildResult(Long participationId, AbstractBuildResultNotificationDTO buildResult) {
+ protected Optional getSubmissionForBuildResult(Long participationId, BuildResultNotification buildResult) {
var submissions = programmingSubmissionRepository.findAllByParticipationIdWithResults(participationId);
if (submissions.isEmpty()) {
return Optional.empty();
}
return submissions.stream().filter(theSubmission -> {
- var commitHash = buildResult.getCommitHash(theSubmission.getType());
+ var commitHash = buildResult.commitHash(theSubmission.getType());
return !ObjectUtils.isEmpty(commitHash) && commitHash.equals(theSubmission.getCommitHash());
}).max(Comparator.naturalOrder());
}
@NotNull
- protected ProgrammingSubmission createAndSaveFallbackSubmission(ProgrammingExerciseParticipation participation, AbstractBuildResultNotificationDTO buildResult) {
- final var commitHash = buildResult.getCommitHash(SubmissionType.MANUAL);
+ protected ProgrammingSubmission createAndSaveFallbackSubmission(ProgrammingExerciseParticipation participation, BuildResultNotification buildResult) {
+ final var commitHash = buildResult.commitHash(SubmissionType.MANUAL);
if (ObjectUtils.isEmpty(commitHash)) {
log.error("Could not find commit hash for participation {}, build plan {}", participation.getId(), participation.getBuildPlanId());
}
log.warn("Could not find pending ProgrammingSubmission for Commit Hash {} (Participation {}, Build Plan {}). Will create a new one subsequently...", commitHash,
participation.getId(), participation.getBuildPlanId());
// We always take the build run date as the fallback solution
- ZonedDateTime submissionDate = buildResult.getBuildRunDate();
+ ZonedDateTime submissionDate = buildResult.buildRunDate();
if (!ObjectUtils.isEmpty(commitHash)) {
try {
// Try to get the actual date, the push might be 10s - 3min earlier, depending on how long the build takes.
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseImportBasicService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseImportBasicService.java
index 8f5c1b427390..92bddf8f75d4 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseImportBasicService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseImportBasicService.java
@@ -9,6 +9,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
+import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.context.annotation.Profile;
@@ -22,34 +23,24 @@
import de.tum.cit.aet.artemis.programming.domain.AuxiliaryRepository;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseBuildConfig;
+import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseTask;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseTestCase;
import de.tum.cit.aet.artemis.programming.domain.RepositoryType;
import de.tum.cit.aet.artemis.programming.domain.StaticCodeAnalysisCategory;
-import de.tum.cit.aet.artemis.programming.domain.hestia.CodeHint;
-import de.tum.cit.aet.artemis.programming.domain.hestia.ProgrammingExerciseSolutionEntry;
-import de.tum.cit.aet.artemis.programming.domain.hestia.ProgrammingExerciseTask;
import de.tum.cit.aet.artemis.programming.domain.submissionpolicy.SubmissionPolicy;
import de.tum.cit.aet.artemis.programming.repository.AuxiliaryRepositoryRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseBuildConfigRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseRepository;
+import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseTaskRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseTestCaseRepository;
import de.tum.cit.aet.artemis.programming.repository.StaticCodeAnalysisCategoryRepository;
import de.tum.cit.aet.artemis.programming.repository.SubmissionPolicyRepository;
-import de.tum.cit.aet.artemis.programming.repository.hestia.ExerciseHintRepository;
-import de.tum.cit.aet.artemis.programming.repository.hestia.ProgrammingExerciseSolutionEntryRepository;
-import de.tum.cit.aet.artemis.programming.repository.hestia.ProgrammingExerciseTaskRepository;
-import de.tum.cit.aet.artemis.programming.service.hestia.ExerciseHintService;
-import de.tum.cit.aet.artemis.programming.service.hestia.ProgrammingExerciseTaskService;
import de.tum.cit.aet.artemis.programming.service.vcs.VersionControlService;
@Profile(PROFILE_CORE)
@Service
public class ProgrammingExerciseImportBasicService {
- private final ExerciseHintService exerciseHintService;
-
- private final ExerciseHintRepository exerciseHintRepository;
-
private final Optional versionControlService;
private final ProgrammingExerciseParticipationService programmingExerciseParticipationService;
@@ -74,22 +65,17 @@ public class ProgrammingExerciseImportBasicService {
private final ProgrammingExerciseTaskService programmingExerciseTaskService;
- private final ProgrammingExerciseSolutionEntryRepository solutionEntryRepository;
-
private final ChannelService channelService;
private final ExerciseService exerciseService;
- public ProgrammingExerciseImportBasicService(ExerciseHintService exerciseHintService, ExerciseHintRepository exerciseHintRepository,
- Optional versionControlService, ProgrammingExerciseParticipationService programmingExerciseParticipationService,
- ProgrammingExerciseTestCaseRepository programmingExerciseTestCaseRepository, StaticCodeAnalysisCategoryRepository staticCodeAnalysisCategoryRepository,
- ProgrammingExerciseRepository programmingExerciseRepository, ProgrammingExerciseService programmingExerciseService, StaticCodeAnalysisService staticCodeAnalysisService,
- AuxiliaryRepositoryRepository auxiliaryRepositoryRepository, SubmissionPolicyRepository submissionPolicyRepository,
- ProgrammingExerciseTaskRepository programmingExerciseTaskRepository, ProgrammingExerciseTaskService programmingExerciseTaskService,
- ProgrammingExerciseSolutionEntryRepository solutionEntryRepository, ChannelService channelService,
+ public ProgrammingExerciseImportBasicService(Optional versionControlService,
+ ProgrammingExerciseParticipationService programmingExerciseParticipationService, ProgrammingExerciseTestCaseRepository programmingExerciseTestCaseRepository,
+ StaticCodeAnalysisCategoryRepository staticCodeAnalysisCategoryRepository, ProgrammingExerciseRepository programmingExerciseRepository,
+ ProgrammingExerciseService programmingExerciseService, StaticCodeAnalysisService staticCodeAnalysisService, AuxiliaryRepositoryRepository auxiliaryRepositoryRepository,
+ SubmissionPolicyRepository submissionPolicyRepository, ProgrammingExerciseTaskRepository programmingExerciseTaskRepository,
+ ProgrammingExerciseTaskService programmingExerciseTaskService, ChannelService channelService,
ProgrammingExerciseBuildConfigRepository programmingExerciseBuildConfigRepository, ExerciseService exerciseService) {
- this.exerciseHintService = exerciseHintService;
- this.exerciseHintRepository = exerciseHintRepository;
this.versionControlService = versionControlService;
this.programmingExerciseParticipationService = programmingExerciseParticipationService;
this.programmingExerciseTestCaseRepository = programmingExerciseTestCaseRepository;
@@ -101,7 +87,6 @@ public ProgrammingExerciseImportBasicService(ExerciseHintService exerciseHintSer
this.submissionPolicyRepository = submissionPolicyRepository;
this.programmingExerciseTaskRepository = programmingExerciseTaskRepository;
this.programmingExerciseTaskService = programmingExerciseTaskService;
- this.solutionEntryRepository = solutionEntryRepository;
this.channelService = channelService;
this.programmingExerciseBuildConfigRepository = programmingExerciseBuildConfigRepository;
this.exerciseService = exerciseService;
@@ -143,20 +128,16 @@ public ProgrammingExercise importProgrammingExerciseBasis(final ProgrammingExerc
}
// Hints, tasks, test cases and static code analysis categories
- final Map newHintIdByOldId = exerciseHintService.copyExerciseHints(originalProgrammingExercise, newProgrammingExercise);
-
newProgrammingExercise.setBuildConfig(programmingExerciseBuildConfigRepository.save(newProgrammingExercise.getBuildConfig()));
final ProgrammingExercise importedExercise = exerciseService.saveWithCompetencyLinks(newProgrammingExercise, programmingExerciseRepository::save);
final Map newTestCaseIdByOldId = importTestCases(originalProgrammingExercise, importedExercise);
- final Map newTaskIdByOldId = importTasks(originalProgrammingExercise, importedExercise, newTestCaseIdByOldId);
- updateTaskExerciseHintReferences(originalProgrammingExercise, importedExercise, newTaskIdByOldId, newHintIdByOldId);
+ importTasks(originalProgrammingExercise, importedExercise, newTestCaseIdByOldId);
// Set up new exercise submission policy before the solution entries are imported
importSubmissionPolicy(importedExercise);
// Having the submission policy in place prevents errors
- importSolutionEntries(originalProgrammingExercise, importedExercise, newTestCaseIdByOldId, newHintIdByOldId);
// Use the template problem statement (with ids) as a new basis (You cannot edit the problem statement while importing)
// Then replace the old test ids by the newly created ones.
@@ -284,33 +265,62 @@ private Map importTestCases(final ProgrammingExercise templateExerci
}
/**
- * Copies tasks from one exercise to another. Because the tasks from the template exercise references its test cases, the
- * references between tasks and test cases also need to be changed.
+ * Imports tasks from a template exercise to a new exercise. The tasks will get new IDs, thus being saved as a new entity.
+ * The remaining contents stay the same, especially the test cases.
*
- * @param templateExercise The template exercise which tasks should be copied
- * @param targetExercise The new exercise to which all tasks should get copied to
- * @param newTestCaseIdByOldId A map with the old test case id as a key and the new test case id as a value
- * @return A map with the old task id as a key and the new task id as value
+ * @param sourceExercise The template exercise which tasks should get copied
+ * @param targetExercise The new exercise to which all tasks should get copied to
+ * @param testCaseIdMapping A map with the old test case id as a key and the new test case id as a value
*/
- private Map importTasks(final ProgrammingExercise templateExercise, final ProgrammingExercise targetExercise, Map newTestCaseIdByOldId) {
- Map newIdByOldId = new HashMap<>();
- targetExercise.setTasks(templateExercise.getTasks().stream().map(task -> {
- final var copy = new ProgrammingExerciseTask();
-
- // copy everything except for the referenced exercise
- copy.setTaskName(task.getTaskName());
- // change reference to newly imported test cases from the target exercise
- copy.setTestCases(task.getTestCases().stream().map(testCase -> {
- Long oldTestCaseId = testCase.getId();
- Long newTestCaseId = newTestCaseIdByOldId.get(oldTestCaseId);
- return targetExercise.getTestCases().stream().filter(newTestCase -> Objects.equals(newTestCaseId, newTestCase.getId())).findFirst().orElseThrow();
- }).collect(Collectors.toSet()));
- copy.setExercise(targetExercise);
- programmingExerciseTaskRepository.save(copy);
- newIdByOldId.put(task.getId(), copy.getId());
- return copy;
- }).collect(Collectors.toCollection(ArrayList::new)));
- return newIdByOldId;
+ private void importTasks(final ProgrammingExercise sourceExercise, final ProgrammingExercise targetExercise, Map testCaseIdMapping) {
+ // Map the tasks from the template exercise to new tasks in the target exercise
+ List newTasks = sourceExercise.getTasks().stream().map(templateTask -> createTaskCopy(templateTask, targetExercise, testCaseIdMapping)).toList();
+
+ // Set the new tasks to the target exercise
+ targetExercise.setTasks(new ArrayList<>(newTasks));
+ }
+
+ /**
+ * Creates a copy of a task from a template exercise and links it to the target exercise. The test cases of the task
+ * are also copied and linked to the new task.
+ *
+ * @param sourceTask The template task which should be copied
+ * @param targetExercise The new exercise to which the task should be linked
+ * @param testCaseIdMapping A map with the old test case id as a key and the new test case id as a value
+ * @return The new task
+ */
+ private ProgrammingExerciseTask createTaskCopy(ProgrammingExerciseTask sourceTask, ProgrammingExercise targetExercise, Map testCaseIdMapping) {
+ ProgrammingExerciseTask copiedTask = new ProgrammingExerciseTask();
+
+ // Copy task properties
+ copiedTask.setTaskName(sourceTask.getTaskName());
+
+ // Map and set new test cases
+ Set mappedTestCases = sourceTask.getTestCases().stream().map(testCase -> findMappedTestCase(testCase, targetExercise, testCaseIdMapping))
+ .collect(Collectors.toSet());
+ copiedTask.setTestCases(mappedTestCases);
+
+ // Link the task to the target exercise
+ copiedTask.setExercise(targetExercise);
+
+ // Persist the new task
+ programmingExerciseTaskRepository.save(copiedTask);
+ return copiedTask;
+ }
+
+ /**
+ * Finds a test case in the target exercise that corresponds to a test case in the template exercise.
+ *
+ * @param existingTestCase The test case from the template exercise
+ * @param targetExercise The new exercise to which the test case should be linked
+ * @param testCaseIdMapping A map with the old test case id as a key and the new test case id as a value
+ * @return The test case in the target exercise
+ */
+ private ProgrammingExerciseTestCase findMappedTestCase(ProgrammingExerciseTestCase existingTestCase, ProgrammingExercise targetExercise, Map testCaseIdMapping) {
+ Long newTestCaseId = testCaseIdMapping.get(existingTestCase.getId());
+
+ return targetExercise.getTestCases().stream().filter(newTestCase -> Objects.equals(newTestCaseId, newTestCase.getId())).findFirst()
+ .orElseThrow(() -> new IllegalArgumentException("Test case not found for ID: " + newTestCaseId));
}
/**
@@ -380,68 +390,4 @@ else if (newExercise.isCourseExercise() && newExercise.getPlagiarismDetectionCon
newExercise.setPlagiarismDetectionConfig(null);
}
}
-
- /**
- * Updates the newly imported exercise hints to reference the newly imported tasks they belong to.
- *
- * @param templateExercise The template exercise which tasks should be copied
- * @param targetExercise The new exercise to which all tasks should get copied to
- * @param newTaskIdByOldId A map with the old task id as a key and the new task id as a value
- * @param newHintIdByOldId A map with the old hint id as a key and the new hint id as a value
- */
- private void updateTaskExerciseHintReferences(final ProgrammingExercise templateExercise, final ProgrammingExercise targetExercise, Map newTaskIdByOldId,
- Map newHintIdByOldId) {
- templateExercise.getExerciseHints().forEach(templateExerciseHint -> {
- var templateTask = templateExerciseHint.getProgrammingExerciseTask();
- if (templateTask == null) {
- return;
- }
- var targetTask = targetExercise.getTasks().stream().filter(newTask -> Objects.equals(newTask.getId(), newTaskIdByOldId.get(templateTask.getId()))).findAny()
- .orElseThrow();
- var targetExerciseHint = targetExercise.getExerciseHints().stream()
- .filter(newHint -> Objects.equals(newHint.getId(), newHintIdByOldId.get(templateExerciseHint.getId()))).findAny().orElseThrow();
-
- targetExerciseHint.setProgrammingExerciseTask(targetTask);
- exerciseHintRepository.save(targetExerciseHint);
- targetTask.getExerciseHints().add(targetExerciseHint);
- });
- }
-
- /**
- * Copies solution entries from one exercise to another. Because the solution entries from the template exercise
- * references its test cases and code hint, the references between them also need to be changed.
- *
- * @param templateExercise The template exercise which tasks should be copied
- * @param targetExercise The new exercise to which all tasks should get copied to
- * @param newTestCaseIdByOldId A map with the old test case id as a key and the new test case id as a value
- * @param newHintIdByOldId A map with the old hint id as a key and the new hint id as a value
- */
- private void importSolutionEntries(final ProgrammingExercise templateExercise, final ProgrammingExercise targetExercise, Map newTestCaseIdByOldId,
- Map newHintIdByOldId) {
- templateExercise.getTestCases().forEach(testCase -> {
- var newSolutionEntries = solutionEntryRepository.findByTestCaseIdWithCodeHint(testCase.getId()).stream().map(solutionEntry -> {
- Long newTestCaseId = newTestCaseIdByOldId.get(testCase.getId());
- var targetTestCase = targetExercise.getTestCases().stream().filter(newTestCase -> Objects.equals(newTestCaseId, newTestCase.getId())).findFirst().orElseThrow();
-
- CodeHint codeHint = null;
- if (solutionEntry.getCodeHint() != null) {
- Long newHintId = newHintIdByOldId.get(solutionEntry.getCodeHint().getId());
- codeHint = (CodeHint) targetExercise.getExerciseHints().stream().filter(newHint -> Objects.equals(newHintId, newHint.getId())).findFirst().orElseThrow();
- }
- var copy = new ProgrammingExerciseSolutionEntry();
- copy.setCode(solutionEntry.getCode());
- copy.setPreviousCode(solutionEntry.getPreviousCode());
- copy.setLine(solutionEntry.getLine());
- copy.setPreviousLine(solutionEntry.getPreviousLine());
- copy.setTestCase(targetTestCase);
- targetTestCase.getSolutionEntries().add(copy);
- copy.setCodeHint(codeHint);
- if (codeHint != null) {
- codeHint.getSolutionEntries().add(copy);
- }
- return copy;
- }).collect(Collectors.toSet());
- solutionEntryRepository.saveAll(newSolutionEntries);
- });
- }
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseImportService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseImportService.java
index 710837ac4fb4..0c308cc80c0a 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseImportService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseImportService.java
@@ -35,7 +35,6 @@
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseTestCaseRepository;
import de.tum.cit.aet.artemis.programming.service.ci.ContinuousIntegrationService;
import de.tum.cit.aet.artemis.programming.service.ci.ContinuousIntegrationTriggerService;
-import de.tum.cit.aet.artemis.programming.service.hestia.ProgrammingExerciseTaskService;
import de.tum.cit.aet.artemis.programming.service.vcs.VersionControlService;
@Profile(PROFILE_CORE)
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseRepositoryService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseRepositoryService.java
index 43523ec566f1..ffbf6aa37f0a 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseRepositoryService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseRepositoryService.java
@@ -404,8 +404,6 @@ private void setupJVMTestTemplateAndPush(final RepositoryResources resources, fi
final Map sectionsMap = new HashMap<>();
// Keep or delete static code analysis configuration in the build configuration file
sectionsMap.put("static-code-analysis", Boolean.TRUE.equals(programmingExercise.isStaticCodeAnalysisEnabled()));
- // Keep or delete testwise coverage configuration in the build file
- sectionsMap.put("record-testwise-coverage", Boolean.TRUE.equals(programmingExercise.getBuildConfig().isTestwiseCoverageEnabled()));
if (programmingExercise.getBuildConfig().hasSequentialTestRuns()) {
setupTestTemplateSequentialTestRuns(resources, templatePath, projectTemplatePath, projectType, sectionsMap);
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseService.java
index d85af7904c4c..d03c14a5cbc5 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseService.java
@@ -17,7 +17,6 @@
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -26,7 +25,6 @@
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.util.stream.Collectors;
import jakarta.annotation.Nullable;
@@ -70,7 +68,7 @@
import de.tum.cit.aet.artemis.programming.domain.AuxiliaryRepository;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseBuildConfig;
-import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseTestCase;
+import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseTask;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage;
import de.tum.cit.aet.artemis.programming.domain.ProjectType;
import de.tum.cit.aet.artemis.programming.domain.Repository;
@@ -78,23 +76,19 @@
import de.tum.cit.aet.artemis.programming.domain.SolutionProgrammingExerciseParticipation;
import de.tum.cit.aet.artemis.programming.domain.TemplateProgrammingExerciseParticipation;
import de.tum.cit.aet.artemis.programming.domain.VcsRepositoryUri;
-import de.tum.cit.aet.artemis.programming.domain.hestia.ProgrammingExerciseSolutionEntry;
-import de.tum.cit.aet.artemis.programming.domain.hestia.ProgrammingExerciseTask;
+import de.tum.cit.aet.artemis.programming.dto.aeolus.Windfile;
import de.tum.cit.aet.artemis.programming.repository.AuxiliaryRepositoryRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseBuildConfigRepository;
+import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseGitDiffReportRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseStudentParticipationRepository;
+import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseTaskRepository;
import de.tum.cit.aet.artemis.programming.repository.SolutionProgrammingExerciseParticipationRepository;
import de.tum.cit.aet.artemis.programming.repository.TemplateProgrammingExerciseParticipationRepository;
-import de.tum.cit.aet.artemis.programming.repository.hestia.ProgrammingExerciseGitDiffReportRepository;
-import de.tum.cit.aet.artemis.programming.repository.hestia.ProgrammingExerciseSolutionEntryRepository;
-import de.tum.cit.aet.artemis.programming.repository.hestia.ProgrammingExerciseTaskRepository;
import de.tum.cit.aet.artemis.programming.service.aeolus.AeolusTemplateService;
-import de.tum.cit.aet.artemis.programming.service.aeolus.Windfile;
import de.tum.cit.aet.artemis.programming.service.ci.CIPermission;
import de.tum.cit.aet.artemis.programming.service.ci.ContinuousIntegrationService;
import de.tum.cit.aet.artemis.programming.service.ci.ContinuousIntegrationTriggerService;
-import de.tum.cit.aet.artemis.programming.service.hestia.ProgrammingExerciseTaskService;
import de.tum.cit.aet.artemis.programming.service.structureoraclegenerator.OracleGenerator;
import de.tum.cit.aet.artemis.programming.service.vcs.VersionControlService;
@@ -163,8 +157,6 @@ public class ProgrammingExerciseService {
private final ProgrammingExerciseTaskRepository programmingExerciseTaskRepository;
- private final ProgrammingExerciseSolutionEntryRepository programmingExerciseSolutionEntryRepository;
-
private final ProgrammingExerciseTaskService programmingExerciseTaskService;
private final ProgrammingExerciseGitDiffReportRepository programmingExerciseGitDiffReportRepository;
@@ -206,11 +198,11 @@ public ProgrammingExerciseService(ProgrammingExerciseRepository programmingExerc
ParticipationRepository participationRepository, ResultRepository resultRepository, UserRepository userRepository,
GroupNotificationScheduleService groupNotificationScheduleService, InstanceMessageSendService instanceMessageSendService,
AuxiliaryRepositoryRepository auxiliaryRepositoryRepository, ProgrammingExerciseTaskRepository programmingExerciseTaskRepository,
- ProgrammingExerciseSolutionEntryRepository programmingExerciseSolutionEntryRepository, ProgrammingExerciseTaskService programmingExerciseTaskService,
- ProgrammingExerciseGitDiffReportRepository programmingExerciseGitDiffReportRepository, ExerciseSpecificationService exerciseSpecificationService,
- ProgrammingExerciseRepositoryService programmingExerciseRepositoryService, AuxiliaryRepositoryService auxiliaryRepositoryService,
- SubmissionPolicyService submissionPolicyService, Optional programmingLanguageFeatureService, ChannelService channelService,
- ProgrammingSubmissionService programmingSubmissionService, Optional irisSettingsService, Optional aeolusTemplateService,
+ ProgrammingExerciseTaskService programmingExerciseTaskService, ProgrammingExerciseGitDiffReportRepository programmingExerciseGitDiffReportRepository,
+ ExerciseSpecificationService exerciseSpecificationService, ProgrammingExerciseRepositoryService programmingExerciseRepositoryService,
+ AuxiliaryRepositoryService auxiliaryRepositoryService, SubmissionPolicyService submissionPolicyService,
+ Optional programmingLanguageFeatureService, ChannelService channelService, ProgrammingSubmissionService programmingSubmissionService,
+ Optional irisSettingsService, Optional aeolusTemplateService,
Optional buildScriptGenerationService,
ProgrammingExerciseStudentParticipationRepository programmingExerciseStudentParticipationRepository, ProfileService profileService, ExerciseService exerciseService,
ProgrammingExerciseBuildConfigRepository programmingExerciseBuildConfigRepository, CompetencyProgressApi competencyProgressApi,
@@ -230,7 +222,6 @@ public ProgrammingExerciseService(ProgrammingExerciseRepository programmingExerc
this.instanceMessageSendService = instanceMessageSendService;
this.auxiliaryRepositoryRepository = auxiliaryRepositoryRepository;
this.programmingExerciseTaskRepository = programmingExerciseTaskRepository;
- this.programmingExerciseSolutionEntryRepository = programmingExerciseSolutionEntryRepository;
this.programmingExerciseTaskService = programmingExerciseTaskService;
this.programmingExerciseGitDiffReportRepository = programmingExerciseGitDiffReportRepository;
this.exerciseSpecificationService = exerciseSpecificationService;
@@ -405,11 +396,6 @@ public void validateNewProgrammingExerciseSettings(ProgrammingExercise programmi
throw new BadRequestAlertException("Checkout solution repository is not supported for this programming language", "Exercise", "checkoutSolutionRepositoryNotSupported");
}
- // Check if testwise coverage analysis is enabled
- if (Boolean.TRUE.equals(buildConfig.isTestwiseCoverageEnabled()) && !programmingLanguageFeature.testwiseCoverageAnalysisSupported()) {
- throw new BadRequestAlertException("Testwise coverage analysis is not supported for this language", "Exercise", "testwiseCoverageAnalysisNotSupported");
- }
-
programmingExerciseRepository.validateCourseSettings(programmingExercise, course);
validateStaticCodeAnalysisSettings(programmingExercise);
@@ -1033,12 +1019,9 @@ public boolean preCheckProjectExistsOnVCSOrCI(ProgrammingExercise programmingExe
*
* @param exerciseId of the exercise
*/
- public void deleteTasksWithSolutionEntries(Long exerciseId) {
- List tasks = programmingExerciseTaskRepository.findByExerciseIdWithTestCaseAndSolutionEntriesElseThrow(exerciseId);
- Set solutionEntries = tasks.stream().map(ProgrammingExerciseTask::getTestCases).flatMap(Collection::stream)
- .map(ProgrammingExerciseTestCase::getSolutionEntries).flatMap(Collection::stream).collect(Collectors.toSet());
+ public void deleteTasks(Long exerciseId) {
+ List tasks = programmingExerciseTaskRepository.findByExerciseIdWithTestCaseElseThrow(exerciseId);
programmingExerciseTaskRepository.deleteAll(tasks);
- programmingExerciseSolutionEntryRepository.deleteAll(solutionEntries);
}
private void resetAllStudentBuildPlanIdsForExercise(ProgrammingExercise programmingExercise) {
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/hestia/ProgrammingExerciseTaskService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseTaskService.java
similarity index 91%
rename from src/main/java/de/tum/cit/aet/artemis/programming/service/hestia/ProgrammingExerciseTaskService.java
rename to src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseTaskService.java
index 0b1a14be8646..3ec052802f83 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/hestia/ProgrammingExerciseTaskService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseTaskService.java
@@ -1,4 +1,4 @@
-package de.tum.cit.aet.artemis.programming.service.hestia;
+package de.tum.cit.aet.artemis.programming.service;
import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;
@@ -20,11 +20,10 @@
import org.springframework.stereotype.Service;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise;
+import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseTask;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseTestCase;
-import de.tum.cit.aet.artemis.programming.domain.hestia.ProgrammingExerciseTask;
+import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseTaskRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseTestCaseRepository;
-import de.tum.cit.aet.artemis.programming.repository.hestia.ExerciseHintRepository;
-import de.tum.cit.aet.artemis.programming.repository.hestia.ProgrammingExerciseTaskRepository;
@Profile(PROFILE_CORE)
@Service
@@ -34,8 +33,6 @@ public class ProgrammingExerciseTaskService {
private final ProgrammingExerciseTestCaseRepository programmingExerciseTestCaseRepository;
- private final ExerciseHintRepository exerciseHintRepository;
-
/**
* Pattern that is used to extract the tasks (capturing group {@code name}) and test case names (capturing groups {@code tests}) from the problem statement.
* Example: "[task][Implement BubbleSort](testBubbleSort,testBubbleSortHidden)". Following groups are extracted by the capturing groups:
@@ -85,21 +82,18 @@ public class ProgrammingExerciseTaskService {
private static final Pattern TESTID_PATTERN = Pattern.compile(TESTID_START + "(\\d+)" + TESTID_END);
public ProgrammingExerciseTaskService(ProgrammingExerciseTaskRepository programmingExerciseTaskRepository,
- ProgrammingExerciseTestCaseRepository programmingExerciseTestCaseRepository, ExerciseHintRepository exerciseHintRepository) {
+ ProgrammingExerciseTestCaseRepository programmingExerciseTestCaseRepository) {
this.programmingExerciseTaskRepository = programmingExerciseTaskRepository;
this.programmingExerciseTestCaseRepository = programmingExerciseTestCaseRepository;
- this.exerciseHintRepository = exerciseHintRepository;
}
/**
- * Deletes a ProgrammingExerciseTask together with its CodeHints
+ * Deletes a ProgrammingExerciseTask
* This has to be manually done, as there is no orphanRemoval between the two entities
*
* @param task The task to delete
*/
public void delete(ProgrammingExerciseTask task) {
- var exerciseHints = exerciseHintRepository.findByTaskId(task.getId());
- exerciseHintRepository.deleteAll(exerciseHints);
programmingExerciseTaskRepository.delete(task);
}
@@ -109,14 +103,13 @@ public void delete(ProgrammingExerciseTask task) {
* If there is already a task with the same test cases as a new one, but with a different name the existing one will be renamed.
*
* @param exercise The programming exercise to extract the tasks from
- * @return The current tasks of the exercise
*/
- public Set updateTasksFromProblemStatement(ProgrammingExercise exercise) {
+ public void updateTasksFromProblemStatement(ProgrammingExercise exercise) {
var previousTasks = programmingExerciseTaskRepository.findByExerciseIdWithTestCases(exercise.getId());
var extractedTasks = new HashSet<>(extractTasks(exercise));
// No changes
if (previousTasks.equals(extractedTasks)) {
- return previousTasks;
+ return;
}
// Add all tasks that did not change
var tasksToBeSaved = new HashSet<>(previousTasks);
@@ -151,24 +144,7 @@ public Set updateTasksFromProblemStatement(ProgrammingE
for (ProgrammingExerciseTask task : tasksToBeSaved) {
task.setExercise(exercise);
}
- return new HashSet<>(programmingExerciseTaskRepository.saveAll(tasksToBeSaved));
- }
-
- /**
- * Gets the tasks of a programming exercise sorted by their order in the problem statement
- * TODO: Replace this with an @OrderColumn on tasks in ProgrammingExercise
- *
- * @param exercise The programming exercise
- * @return The sorted tasks
- */
- public List getSortedTasks(ProgrammingExercise exercise) {
- var unsortedTasks = programmingExerciseTaskRepository.findByExerciseIdWithTestCases(exercise.getId());
- var sortedExtractedTasks = extractTasks(exercise);
- return sortedExtractedTasks.stream()
- .map(extractedTask -> unsortedTasks.stream()
- .filter(task -> task.getTaskName().equals(extractedTask.getTaskName()) && task.getTestCases().equals(extractedTask.getTestCases())).findFirst()
- .orElse(null))
- .distinct().filter(Objects::nonNull).toList();
+ programmingExerciseTaskRepository.saveAll(tasksToBeSaved);
}
/**
@@ -178,7 +154,7 @@ public List getSortedTasks(ProgrammingExercise exercise
* @return Set of all tasks and its test cases
*/
public Set getTasksWithoutInactiveTestCases(long exerciseId) {
- return programmingExerciseTaskRepository.findByExerciseIdWithTestCaseAndSolutionEntriesElseThrow(exerciseId).stream()
+ return programmingExerciseTaskRepository.findByExerciseIdWithTestCaseElseThrow(exerciseId).stream()
.peek(task -> task.getTestCases().removeIf(Predicate.not(ProgrammingExerciseTestCase::isActive))).collect(Collectors.toSet());
}
@@ -187,10 +163,10 @@ public Set getTasksWithoutInactiveTestCases(long exerci
* Additionally, adds a new task for all test cases with no manually assigned task and adds all tests to that task
*
* @param exerciseId of the programming exercise
- * @return Set of all tasks including one for not manually assigned tests
+ * @return List of all tasks including one for not manually assigned tests
*/
public List getTasksWithUnassignedTestCases(long exerciseId) {
- List tasks = programmingExerciseTaskRepository.findByExerciseIdWithTestCaseAndSolutionEntriesElseThrow(exerciseId);
+ List tasks = programmingExerciseTaskRepository.findByExerciseIdWithTestCaseElseThrow(exerciseId);
Set testsWithTasks = tasks.stream().flatMap(task -> task.getTestCases().stream()).collect(Collectors.toSet());
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseTestCaseService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseTestCaseService.java
index f3770b417e5b..f06a901b8479 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseTestCaseService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseTestCaseService.java
@@ -27,7 +27,6 @@
import de.tum.cit.aet.artemis.programming.dto.ProgrammingExerciseTestCaseDTO;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseTestCaseRepository;
-import de.tum.cit.aet.artemis.programming.service.hestia.ProgrammingExerciseTaskService;
@Profile(PROFILE_CORE)
@Service
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingLanguageFeature.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingLanguageFeature.java
index 88bee465e155..df07a8f6d5b3 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingLanguageFeature.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingLanguageFeature.java
@@ -13,6 +13,5 @@
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public record ProgrammingLanguageFeature(ProgrammingLanguage programmingLanguage, boolean sequentialTestRuns, boolean staticCodeAnalysis, boolean plagiarismCheckSupported,
- boolean packageNameRequired, boolean checkoutSolutionRepositoryAllowed, List projectTypes, boolean testwiseCoverageAnalysisSupported,
- boolean auxiliaryRepositoriesSupported) {
+ boolean packageNameRequired, boolean checkoutSolutionRepositoryAllowed, List projectTypes, boolean auxiliaryRepositoriesSupported) {
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingSubmissionService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingSubmissionService.java
index 9de4485f16b2..e1ae83935eec 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingSubmissionService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingSubmissionService.java
@@ -67,7 +67,6 @@
import de.tum.cit.aet.artemis.programming.repository.ProgrammingSubmissionRepository;
import de.tum.cit.aet.artemis.programming.repository.SubmissionPolicyRepository;
import de.tum.cit.aet.artemis.programming.service.ci.ContinuousIntegrationTriggerService;
-import de.tum.cit.aet.artemis.programming.service.hestia.ProgrammingExerciseGitDiffReportService;
import de.tum.cit.aet.artemis.programming.service.vcs.VersionControlService;
// TODO: this class has too many dependencies to other services. We should reduce this
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/Action.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/Action.java
deleted file mode 100644
index be22f81ddad9..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/Action.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package de.tum.cit.aet.artemis.programming.service.aeolus;
-
-import java.util.List;
-import java.util.Map;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonInclude;
-
-/**
- * Base class for the actions that can be defined in a {@link Windfile}
- */
-// TODO: remove and convert subclasses into Records
-@JsonIgnoreProperties(ignoreUnknown = true)
-@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public abstract class Action {
-
- private String name;
-
- private Map parameters;
-
- private Map environment;
-
- private List results;
-
- private String workdir;
-
- private boolean runAlways;
-
- private String platform;
-
- public Map getParameters() {
- return parameters;
- }
-
- public void setParameters(Map parameters) {
- this.parameters = parameters;
- }
-
- public Map getEnvironment() {
- return environment;
- }
-
- public void setEnvironment(Map environment) {
- this.environment = environment;
- }
-
- public boolean isRunAlways() {
- return runAlways;
- }
-
- public void setRunAlways(boolean runAlways) {
- this.runAlways = runAlways;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public List getResults() {
- return results;
- }
-
- public void setResults(List results) {
- this.results = results;
- }
-
- public String getWorkdir() {
- return workdir;
- }
-
- public void setWorkdir(String workdir) {
- this.workdir = workdir;
- }
-
- public String getPlatform() {
- return platform;
- }
-
- public void setPlatform(String platform) {
- this.platform = platform;
- }
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/ActionDeserializer.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/ActionDeserializer.java
index 65d42487e398..32463ba0d841 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/ActionDeserializer.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/ActionDeserializer.java
@@ -8,6 +8,10 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
+import de.tum.cit.aet.artemis.programming.dto.aeolus.Action;
+import de.tum.cit.aet.artemis.programming.dto.aeolus.PlatformAction;
+import de.tum.cit.aet.artemis.programming.dto.aeolus.ScriptAction;
+
/**
* Deserializer for {@link Action} that determines the type of the action based on the content of the JSON.
*/
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/AeolusBuildPlanService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/AeolusBuildPlanService.java
index 9cb410de37fa..9dd35b363709 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/AeolusBuildPlanService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/AeolusBuildPlanService.java
@@ -35,6 +35,8 @@
import de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage;
import de.tum.cit.aet.artemis.programming.domain.VcsRepositoryUri;
import de.tum.cit.aet.artemis.programming.dto.AeolusGenerationResponseDTO;
+import de.tum.cit.aet.artemis.programming.dto.aeolus.AeolusRepository;
+import de.tum.cit.aet.artemis.programming.dto.aeolus.Windfile;
import de.tum.cit.aet.artemis.programming.service.InternalUrlService;
import de.tum.cit.aet.artemis.programming.service.ci.ContinuousIntegrationService;
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/AeolusBuildScriptGenerationService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/AeolusBuildScriptGenerationService.java
index 8830adb96389..57141ab1a84a 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/AeolusBuildScriptGenerationService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/AeolusBuildScriptGenerationService.java
@@ -10,6 +10,8 @@
import de.tum.cit.aet.artemis.core.service.ProfileService;
import de.tum.cit.aet.artemis.programming.domain.AeolusTarget;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise;
+import de.tum.cit.aet.artemis.programming.dto.aeolus.Windfile;
+import de.tum.cit.aet.artemis.programming.dto.aeolus.WindfileMetadata;
import de.tum.cit.aet.artemis.programming.service.BuildScriptGenerationService;
import de.tum.cit.aet.artemis.programming.service.BuildScriptProviderService;
@@ -52,12 +54,12 @@ public String getScript(ProgrammingExercise programmingExercise) throws JsonProc
windfile = aeolusTemplateService.getDefaultWindfileFor(programmingExercise);
}
if (windfile != null) {
- WindfileMetadata oldMetadata = windfile.getMetadata();
+ WindfileMetadata oldMetadata = windfile.metadata();
// Creating a new instance of WindfileMetadata with placeholder values for id, name, and description,
// and copying the rest of the fields from oldMetadata
WindfileMetadata updatedMetadata = new WindfileMetadata("not-used", "not-used", "not-used", oldMetadata.author(), oldMetadata.gitCredentials(), oldMetadata.docker(),
oldMetadata.resultHook(), oldMetadata.resultHookCredentials());
- windfile.setMetadata(updatedMetadata);
+ windfile = new Windfile(windfile, updatedMetadata);
return aeolusBuildPlanService.generateBuildScript(windfile, AeolusTarget.CLI);
}
return null;
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/AeolusTemplateService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/AeolusTemplateService.java
index 64321ad3b61d..f2e51ab78496 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/AeolusTemplateService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/AeolusTemplateService.java
@@ -26,6 +26,10 @@
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseBuildConfig;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage;
import de.tum.cit.aet.artemis.programming.domain.ProjectType;
+import de.tum.cit.aet.artemis.programming.dto.aeolus.Action;
+import de.tum.cit.aet.artemis.programming.dto.aeolus.DockerConfig;
+import de.tum.cit.aet.artemis.programming.dto.aeolus.Windfile;
+import de.tum.cit.aet.artemis.programming.dto.aeolus.WindfileMetadata;
import de.tum.cit.aet.artemis.programming.service.BuildScriptProviderService;
import de.tum.cit.aet.artemis.programming.web.localci.AeolusTemplateResource;
@@ -84,7 +88,7 @@ public void cacheOnBoot() {
script = buildScriptProviderService.replacePlaceholders(script, null, null, null);
}
Windfile windfile = readWindfile(script);
- this.addInstanceVariablesToWindfile(windfile, ProgrammingLanguage.valueOf(directory.toUpperCase()), optionalProjectType);
+ windfile = addInstanceVariablesToWindfile(windfile, ProgrammingLanguage.valueOf(directory.toUpperCase()), optionalProjectType);
templateCache.put(uniqueKey, windfile);
}
catch (IOException | IllegalArgumentException e) {
@@ -127,17 +131,15 @@ private static Windfile readWindfile(String yaml) throws IOException {
* @param projectType the project type for which the template file should be returned. If omitted, a default depending on the language will be used.
* @param staticAnalysis whether the static analysis template should be used
* @param sequentialRuns whether the sequential runs template should be used
- * @param testCoverage whether the test coverage template should be used
* @return the requested template as a {@link Windfile} object
* @throws IOException if the file does not exist
*/
- public Windfile getWindfileFor(ProgrammingLanguage programmingLanguage, Optional projectType, Boolean staticAnalysis, Boolean sequentialRuns, Boolean testCoverage)
- throws IOException {
+ public Windfile getWindfileFor(ProgrammingLanguage programmingLanguage, Optional projectType, Boolean staticAnalysis, Boolean sequentialRuns) throws IOException {
if (programmingLanguage.equals(ProgrammingLanguage.JAVA) && projectType.isEmpty()) {
// to be backwards compatible, we assume that java exercises without project type are plain maven projects
projectType = Optional.of(ProjectType.PLAIN_MAVEN);
}
- String templateFileName = buildScriptProviderService.buildTemplateName(projectType, staticAnalysis, sequentialRuns, testCoverage, "yaml");
+ String templateFileName = buildScriptProviderService.buildTemplateName(projectType, staticAnalysis, sequentialRuns, "yaml");
String uniqueKey = programmingLanguage.name().toLowerCase() + "_" + templateFileName;
if (templateCache.containsKey(uniqueKey)) {
return templateCache.get(uniqueKey);
@@ -151,7 +153,7 @@ public Windfile getWindfileFor(ProgrammingLanguage programmingLanguage, Optional
scriptCache = buildScriptProviderService.replacePlaceholders(scriptCache, null, null, null);
}
Windfile windfile = readWindfile(scriptCache);
- this.addInstanceVariablesToWindfile(windfile, programmingLanguage, projectType);
+ windfile = addInstanceVariablesToWindfile(windfile, programmingLanguage, projectType);
templateCache.put(uniqueKey, windfile);
return windfile;
}
@@ -184,7 +186,7 @@ public Windfile getDefaultWindfileFor(ProgrammingExercise exercise) {
try {
ProgrammingExerciseBuildConfig buildConfig = exercise.getBuildConfig();
return getWindfileFor(exercise.getProgrammingLanguage(), Optional.ofNullable(exercise.getProjectType()), exercise.isStaticCodeAnalysisEnabled(),
- buildConfig.hasSequentialTestRuns(), buildConfig.isTestwiseCoverageEnabled());
+ buildConfig.hasSequentialTestRuns());
}
catch (IOException e) {
log.info("No windfile for the settings of exercise {}", exercise.getId(), e);
@@ -202,23 +204,24 @@ public Windfile getDefaultWindfileFor(ProgrammingExercise exercise) {
* @param windfile the Windfile template to be updated with Docker configuration
* @param language the programming language used, which determines the Docker image and flags
* @param projectType an optional specifying the project type; influences the Docker configuration
+ * @return the updated Windfile instance with Docker configuration
*/
- private void addInstanceVariablesToWindfile(Windfile windfile, ProgrammingLanguage language, Optional projectType) {
+ private Windfile addInstanceVariablesToWindfile(Windfile windfile, ProgrammingLanguage language, Optional projectType) {
- WindfileMetadata metadata = windfile.getMetadata();
+ WindfileMetadata metadata = windfile.metadata();
if (metadata == null) {
metadata = new WindfileMetadata();
}
if (projectType.isPresent() && ProjectType.XCODE.equals(projectType.get())) {
// xcode does not support docker
metadata = new WindfileMetadata();
- windfile.setMetadata(metadata);
- return;
}
- String image = programmingLanguageConfiguration.getImage(language, projectType);
- DockerConfig dockerConfig = new DockerConfig(image, null, null, programmingLanguageConfiguration.getDefaultDockerFlags());
- metadata = new WindfileMetadata(metadata.name(), metadata.id(), metadata.description(), metadata.author(), metadata.gitCredentials(), dockerConfig, metadata.resultHook(),
- metadata.resultHookCredentials());
- windfile.setMetadata(metadata);
+ else {
+ String image = programmingLanguageConfiguration.getImage(language, projectType);
+ DockerConfig dockerConfig = new DockerConfig(image, null, null, programmingLanguageConfiguration.getDefaultDockerFlags());
+ metadata = new WindfileMetadata(metadata.name(), metadata.id(), metadata.description(), metadata.author(), metadata.gitCredentials(), dockerConfig,
+ metadata.resultHook(), metadata.resultHookCredentials());
+ }
+ return new Windfile(windfile, metadata);
}
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/PlatformAction.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/PlatformAction.java
deleted file mode 100644
index 5c161ffe798b..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/PlatformAction.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package de.tum.cit.aet.artemis.programming.service.aeolus;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonInclude;
-
-/**
- * Represents a CI action that is intended to run only on a specific target, can be used in a {@link Windfile}.
- */
-// TODO: convert into Record
-@JsonIgnoreProperties(ignoreUnknown = true)
-@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public class PlatformAction extends Action {
-
- private String kind;
-
- private String type;
-
- public String getKind() {
- return kind;
- }
-
- public void setKind(String kind) {
- this.kind = kind;
- }
-
- public String getType() {
- return type;
- }
-
- public void setType(String type) {
- this.type = type;
- }
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/Windfile.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/Windfile.java
deleted file mode 100644
index a9f2382591d4..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/aeolus/Windfile.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package de.tum.cit.aet.artemis.programming.service.aeolus;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.module.SimpleModule;
-
-/**
- * Represents a windfile, the definition file for an aeolus build plan that
- * can then be used to generate a Jenkinsfile.
- */
-// TODO convert into Record
-@JsonIgnoreProperties(ignoreUnknown = true)
-@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public class Windfile {
-
- private static final ObjectMapper mapper = new ObjectMapper();
-
- private String api;
-
- private WindfileMetadata metadata;
-
- private List actions = new ArrayList<>();
-
- private Map repositories = new HashMap<>();
-
- public String getApi() {
- return api;
- }
-
- public void setApi(String api) {
- this.api = api;
- }
-
- public WindfileMetadata getMetadata() {
- return metadata;
- }
-
- public void setMetadata(WindfileMetadata metadata) {
- this.metadata = metadata;
- }
-
- public List getActions() {
- return actions;
- }
-
- public void setActions(List actions) {
- this.actions = actions;
- }
-
- /**
- * Gets the script actions of a windfile.
- *
- * @return the script actions of a windfile.
- */
- public List getScriptActions() {
- List scriptActions = new ArrayList<>();
- for (Action action : actions) {
- if (action instanceof ScriptAction) {
- scriptActions.add((ScriptAction) action);
- }
- }
- return scriptActions;
- }
-
- public void setRepositories(Map repositories) {
- this.repositories = repositories;
- }
-
- public Map getRepositories() {
- return repositories;
- }
-
- /**
- * Sets the pre-processing metadata for the windfile.
- *
- * @param id the id of the windfile.
- * @param name the name of the windfile.
- * @param gitCredentials the git credentials of the windfile.
- * @param resultHook the result hook of the windfile.
- * @param description the description of the windfile.
- * @param repositories the repositories of the windfile.
- * @param resultHookCredentials the credentials for the result hook of the windfile.
- */
- public void setPreProcessingMetadata(String id, String name, String gitCredentials, String resultHook, String description, Map repositories,
- String resultHookCredentials) {
- this.setMetadata(new WindfileMetadata(name, id, description, null, gitCredentials, null, resultHook, resultHookCredentials));
- this.setRepositories(repositories);
- }
-
- /**
- * Deserializes a windfile from a json string.
- *
- * @param json the json string to deserialize.
- * @return the deserialized windfile.
- * @throws JsonProcessingException if the json string is not valid.
- */
- public static Windfile deserialize(String json) throws JsonProcessingException {
- SimpleModule module = new SimpleModule();
- module.addDeserializer(Action.class, new ActionDeserializer());
- mapper.registerModule(module);
- return mapper.readValue(json, Windfile.class);
- }
-
- /**
- * Collects the results of all actions of a windfile.
- *
- * @return the results of all actions of this windfile
- */
- public List getResults() {
- List results = new ArrayList<>();
- for (Action action : actions.stream().filter(action -> action.getResults() != null && !action.getResults().isEmpty()).toList()) {
- results.addAll(action.getResults());
- }
- return results;
- }
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/AbstractContinuousIntegrationResultService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/AbstractContinuousIntegrationResultService.java
index 238d4ffca0fc..2f540cd869b7 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/AbstractContinuousIntegrationResultService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/AbstractContinuousIntegrationResultService.java
@@ -11,13 +11,12 @@
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseParticipation;
import de.tum.cit.aet.artemis.programming.domain.build.BuildLogEntry;
-import de.tum.cit.aet.artemis.programming.dto.AbstractBuildResultNotificationDTO;
-import de.tum.cit.aet.artemis.programming.dto.BuildJobDTOInterface;
+import de.tum.cit.aet.artemis.programming.dto.BuildJobInterface;
+import de.tum.cit.aet.artemis.programming.dto.BuildResultNotification;
import de.tum.cit.aet.artemis.programming.repository.BuildLogStatisticsEntryRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseBuildConfigRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseTestCaseRepository;
import de.tum.cit.aet.artemis.programming.service.ProgrammingExerciseFeedbackCreationService;
-import de.tum.cit.aet.artemis.programming.service.hestia.TestwiseCoverageService;
public abstract class AbstractContinuousIntegrationResultService implements ContinuousIntegrationResultService {
@@ -25,32 +24,29 @@ public abstract class AbstractContinuousIntegrationResultService implements Cont
protected final BuildLogStatisticsEntryRepository buildLogStatisticsEntryRepository;
- protected final TestwiseCoverageService testwiseCoverageService;
-
protected final ProgrammingExerciseFeedbackCreationService feedbackCreationService;
protected final ProgrammingExerciseBuildConfigRepository programmingExerciseBuildConfigRepository;
protected AbstractContinuousIntegrationResultService(ProgrammingExerciseTestCaseRepository testCaseRepository,
- BuildLogStatisticsEntryRepository buildLogStatisticsEntryRepository, TestwiseCoverageService testwiseCoverageService,
- ProgrammingExerciseFeedbackCreationService feedbackCreationService, ProgrammingExerciseBuildConfigRepository programmingExerciseBuildConfigRepository) {
+ BuildLogStatisticsEntryRepository buildLogStatisticsEntryRepository, ProgrammingExerciseFeedbackCreationService feedbackCreationService,
+ ProgrammingExerciseBuildConfigRepository programmingExerciseBuildConfigRepository) {
this.testCaseRepository = testCaseRepository;
this.buildLogStatisticsEntryRepository = buildLogStatisticsEntryRepository;
- this.testwiseCoverageService = testwiseCoverageService;
this.feedbackCreationService = feedbackCreationService;
this.programmingExerciseBuildConfigRepository = programmingExerciseBuildConfigRepository;
}
@Override
- public Result createResultFromBuildResult(AbstractBuildResultNotificationDTO buildResult, ProgrammingExerciseParticipation participation) {
+ public Result createResultFromBuildResult(BuildResultNotification buildResult, ProgrammingExerciseParticipation participation) {
ProgrammingExercise exercise = participation.getProgrammingExercise();
final var result = new Result();
result.setAssessmentType(AssessmentType.AUTOMATIC);
result.setSuccessful(buildResult.isBuildSuccessful());
- result.setCompletionDate(buildResult.getBuildRunDate());
+ result.setCompletionDate(buildResult.buildRunDate());
// this only sets the score to a temporary value, the real score is calculated in the grading service
- result.setScore(buildResult.getBuildScore(), exercise.getCourseViaExerciseGroupOrCourseMember());
+ result.setScore(buildResult.buildScore(), exercise.getCourseViaExerciseGroupOrCourseMember());
result.setParticipation((Participation) participation);
addFeedbackToResult(result, buildResult);
@@ -63,8 +59,8 @@ public Result createResultFromBuildResult(AbstractBuildResultNotificationDTO bui
* @param result the result for which the feedback should be added
* @param buildResult The build result
*/
- private void addFeedbackToResult(Result result, AbstractBuildResultNotificationDTO buildResult) {
- final var jobs = buildResult.getBuildJobs();
+ private void addFeedbackToResult(Result result, BuildResultNotification buildResult) {
+ final var jobs = buildResult.jobs();
final var programmingExercise = (ProgrammingExercise) result.getParticipation().getExercise();
// 1) add feedback for failed and passed test cases
@@ -72,32 +68,28 @@ private void addFeedbackToResult(Result result, AbstractBuildResultNotificationD
// 2) process static code analysis feedback
addStaticCodeAnalysisFeedbackToResult(result, buildResult, programmingExercise);
-
- // 3) process testwise coverage analysis report
- addTestwiseCoverageReportToResult(result, buildResult, programmingExercise);
}
- private void addTestCaseFeedbacksToResult(Result result, List extends BuildJobDTOInterface> jobs, ProgrammingExercise programmingExercise) {
+ private void addTestCaseFeedbacksToResult(Result result, List extends BuildJobInterface> jobs, ProgrammingExercise programmingExercise) {
var activeTestCases = testCaseRepository.findByExerciseIdAndActive(programmingExercise.getId(), true);
- for (final var job : jobs) {
- for (final var failedTest : job.getFailedTests()) {
- result.addFeedback(
- feedbackCreationService.createFeedbackFromTestCase(failedTest.getName(), failedTest.getTestMessages(), false, programmingExercise, activeTestCases));
- }
- result.setTestCaseCount(result.getTestCaseCount() + job.getFailedTests().size());
+ jobs.forEach(job -> {
+ job.failedTests().forEach(failedTest -> {
+ result.addFeedback(feedbackCreationService.createFeedbackFromTestCase(failedTest.name(), failedTest.testMessages(), false, programmingExercise, activeTestCases));
+ });
+ result.setTestCaseCount(result.getTestCaseCount() + job.failedTests().size());
- for (final var successfulTest : job.getSuccessfulTests()) {
+ for (final var successfulTest : job.successfulTests()) {
result.addFeedback(
- feedbackCreationService.createFeedbackFromTestCase(successfulTest.getName(), successfulTest.getTestMessages(), true, programmingExercise, activeTestCases));
+ feedbackCreationService.createFeedbackFromTestCase(successfulTest.name(), successfulTest.testMessages(), true, programmingExercise, activeTestCases));
}
- result.setTestCaseCount(result.getTestCaseCount() + job.getSuccessfulTests().size());
- result.setPassedTestCaseCount(result.getPassedTestCaseCount() + job.getSuccessfulTests().size());
- }
+ result.setTestCaseCount(result.getTestCaseCount() + job.successfulTests().size());
+ result.setPassedTestCaseCount(result.getPassedTestCaseCount() + job.successfulTests().size());
+ });
}
- private void addStaticCodeAnalysisFeedbackToResult(Result result, AbstractBuildResultNotificationDTO buildResult, ProgrammingExercise programmingExercise) {
- final var staticCodeAnalysisReports = buildResult.getStaticCodeAnalysisReports();
+ private void addStaticCodeAnalysisFeedbackToResult(Result result, BuildResultNotification buildResult, ProgrammingExercise programmingExercise) {
+ final var staticCodeAnalysisReports = buildResult.staticCodeAnalysisReports();
if (Boolean.TRUE.equals(programmingExercise.isStaticCodeAnalysisEnabled()) && staticCodeAnalysisReports != null && !staticCodeAnalysisReports.isEmpty()) {
List scaFeedbackList = feedbackCreationService.createFeedbackFromStaticCodeAnalysisReports(staticCodeAnalysisReports);
result.addFeedbacks(scaFeedbackList);
@@ -105,18 +97,6 @@ private void addStaticCodeAnalysisFeedbackToResult(Result result, AbstractBuildR
}
}
- private void addTestwiseCoverageReportToResult(Result result, AbstractBuildResultNotificationDTO buildResult, ProgrammingExercise programmingExercise) {
- programmingExercise.setBuildConfig(programmingExerciseBuildConfigRepository.getProgrammingExerciseBuildConfigElseThrow(programmingExercise));
- if (Boolean.TRUE.equals(programmingExercise.getBuildConfig().isTestwiseCoverageEnabled())) {
- var report = buildResult.getTestwiseCoverageReports();
- if (report != null) {
- // since the test cases are not saved to the database yet, the test case is null for the entries
- var coverageFileReportsWithoutTestsByTestCaseName = testwiseCoverageService.createTestwiseCoverageFileReportsWithoutTestsByTestCaseName(report);
- result.setCoverageFileReportsByTestCaseName(coverageFileReportsWithoutTestsByTestCaseName);
- }
- }
- }
-
/**
* Find the ZonedDateTime of the first BuildLogEntry that contains the searchString in the log message.
*
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/ContinuousIntegrationResultService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/ContinuousIntegrationResultService.java
index b81239c44f0e..a63fc4871d4c 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/ContinuousIntegrationResultService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/ContinuousIntegrationResultService.java
@@ -8,7 +8,7 @@
import de.tum.cit.aet.artemis.programming.domain.ProgrammingSubmission;
import de.tum.cit.aet.artemis.programming.domain.ProjectType;
import de.tum.cit.aet.artemis.programming.domain.build.BuildLogEntry;
-import de.tum.cit.aet.artemis.programming.dto.AbstractBuildResultNotificationDTO;
+import de.tum.cit.aet.artemis.programming.dto.BuildResultNotification;
/**
* Abstract service for managing entities related to continuous integration.
@@ -21,7 +21,7 @@ public interface ContinuousIntegrationResultService {
* @param requestBody the object sent from the CI system to Artemis
* @return the DTO with all information in Java Object form
*/
- AbstractBuildResultNotificationDTO convertBuildResult(Object requestBody);
+ BuildResultNotification convertBuildResult(Object requestBody);
/**
* Generate an Artemis result object from the CI build result. Will use the test case results and issues in static code analysis as result feedback.
@@ -30,7 +30,7 @@ public interface ContinuousIntegrationResultService {
* @param participation to attach result to.
* @return the created Artemis result with a score, completion date, etc.
*/
- Result createResultFromBuildResult(AbstractBuildResultNotificationDTO buildResult, ProgrammingExerciseParticipation participation);
+ Result createResultFromBuildResult(BuildResultNotification buildResult, ProgrammingExerciseParticipation participation);
/**
* Extract the build log statistics from the BuildLogEntries and persist a BuildLogStatisticsEntry.
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/notification/dto/TestCaseDTO.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/notification/dto/TestCaseDTO.java
index e4e15c9227bf..5ae570f5b2d5 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/notification/dto/TestCaseDTO.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/notification/dto/TestCaseDTO.java
@@ -14,13 +14,13 @@
import com.fasterxml.jackson.annotation.Nulls;
import de.tum.cit.aet.artemis.assessment.domain.Feedback;
-import de.tum.cit.aet.artemis.programming.dto.TestCaseBaseDTO;
+import de.tum.cit.aet.artemis.programming.dto.TestCaseBase;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public record TestCaseDTO(String name, String classname, double time, @JsonProperty("failures") @JsonSetter(nulls = Nulls.AS_EMPTY) List failures,
@JsonProperty("errors") @JsonSetter(nulls = Nulls.AS_EMPTY) List errors,
- @JsonProperty("successInfos") @JsonSetter(nulls = Nulls.AS_EMPTY) List successInfos) implements TestCaseBaseDTO {
+ @JsonProperty("successInfos") @JsonSetter(nulls = Nulls.AS_EMPTY) List successInfos) implements TestCaseBase {
@JsonIgnore
public boolean isSuccessful() {
@@ -28,12 +28,7 @@ public boolean isSuccessful() {
}
@Override
- public String getName() {
- return name;
- }
-
- @Override
- public List getTestMessages() {
+ public List testMessages() {
return extractMessage().map(Collections::singletonList).orElse(Collections.emptyList());
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/notification/dto/TestResultsDTO.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/notification/dto/TestResultsDTO.java
index cd029f5adf5e..9bb2e13c588a 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/notification/dto/TestResultsDTO.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/notification/dto/TestResultsDTO.java
@@ -4,7 +4,6 @@
import java.util.List;
import java.util.stream.Stream;
-import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
@@ -15,156 +14,64 @@
import de.tum.cit.aet.artemis.programming.domain.RepositoryType;
import de.tum.cit.aet.artemis.programming.domain.build.BuildLogEntry;
-import de.tum.cit.aet.artemis.programming.dto.AbstractBuildResultNotificationDTO;
-import de.tum.cit.aet.artemis.programming.dto.BuildJobDTOInterface;
+import de.tum.cit.aet.artemis.programming.dto.BuildJobInterface;
+import de.tum.cit.aet.artemis.programming.dto.BuildResultNotification;
import de.tum.cit.aet.artemis.programming.dto.StaticCodeAnalysisReportDTO;
import de.tum.cit.aet.artemis.programming.service.ci.notification.BuildLogParseUtils;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
// Note: due to limitations with inheritance, we cannot declare this as record, but we can use it in a similar way with final fields
-public class TestResultsDTO extends AbstractBuildResultNotificationDTO {
-
- private final int successful;
-
- private final int skipped;
-
- private final int errors;
-
- private final int failures;
-
- private final String fullName;
-
- private final List commits;
-
- private final List results;
-
- private final List