diff --git a/db/test-data/execution-insert.xml b/db/test-data/execution-insert.xml
index 8126d0be91..0dc0034dc7 100644
--- a/db/test-data/execution-insert.xml
+++ b/db/test-data/execution-insert.xml
@@ -33,6 +33,7 @@
+
@@ -61,6 +62,7 @@
+
@@ -89,6 +91,7 @@
+
@@ -117,6 +120,7 @@
+
@@ -145,6 +149,7 @@
+
@@ -174,6 +179,7 @@
+
diff --git a/db/test-data/lnk-contest-execution-insert.xml b/db/test-data/lnk-contest-execution-insert.xml
index 8744ac1e40..7625352927 100644
--- a/db/test-data/lnk-contest-execution-insert.xml
+++ b/db/test-data/lnk-contest-execution-insert.xml
@@ -10,7 +10,6 @@
-
diff --git a/db/test-data/sqlRequests/lnk-contest-execution.csv b/db/test-data/sqlRequests/lnk-contest-execution.csv
index 9696f0f200..3ca63d4861 100644
--- a/db/test-data/sqlRequests/lnk-contest-execution.csv
+++ b/db/test-data/sqlRequests/lnk-contest-execution.csv
@@ -1,9 +1,9 @@
-id;contest_id;execution_id;score
-1;1;1;100.0
-2;1;2;75.0
-3;1;3;24.4
-4;1;4;11.2
-5;2;1;0.0
-6;2;2;11.11
-7;2;3;22.22
-8;2;4;88.88
+id;contest_id;execution_id
+1;1;1
+2;1;2
+3;1;3
+4;1;4
+5;2;1
+6;2;2
+7;2;3
+8;2;4
diff --git a/db/v-2/tables/lnk-contest-execution.xml b/db/v-2/tables/lnk-contest-execution.xml
index d5a068fa4d..9b1f24c4de 100644
--- a/db/v-2/tables/lnk-contest-execution.xml
+++ b/db/v-2/tables/lnk-contest-execution.xml
@@ -33,4 +33,14 @@
+
+
+
+
+
+ update lnk_contest_execution lce inner join execution e on e.id = lce.execution_id set e.score = lce.score;
+
+
+
+
\ No newline at end of file
diff --git a/db/v-2/tables/lnk-contest-project.xml b/db/v-2/tables/lnk-contest-project.xml
index 449f82a300..b2de181ba9 100644
--- a/db/v-2/tables/lnk-contest-project.xml
+++ b/db/v-2/tables/lnk-contest-project.xml
@@ -46,4 +46,8 @@
+
+
+
+
\ No newline at end of file
diff --git a/save-backend/backend-api-docs.json b/save-backend/backend-api-docs.json
index b8ab77db44..8db517d3de 100644
--- a/save-backend/backend-api-docs.json
+++ b/save-backend/backend-api-docs.json
@@ -7426,6 +7426,10 @@
"testSuiteSourceName": {
"type": "string"
},
+ "score": {
+ "type": "number",
+ "format": "double"
+ },
"id": {
"type": "integer",
"format": "int64"
@@ -7604,6 +7608,10 @@
},
"testSuiteSourceName": {
"type": "string"
+ },
+ "score": {
+ "type": "number",
+ "format": "double"
}
}
},
diff --git a/save-backend/src/main/kotlin/com/saveourtool/save/backend/controllers/LnkContestProjectController.kt b/save-backend/src/main/kotlin/com/saveourtool/save/backend/controllers/LnkContestProjectController.kt
index 92fed5dc76..0e410a47b4 100644
--- a/save-backend/src/main/kotlin/com/saveourtool/save/backend/controllers/LnkContestProjectController.kt
+++ b/save-backend/src/main/kotlin/com/saveourtool/save/backend/controllers/LnkContestProjectController.kt
@@ -94,7 +94,7 @@ class LnkContestProjectController(
).getScores()
private fun Flux.getScores() = map {
- it to lnkContestExecutionService.getBestScoreOfProjectInContestWithName(it.project, it.contest.name)
+ it to lnkContestProjectService.getBestScoreOfProjectInContestWithName(it.project, it.contest.name)
}
.map { (lnkContestProject, score) ->
lnkContestProject.toContestResult(score)
diff --git a/save-backend/src/main/kotlin/com/saveourtool/save/backend/controllers/RunExecutionController.kt b/save-backend/src/main/kotlin/com/saveourtool/save/backend/controllers/RunExecutionController.kt
index 2f63c8403f..30316be8e4 100644
--- a/save-backend/src/main/kotlin/com/saveourtool/save/backend/controllers/RunExecutionController.kt
+++ b/save-backend/src/main/kotlin/com/saveourtool/save/backend/controllers/RunExecutionController.kt
@@ -105,6 +105,10 @@ class RunExecutionController(
authentication: Authentication,
): Mono = blockingToMono { executionService.findExecution(executionId) }
.switchIfEmptyToNotFound { "Not found execution id = $executionId" }
+ .filter { it.type != TestingType.CONTEST_MODE }
+ .switchIfEmptyToResponseException(HttpStatus.CONFLICT) {
+ "Rerun is not supported for executions that were performed under a contest"
+ }
.validateAccess(authentication) { execution ->
ProjectCoordinates(
execution.project.organization.name,
diff --git a/save-backend/src/main/kotlin/com/saveourtool/save/backend/repository/LnkContestExecutionRepository.kt b/save-backend/src/main/kotlin/com/saveourtool/save/backend/repository/LnkContestExecutionRepository.kt
index 3cd729dd50..dab37b1589 100644
--- a/save-backend/src/main/kotlin/com/saveourtool/save/backend/repository/LnkContestExecutionRepository.kt
+++ b/save-backend/src/main/kotlin/com/saveourtool/save/backend/repository/LnkContestExecutionRepository.kt
@@ -18,7 +18,7 @@ interface LnkContestExecutionRepository : BaseEntityRepository
+ fun findByExecutionProjectAndContestNameOrderByExecutionScoreDesc(project: Project, contestName: String, pageable: Pageable): Page
/**
* Get N executions of a [Project] in [Contest]
@@ -46,4 +46,11 @@ interface LnkContestExecutionRepository : BaseEntityRepository): List
+
+ /**
+ * @param project
+ * @param contestName
+ * @return [LnkContestExecution] associated with [project] and [Contest] with name [contestName]
+ */
+ fun findByExecutionProjectAndContestName(project: Project, contestName: String): LnkContestExecution?
}
diff --git a/save-backend/src/main/kotlin/com/saveourtool/save/backend/repository/LnkContestProjectRepository.kt b/save-backend/src/main/kotlin/com/saveourtool/save/backend/repository/LnkContestProjectRepository.kt
index 40aa9472d7..de5fa4c505 100644
--- a/save-backend/src/main/kotlin/com/saveourtool/save/backend/repository/LnkContestProjectRepository.kt
+++ b/save-backend/src/main/kotlin/com/saveourtool/save/backend/repository/LnkContestProjectRepository.kt
@@ -52,4 +52,11 @@ interface LnkContestProjectRepository : BaseEntityRepository
* @return list of [LnkContestProject] linked to contest with name [contestName]
*/
fun findByContestName(contestName: String): List
+
+ /**
+ * @param project
+ * @param contestName
+ * @return a [LnkContestProject], if any, associated with [project] and [Contest] named [contestName]
+ */
+ fun findByProjectAndContestName(project: Project, contestName: String): LnkContestProject?
}
diff --git a/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/ExecutionService.kt b/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/ExecutionService.kt
index 56b6e73f15..d564a19097 100644
--- a/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/ExecutionService.kt
+++ b/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/ExecutionService.kt
@@ -236,6 +236,7 @@ class ExecutionService(
execCmd = execCmd,
batchSizeForAnalyzer = batchSizeForAnalyzer,
testSuiteSourceName = testSuiteSourceName,
+ score = null,
)
val savedExecution = saveExecution(execution)
log.info("Created a new execution id=${savedExecution.id} for project id=${project.id}")
diff --git a/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/LnkContestExecutionService.kt b/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/LnkContestExecutionService.kt
index 5c5f83e211..cbf90068b4 100644
--- a/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/LnkContestExecutionService.kt
+++ b/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/LnkContestExecutionService.kt
@@ -3,7 +3,6 @@ package com.saveourtool.save.backend.service
import com.saveourtool.save.backend.repository.LnkContestExecutionRepository
import com.saveourtool.save.entities.*
import org.springframework.data.domain.PageRequest
-import org.springframework.data.domain.Pageable
import org.springframework.stereotype.Service
/**
@@ -13,17 +12,6 @@ import org.springframework.stereotype.Service
class LnkContestExecutionService(
private val lnkContestExecutionRepository: LnkContestExecutionRepository,
) {
- /**
- * @param project
- * @param contestName
- * @return best score of a [Project] in contest with name [contestName]
- */
- fun getBestScoreOfProjectInContestWithName(project: Project, contestName: String) =
- lnkContestExecutionRepository.findByExecutionProjectAndContestNameOrderByScoreDesc(project, contestName, Pageable.ofSize(1))
- .content
- .singleOrNull()
- ?.score
-
/**
* @param contest
* @param project
diff --git a/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/LnkContestProjectService.kt b/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/LnkContestProjectService.kt
index 82fb0958a2..b977638197 100644
--- a/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/LnkContestProjectService.kt
+++ b/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/LnkContestProjectService.kt
@@ -45,6 +45,14 @@ class LnkContestProjectService(
lnkContestProjectRepository.findByContestNameAndProjectIdIn(contestName, it)
}
+ /**
+ * @param project
+ * @param contestName
+ * @return best score of [project] under [Contest] with name [contestName]
+ */
+ fun getBestScoreOfProjectInContestWithName(project: Project, contestName: String) =
+ lnkContestProjectRepository.findByProjectAndContestName(project, contestName)?.bestScore
+
/**
* @param project a [Project]
* @param contest a [Contest]
@@ -54,7 +62,7 @@ class LnkContestProjectService(
fun saveLnkContestProject(project: Project, contest: Contest): Boolean = if (lnkContestProjectRepository.findByContestAndProject(contest, project).isPresent) {
false
} else {
- lnkContestProjectRepository.save(LnkContestProject(project, contest, null, 0))
+ lnkContestProjectRepository.save(LnkContestProject(project, contest, null, 0.0))
true
}
}
diff --git a/save-cloud-common/src/commonMain/kotlin/com/saveourtool/save/execution/ExecutionDto.kt b/save-cloud-common/src/commonMain/kotlin/com/saveourtool/save/execution/ExecutionDto.kt
index 3cb95e4ec3..8841fc6aef 100644
--- a/save-cloud-common/src/commonMain/kotlin/com/saveourtool/save/execution/ExecutionDto.kt
+++ b/save-cloud-common/src/commonMain/kotlin/com/saveourtool/save/execution/ExecutionDto.kt
@@ -19,6 +19,7 @@ import kotlinx.serialization.Serializable
* @property expectedChecks
* @property unexpectedChecks
* @property testSuiteSourceName
+ * @property score see [Execution.score]
*/
@Serializable
@Suppress("LongParameterList")
@@ -39,6 +40,7 @@ data class ExecutionDto(
val expectedChecks: Long,
val unexpectedChecks: Long,
val testSuiteSourceName: String?,
+ val score: Double?,
) {
companion object {
val empty = ExecutionDto(
@@ -58,6 +60,7 @@ data class ExecutionDto(
expectedChecks = 0,
unexpectedChecks = 0,
testSuiteSourceName = "",
+ score = null,
)
}
}
diff --git a/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/Execution.kt b/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/Execution.kt
index 0a38f8a909..63ac292277 100644
--- a/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/Execution.kt
+++ b/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/Execution.kt
@@ -38,6 +38,7 @@ import javax.persistence.ManyToOne
* @property execCmd
* @property batchSizeForAnalyzer
* @property testSuiteSourceName
+ * @property score a rating of this execution. Specific meaning may vary depending on [type]
*/
@Suppress("LongParameterList")
@Entity
@@ -95,28 +96,31 @@ class Execution(
var testSuiteSourceName: String?,
+ var score: Double?,
+
) : BaseEntity() {
/**
* @return Execution dto
*/
@Suppress("UnsafeCallOnNullableType")
fun toDto() = ExecutionDto(
- id!!,
- status,
- type,
- version,
- startTime.toEpochSecond(ZoneOffset.UTC),
- endTime?.toEpochSecond(ZoneOffset.UTC),
- allTests,
- runningTests,
- passedTests,
- failedTests,
- skippedTests,
- unmatchedChecks,
- matchedChecks,
- expectedChecks,
- unexpectedChecks,
- testSuiteSourceName,
+ id = id!!,
+ status = status,
+ type = type,
+ version = version,
+ startTime = startTime.toEpochSecond(ZoneOffset.UTC),
+ endTime = endTime?.toEpochSecond(ZoneOffset.UTC),
+ allTests = allTests,
+ runningTests = runningTests,
+ passedTests = passedTests,
+ failedTests = failedTests,
+ skippedTests = skippedTests,
+ unmatchedChecks = unmatchedChecks,
+ matchedChecks = matchedChecks,
+ expectedChecks = expectedChecks,
+ unexpectedChecks = unexpectedChecks,
+ testSuiteSourceName = testSuiteSourceName,
+ score = score,
)
/**
@@ -173,6 +177,7 @@ class Execution(
execCmd = null,
batchSizeForAnalyzer = null,
testSuiteSourceName = "",
+ score = null,
)
/**
diff --git a/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/LnkContestExecution.kt b/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/LnkContestExecution.kt
index 6eb3141277..3ec325d647 100644
--- a/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/LnkContestExecution.kt
+++ b/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/LnkContestExecution.kt
@@ -10,7 +10,6 @@ import javax.persistence.OneToOne
*
* @property contest
* @property execution
- * @property score the result of an execution
*/
@Entity
class LnkContestExecution(
@@ -22,7 +21,6 @@ class LnkContestExecution(
@JoinColumn(name = "contest_id")
var contest: Contest,
- var score: Double
) : BaseEntity() {
/**
* @return [ContestResult] from [LnkContestExecution]
@@ -31,7 +29,7 @@ class LnkContestExecution(
execution.project.name,
execution.project.organization.name,
contest.name,
- score,
+ execution.score,
execution.startTime,
execution.status,
execution.sdk,
diff --git a/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/LnkContestProject.kt b/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/LnkContestProject.kt
index 57aefc0ba5..60e3c3e8cf 100644
--- a/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/LnkContestProject.kt
+++ b/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/LnkContestProject.kt
@@ -25,7 +25,7 @@ class LnkContestProject(
@JoinColumn(name = "best_execution_id")
var bestExecution: Execution?,
- var bestScore: Int,
+ var bestScore: Double?,
) : BaseEntity() {
/**
diff --git a/save-frontend/src/test/kotlin/com/saveourtool/save/frontend/components/basic/ExecutionStatisticsValuesTest.kt b/save-frontend/src/test/kotlin/com/saveourtool/save/frontend/components/basic/ExecutionStatisticsValuesTest.kt
index 04a8ade36e..faed360449 100644
--- a/save-frontend/src/test/kotlin/com/saveourtool/save/frontend/components/basic/ExecutionStatisticsValuesTest.kt
+++ b/save-frontend/src/test/kotlin/com/saveourtool/save/frontend/components/basic/ExecutionStatisticsValuesTest.kt
@@ -39,6 +39,7 @@ class ExecutionStatisticsValuesTest {
expectedChecks = 25,
unexpectedChecks = 5,
testSuiteSourceName = "",
+ score = null,
)
val executionStatisticsValues = ExecutionStatisticsValues(executionDto)
assertEquals("danger", executionStatisticsValues.style)