diff --git a/db/changelog/v-1/02-changeset-agent-status-table.xml b/db/changelog/v-1/02-changeset-agent-status-table.xml index 81cc8bd7df..56a10aa5f1 100644 --- a/db/changelog/v-1/02-changeset-agent-status-table.xml +++ b/db/changelog/v-1/02-changeset-agent-status-table.xml @@ -18,10 +18,10 @@ - + - + diff --git a/db/changelog/v-1/03-changeset-test-execution-table.xml b/db/changelog/v-1/03-changeset-test-execution-table.xml index 13c65fdc87..20511f4106 100644 --- a/db/changelog/v-1/03-changeset-test-execution-table.xml +++ b/db/changelog/v-1/03-changeset-test-execution-table.xml @@ -27,10 +27,10 @@ - + - + diff --git a/db/changelog/v-1/11-changeset-test-agent-insert-data.xml b/db/changelog/v-1/11-changeset-test-agent-insert-data.xml index ec2164d827..270acf14c9 100644 --- a/db/changelog/v-1/11-changeset-test-agent-insert-data.xml +++ b/db/changelog/v-1/11-changeset-test-agent-insert-data.xml @@ -88,8 +88,8 @@ - - + + diff --git a/save-backend/src/main/kotlin/org/cqfn/save/backend/controllers/AgentsController.kt b/save-backend/src/main/kotlin/org/cqfn/save/backend/controllers/AgentsController.kt index a13dfa641e..44eb368590 100644 --- a/save-backend/src/main/kotlin/org/cqfn/save/backend/controllers/AgentsController.kt +++ b/save-backend/src/main/kotlin/org/cqfn/save/backend/controllers/AgentsController.kt @@ -7,7 +7,6 @@ import org.cqfn.save.entities.Agent import org.cqfn.save.entities.AgentStatus import org.cqfn.save.entities.AgentStatusDto import org.cqfn.save.entities.AgentStatusesForExecution -import org.cqfn.save.entities.Execution import org.slf4j.LoggerFactory import org.springframework.transaction.annotation.Transactional import org.springframework.web.bind.annotation.GetMapping @@ -60,7 +59,7 @@ class AgentsController(private val agentStatusRepository: AgentStatusRepository, @Transactional fun updateAgentStatusesWithDto(@RequestBody agentStates: List) { agentStates.forEach { dto -> - val agentStatus = agentStatusRepository.findTopByAgentContainerIdOrderByEndTimeDesc(dto.containerId) + val agentStatus = agentStatusRepository.findTopByAgentContainerIdOrderByEndTimeDescIdDesc(dto.containerId) if (agentStatus != null && agentStatus.state == dto.state) { // updating time agentStatus.endTime = dto.time @@ -85,11 +84,9 @@ class AgentsController(private val agentStatusRepository: AgentStatusRepository, @Suppress("UnsafeCallOnNullableType") // id will be available because it's retrieved from DB fun findAllAgentStatusesForSameExecution(@RequestParam agentId: String): AgentStatusesForExecution { val execution = getAgentByContainerId(agentId).execution - val agentStatuses = agentRepository.findAll { root, cq, cb -> - cb.equal(root.get("execution"), execution) - }.map { agent -> + val agentStatuses = agentRepository.findByExecutionId(execution.id!!).map { agent -> val latestStatus = requireNotNull( - agentStatusRepository.findTopByAgentContainerIdOrderByEndTimeDesc(agent.containerId) + agentStatusRepository.findTopByAgentContainerIdOrderByEndTimeDescIdDesc(agent.containerId) ) { "AgentStatus not found for agent id=${agent.containerId}" } diff --git a/save-backend/src/main/kotlin/org/cqfn/save/backend/controllers/TestExecutionController.kt b/save-backend/src/main/kotlin/org/cqfn/save/backend/controllers/TestExecutionController.kt index f2fd8fc1a7..a706d18c3b 100644 --- a/save-backend/src/main/kotlin/org/cqfn/save/backend/controllers/TestExecutionController.kt +++ b/save-backend/src/main/kotlin/org/cqfn/save/backend/controllers/TestExecutionController.kt @@ -2,6 +2,7 @@ package org.cqfn.save.backend.controllers import org.cqfn.save.agent.TestExecutionDto import org.cqfn.save.backend.service.TestExecutionService +import org.cqfn.save.test.TestDto import org.springframework.dao.DataAccessException import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity @@ -45,6 +46,15 @@ class TestExecutionController(private val testExecutionService: TestExecutionSer fun getTestExecutionsCount(@RequestParam executionId: Long) = testExecutionService.getTestExecutionsCount(executionId) + /** + * @param agentContainerId id of an agent + * @param testDtos test that will be executed by [agentContainerId] agent + */ + @PostMapping(value = ["/testExecution/assignAgent"]) + fun assignAgentByTest(@RequestParam agentContainerId: String, @RequestBody testDtos: List) { + testExecutionService.assignAgentByTest(agentContainerId, testDtos) + } + /** * @param testExecutionsDto * @return response diff --git a/save-backend/src/main/kotlin/org/cqfn/save/backend/repository/AgentStatusRepository.kt b/save-backend/src/main/kotlin/org/cqfn/save/backend/repository/AgentStatusRepository.kt index b62020cffa..44ff9a17e5 100644 --- a/save-backend/src/main/kotlin/org/cqfn/save/backend/repository/AgentStatusRepository.kt +++ b/save-backend/src/main/kotlin/org/cqfn/save/backend/repository/AgentStatusRepository.kt @@ -20,7 +20,7 @@ interface AgentStatusRepository : BaseEntityRepository, JpaSpecific * @param containerId id of an agent * @return [AgentStatus] of an agent */ - fun findTopByAgentContainerIdOrderByEndTimeDesc(containerId: String): AgentStatus? + fun findTopByAgentContainerIdOrderByEndTimeDescIdDesc(containerId: String): AgentStatus? } /** diff --git a/save-backend/src/main/kotlin/org/cqfn/save/backend/service/TestExecutionService.kt b/save-backend/src/main/kotlin/org/cqfn/save/backend/service/TestExecutionService.kt index 0cf0dfcc8a..429ce77245 100644 --- a/save-backend/src/main/kotlin/org/cqfn/save/backend/service/TestExecutionService.kt +++ b/save-backend/src/main/kotlin/org/cqfn/save/backend/service/TestExecutionService.kt @@ -8,11 +8,13 @@ import org.cqfn.save.backend.repository.TestRepository import org.cqfn.save.backend.utils.secondsToLocalDateTime import org.cqfn.save.domain.TestResultStatus import org.cqfn.save.entities.TestExecution +import org.cqfn.save.test.TestDto import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.data.domain.PageRequest import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional /** * Service for test result @@ -56,6 +58,7 @@ class TestExecutionService(private val testExecutionRepository: TestExecutionRep */ @Suppress("TOO_MANY_LINES_IN_LAMBDA", "UnsafeCallOnNullableType") fun saveTestResult(testExecutionsDtos: List): List { + log.debug("Saving ${testExecutionsDtos.size} test results from agent ${testExecutionsDtos.first().agentContainerId}") // we take agent id only from first element, because all test executions have same execution val agentContainerId = requireNotNull(testExecutionsDtos.first().agentContainerId) { "Attempt to save test results without assigned agent. testExecutionDtos=$testExecutionsDtos" @@ -111,4 +114,33 @@ class TestExecutionService(private val testExecutionRepository: TestExecutionRep ) } } + + /** + * Set `agent` field of test executions corresponding to [testDtos] to [agentContainerId] + * + * @param agentContainerId id of an agent + * @param testDtos test that will be executed by [agentContainerId] agent + */ + @Transactional + @Suppress("UnsafeCallOnNullableType") + fun assignAgentByTest(agentContainerId: String, testDtos: List) { + val agent = requireNotNull(agentRepository.findByContainerId(agentContainerId)) { + "Agent with containerId=[$agentContainerId] was not found in the DB" + } + val executionId = agent.execution.id!! + testDtos.forEach { test -> + val testExecution = testExecutionRepository.findByExecutionIdAndTestPluginNameAndTestFilePath( + executionId, + test.pluginName, + test.filePath + ) + .orElseThrow { + log.error("Can't find test_execution for executionId=$executionId, test.pluginName=${test.pluginName}, test.filePath=${test.filePath}") + NoSuchElementException() + } + testExecutionRepository.save(testExecution.apply { + this.agent = agent + }) + } + } } diff --git a/save-backend/src/main/resources/logback.xml b/save-backend/src/main/resources/logback.xml index 9429c13fbb..8cf986a72c 100644 --- a/save-backend/src/main/resources/logback.xml +++ b/save-backend/src/main/resources/logback.xml @@ -5,6 +5,8 @@ + + diff --git a/save-cloud-common/src/commonMain/kotlin/org/cqfn/save/agent/AgentState.kt b/save-cloud-common/src/commonMain/kotlin/org/cqfn/save/agent/AgentState.kt index 8c2af5f036..928dae93f9 100644 --- a/save-cloud-common/src/commonMain/kotlin/org/cqfn/save/agent/AgentState.kt +++ b/save-cloud-common/src/commonMain/kotlin/org/cqfn/save/agent/AgentState.kt @@ -41,5 +41,10 @@ enum class AgentState { * Agent has just started and hasn't received any heartbeats yet */ STARTING, + + /** + * Agent has been stopped by save-orchestartor, because there is no more work left + */ + STOPPED_BY_ORCH, ; } diff --git a/save-orchestrator/src/main/kotlin/org/cqfn/save/orchestrator/config/ConfigProperties.kt b/save-orchestrator/src/main/kotlin/org/cqfn/save/orchestrator/config/ConfigProperties.kt index 206d12a0af..50bbe01092 100644 --- a/save-orchestrator/src/main/kotlin/org/cqfn/save/orchestrator/config/ConfigProperties.kt +++ b/save-orchestrator/src/main/kotlin/org/cqfn/save/orchestrator/config/ConfigProperties.kt @@ -15,6 +15,7 @@ import org.springframework.boot.context.properties.ConstructorBinding * @property docker configuration for docker API * @property agentsCount a number of agents to start for every [Execution] * @property executionLogs path to folder to store cli logs + * @property shutdownChecksIntervalMillis interval between checks whether agents are really finished */ @ConstructorBinding @ConfigurationProperties(prefix = "orchestrator") @@ -24,6 +25,7 @@ data class ConfigProperties( val docker: DockerSettings, val agentsCount: Int, val executionLogs: String, + val shutdownChecksIntervalMillis: Long, ) /** diff --git a/save-orchestrator/src/main/kotlin/org/cqfn/save/orchestrator/controller/HeartbeatController.kt b/save-orchestrator/src/main/kotlin/org/cqfn/save/orchestrator/controller/HeartbeatController.kt index 2d5ae22022..9c901a9202 100644 --- a/save-orchestrator/src/main/kotlin/org/cqfn/save/orchestrator/controller/HeartbeatController.kt +++ b/save-orchestrator/src/main/kotlin/org/cqfn/save/orchestrator/controller/HeartbeatController.kt @@ -3,7 +3,6 @@ package org.cqfn.save.orchestrator.controller import org.cqfn.save.agent.AgentState import org.cqfn.save.agent.ContinueResponse import org.cqfn.save.agent.Heartbeat -import org.cqfn.save.agent.NewJobResponse import org.cqfn.save.agent.WaitResponse import org.cqfn.save.entities.AgentStatusDto import org.cqfn.save.orchestrator.config.ConfigProperties @@ -15,8 +14,8 @@ import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RestController import reactor.core.publisher.Mono -import reactor.core.scheduler.Schedulers +import java.time.Duration import java.time.LocalDateTime import kotlinx.serialization.ExperimentalSerializationApi @@ -34,7 +33,6 @@ class HeartbeatController(private val agentService: AgentService, private val dockerService: DockerService, private val configProperties: ConfigProperties) { private val logger = LoggerFactory.getLogger(HeartbeatController::class.java) - private val scheduler = Schedulers.boundedElastic().also { it.start() } /** * This controller accepts heartbeat and depending on the state it returns the needed response @@ -66,8 +64,6 @@ class HeartbeatController(private val agentService: AgentService, .doOnSuccess { if (it is WaitResponse) { initiateShutdownSequence(heartbeat.agentId) - } else if (it is NewJobResponse) { - logger.debug("Agent ${heartbeat.agentId} will receive the following job: $it") } } AgentState.FINISHED -> { @@ -75,9 +71,7 @@ class HeartbeatController(private val agentService: AgentService, Mono.just(WaitResponse) } AgentState.BUSY -> Mono.just(ContinueResponse) - AgentState.BACKEND_FAILURE -> Mono.just(WaitResponse) - AgentState.BACKEND_UNREACHABLE -> Mono.just(WaitResponse) - AgentState.CLI_FAILED -> Mono.just(WaitResponse) + AgentState.BACKEND_FAILURE, AgentState.BACKEND_UNREACHABLE, AgentState.CLI_FAILED, AgentState.STOPPED_BY_ORCH -> Mono.just(WaitResponse) } ) .map { @@ -93,8 +87,18 @@ class HeartbeatController(private val agentService: AgentService, * @param agentId an ID of the agent from the execution, that will be checked. */ private fun initiateShutdownSequence(agentId: String) { - agentService.getAgentsAwaitingStop(agentId).doOnSuccess { (executionId, finishedAgentIds) -> - scheduler.schedule { + agentService.getAgentsAwaitingStop(agentId).flatMap { (_, finishedAgentIds) -> + if (finishedAgentIds.isNotEmpty()) { + // need to retry after some time, because for other agents BUSY state might have not been written completely + logger.debug("Waiting for ${configProperties.shutdownChecksIntervalMillis} seconds to repeat `getAgentsAwaitingStop` call for agentId=$agentId") + Mono.delay(Duration.ofMillis(configProperties.shutdownChecksIntervalMillis)).then( + agentService.getAgentsAwaitingStop(agentId) + ) + } else { + Mono.empty() + } + } + .flatMap { (executionId, finishedAgentIds) -> if (finishedAgentIds.isNotEmpty()) { logger.debug("Agents ids=$finishedAgentIds have completed execution, will make an attempt to terminate them") val areAgentsStopped = dockerService.stopAgents(finishedAgentIds) @@ -102,12 +106,16 @@ class HeartbeatController(private val agentService: AgentService, logger.info("Agents have been stopped, will mark execution id=$executionId and agents $finishedAgentIds as FINISHED") agentService .markAgentsAndExecutionAsFinished(executionId, finishedAgentIds) - .block() + } else { + logger.warn("Agents $finishedAgentIds are not stopped after stop command") + Mono.empty() } + } else { + logger.debug("Agents other than $agentId are still running, so won't try to stop them") + Mono.empty() } } - } - .subscribeOn(scheduler) + .subscribeOn(agentService.scheduler) .subscribe() } } diff --git a/save-orchestrator/src/main/kotlin/org/cqfn/save/orchestrator/service/AgentService.kt b/save-orchestrator/src/main/kotlin/org/cqfn/save/orchestrator/service/AgentService.kt index ed37c6e4cf..5760f8710f 100644 --- a/save-orchestrator/src/main/kotlin/org/cqfn/save/orchestrator/service/AgentService.kt +++ b/save-orchestrator/src/main/kotlin/org/cqfn/save/orchestrator/service/AgentService.kt @@ -12,6 +12,7 @@ import org.cqfn.save.execution.ExecutionStatus import org.cqfn.save.execution.ExecutionUpdateDto import org.cqfn.save.orchestrator.BodilessResponseEntity import org.cqfn.save.test.TestBatch +import org.cqfn.save.test.TestDto import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Qualifier @@ -20,6 +21,7 @@ import org.springframework.web.reactive.function.BodyInserters import org.springframework.web.reactive.function.client.WebClient import org.springframework.web.reactive.function.client.bodyToMono import reactor.core.publisher.Mono +import reactor.core.scheduler.Schedulers import reactor.util.Loggers import java.time.LocalDateTime @@ -30,6 +32,11 @@ import java.util.logging.Level */ @Service class AgentService { + /** + * A scheduler that executes long-running background tasks + */ + internal val scheduler = Schedulers.boundedElastic().also { it.start() } + @Autowired @Qualifier("webClientBackend") private lateinit var webClientBackend: WebClient @@ -46,19 +53,10 @@ class AgentService { .uri("/getTestBatches?agentId=$agentId") .retrieve() .bodyToMono() - .map { batch -> - if (batch.tests.isNotEmpty()) { - // fixme: do we still need suitesToArgs, since we have execFlags in save.toml? - NewJobResponse( - batch.tests, - batch.suitesToArgs.values.first() + - " --report-type json" + - " --result-output file" + - " " + batch.tests.joinToString(separator = " ") { it.filePath } - ) - } else { - log.info("Next test batch for agentId=$agentId is empty, setting it to wait") - WaitResponse + .map { batch -> batch.toHeartbeatResponse(agentId) } + .doOnSuccess { + if (it is NewJobResponse) { + updateAssignedAgent(agentId, it) } } @@ -130,7 +128,7 @@ class AgentService { fun markAgentsAndExecutionAsFinished(executionId: Long, finishedAgentIds: List): Mono = updateAgentStatusesWithDto( finishedAgentIds.map { agentId -> - AgentStatusDto(LocalDateTime.now(), AgentState.FINISHED, agentId) + AgentStatusDto(LocalDateTime.now(), AgentState.STOPPED_BY_ORCH, agentId) } ) .then( @@ -170,6 +168,7 @@ class AgentService { .retrieve() .bodyToMono() .map { (executionId, agentStatuses) -> + log.debug("For executionId=$executionId agent statuses are $agentStatuses") executionId to if (agentStatuses.areIdleOrFinished()) { // We assume, that all agents will eventually have one of these statuses. // Situations when agent gets stuck with a different status and for whatever reason is unable to update @@ -181,6 +180,50 @@ class AgentService { } } + /** + * Perform two operations in arbitrary order: assign `agentContainerId` agent to test executions + * and mark this agent as BUSY + * + * @param agentContainerId id of an agent that receives tests + * @param newJobResponse a heartbeat response with tests + */ + internal fun updateAssignedAgent(agentContainerId: String, newJobResponse: NewJobResponse) { + updateTestExecutionsWithAgent(agentContainerId, newJobResponse.tests).zipWith( + updateAgentStatusesWithDto(listOf( + AgentStatusDto(LocalDateTime.now(), AgentState.BUSY, agentContainerId) + )) + ) + .doOnSuccess { + log.debug("Agent $agentContainerId has been set as executor for tests ${newJobResponse.tests} and its status has been set to BUSY") + } + .subscribeOn(scheduler) + .subscribe() + } + + private fun updateTestExecutionsWithAgent(agentId: String, testDtos: List): Mono { + log.debug("Attempt to update test executions for tests=$testDtos for agent $agentId") + return webClientBackend.post() + .uri("/testExecution/assignAgent?agentContainerId=$agentId") + .bodyValue(testDtos) + .retrieve() + .toBodilessEntity() + } + + private fun TestBatch.toHeartbeatResponse(agentId: String) = + if (tests.isNotEmpty()) { + // fixme: do we still need suitesToArgs, since we have execFlags in save.toml? + NewJobResponse( + tests, + suitesToArgs.values.first() + + " --report-type json" + + " --result-output file" + + " " + tests.joinToString(separator = " ") { it.filePath } + ) + } else { + log.info("Next test batch for agentId=$agentId is empty, setting it to wait") + WaitResponse + } + private fun Collection.areIdleOrFinished() = all { it.state == AgentState.IDLE || it.state == AgentState.FINISHED } diff --git a/save-orchestrator/src/main/resources/application.properties b/save-orchestrator/src/main/resources/application.properties index d0fd109b24..5228aed68d 100644 --- a/save-orchestrator/src/main/resources/application.properties +++ b/save-orchestrator/src/main/resources/application.properties @@ -2,6 +2,7 @@ spring.profiles.default=dev orchestrator.backendUrl=http://backend:5000 orchestrator.executionLogs=/home/cnb/executionLogs/ orchestrator.testResources.basePath=/home/cnb/repositories +orchestrator.shutdownChecksIntervalMillis=5000 server.port = 5100 management.endpoints.web.exposure.include=health,info,prometheus orchestrator.docker.host=unix:///var/run/docker.sock diff --git a/save-orchestrator/src/main/resources/logback.xml b/save-orchestrator/src/main/resources/logback.xml index 9429c13fbb..47825a3160 100644 --- a/save-orchestrator/src/main/resources/logback.xml +++ b/save-orchestrator/src/main/resources/logback.xml @@ -5,6 +5,8 @@ + + diff --git a/save-orchestrator/src/test/kotlin/org/cqfn/save/orchestrator/controller/heartbeat/HeartbeatControllerTest.kt b/save-orchestrator/src/test/kotlin/org/cqfn/save/orchestrator/controller/heartbeat/HeartbeatControllerTest.kt index b7253846a9..be9e3928ba 100644 --- a/save-orchestrator/src/test/kotlin/org/cqfn/save/orchestrator/controller/heartbeat/HeartbeatControllerTest.kt +++ b/save-orchestrator/src/test/kotlin/org/cqfn/save/orchestrator/controller/heartbeat/HeartbeatControllerTest.kt @@ -145,15 +145,26 @@ class HeartbeatControllerTest { @Test fun `should shutdown idle agents when there are no tests left`() { whenever(dockerService.stopAgents(any())).thenReturn(true) + val agentStatusDtos = listOf( + AgentStatusDto(LocalDateTime.now(), AgentState.IDLE, "test-1"), + AgentStatusDto(LocalDateTime.now(), AgentState.IDLE, "test-2"), + ) testHeartbeat( - agentStatusDtos = listOf( - AgentStatusDto(LocalDateTime.now(), AgentState.IDLE, "test-1"), - AgentStatusDto(LocalDateTime.now(), AgentState.IDLE, "test-2"), - ), + agentStatusDtos = agentStatusDtos, heartbeat = Heartbeat("test-1", AgentState.IDLE, ExecutionProgress(100)), testBatch = TestBatch(emptyList(), emptyMap()), mockAgentStatuses = true, { + // /getAgentsStatusesForSameExecution after shutdownIntervalMillis + mockServer.enqueue( + MockResponse() + .setBody( + objectMapper.writeValueAsString( + AgentStatusesForExecution(0, agentStatusDtos) + ) + ) + .addHeader("Content-Type", "application/json") + ) // additional setup for marking stuff as FINISHED // /updateAgentStatuses mockServer.enqueue( @@ -193,16 +204,29 @@ class HeartbeatControllerTest { @Test fun `should shutdown agents even if there are some already FINISHED`() { + val agentStatusDtos = listOf( + AgentStatusDto(LocalDateTime.now(), AgentState.IDLE, "test-1"), + AgentStatusDto(LocalDateTime.now(), AgentState.IDLE, "test-2"), + AgentStatusDto(LocalDateTime.parse("2021-01-01T00:00:00"), AgentState.FINISHED, "test-1"), + AgentStatusDto(LocalDateTime.parse("2021-01-01T00:00:00"), AgentState.FINISHED, "test-2"), + ) testHeartbeat( - agentStatusDtos = listOf( - AgentStatusDto(LocalDateTime.now(), AgentState.IDLE, "test-1"), - AgentStatusDto(LocalDateTime.now(), AgentState.IDLE, "test-2"), - AgentStatusDto(LocalDateTime.parse("2021-01-01T00:00:00"), AgentState.FINISHED, "test-1"), - AgentStatusDto(LocalDateTime.parse("2021-01-01T00:00:00"), AgentState.FINISHED, "test-2"), - ), + agentStatusDtos = agentStatusDtos, heartbeat = Heartbeat("test-1", AgentState.IDLE, ExecutionProgress(100)), testBatch = TestBatch(emptyList(), emptyMap()), mockAgentStatuses = true, + { + // /getAgentsStatusesForSameExecution after shutdownIntervalMillis + mockServer.enqueue( + MockResponse() + .setBody( + objectMapper.writeValueAsString( + AgentStatusesForExecution(0, agentStatusDtos) + ) + ) + .addHeader("Content-Type", "application/json") + ) + } ) { verify(dockerService, times(1)).stopAgents(any()) } diff --git a/save-orchestrator/src/test/resources/application.properties b/save-orchestrator/src/test/resources/application.properties index a372d7870a..53048e0fad 100644 --- a/save-orchestrator/src/test/resources/application.properties +++ b/save-orchestrator/src/test/resources/application.properties @@ -1,6 +1,7 @@ orchestrator.backendUrl=http://backend:5000 orchestrator.executionLogs=/home/cnb/executionLogs/ orchestrator.testResources.basePath=/home/cnb/repositories +orchestrator.shutdownChecksIntervalMillis=100 server.port = 5100 management.endpoints.web.exposure.include=health,info,prometheus # use IP from WSL on windows (`ip a | grep eth0`), because runsc can't be installed on windows diff --git a/save-preprocessor/src/test/kotlin/org/cqfn/save/preprocessor/service/TestDiscoveringServiceTest.kt b/save-preprocessor/src/test/kotlin/org/cqfn/save/preprocessor/service/TestDiscoveringServiceTest.kt index 2b328b1d52..588720699e 100644 --- a/save-preprocessor/src/test/kotlin/org/cqfn/save/preprocessor/service/TestDiscoveringServiceTest.kt +++ b/save-preprocessor/src/test/kotlin/org/cqfn/save/preprocessor/service/TestDiscoveringServiceTest.kt @@ -90,7 +90,7 @@ class TestDiscoveringServiceTest { ) println("Discovered the following tests: $testDtos") - Assertions.assertEquals(13, testDtos.size) + Assertions.assertEquals(14, testDtos.size) Assertions.assertEquals(testDtos.size, testDtos.map { it.hash + it.filePath + it.testSuiteId }.distinct().size) { "Some tests have the same hash/filePath/testSuiteId combination in $testDtos" }