From d76428dc0cac4eff6e6a4788f218aaa27063811f Mon Sep 17 00:00:00 2001 From: Peter Trifanov Date: Mon, 5 Sep 2022 15:08:03 +0300 Subject: [PATCH] Move `score` from `lnk_contest_execution` to `execution` (#1156) * Move `score` from `lnk_contest_execution` to `execution` * Forbid rerun of `TestingType.CONTEST_MODE` executions on backend * Get best_score directly from lnk_contest_project (this column is not being set yet, will be added in subsequent PRs) Second part of #1115 --- db/test-data/execution-insert.xml | 6 +++ db/test-data/lnk-contest-execution-insert.xml | 1 - .../sqlRequests/lnk-contest-execution.csv | 18 ++++----- db/v-2/tables/lnk-contest-execution.xml | 10 +++++ db/v-2/tables/lnk-contest-project.xml | 4 ++ save-backend/backend-api-docs.json | 8 ++++ .../LnkContestProjectController.kt | 2 +- .../controllers/RunExecutionController.kt | 4 ++ .../LnkContestExecutionRepository.kt | 9 ++++- .../repository/LnkContestProjectRepository.kt | 7 ++++ .../save/backend/service/ExecutionService.kt | 1 + .../service/LnkContestExecutionService.kt | 12 ------ .../service/LnkContestProjectService.kt | 10 ++++- .../save/execution/ExecutionDto.kt | 3 ++ .../saveourtool/save/entities/Execution.kt | 37 +++++++++++-------- .../save/entities/LnkContestExecution.kt | 4 +- .../save/entities/LnkContestProject.kt | 2 +- .../basic/ExecutionStatisticsValuesTest.kt | 1 + 18 files changed, 94 insertions(+), 45 deletions(-) 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)