diff --git a/action-impl/src/test/resources/logback-test.xml b/action-impl/src/test/resources/logback-test.xml index 386eab5aa..6550f68ed 100644 --- a/action-impl/src/test/resources/logback-test.xml +++ b/action-impl/src/test/resources/logback-test.xml @@ -13,7 +13,7 @@ - + diff --git a/component/src/test/java/com/chutneytesting/component/execution/CampaignExecutionEngineTest.java b/component/src/test/java/com/chutneytesting/component/execution/CampaignExecutionEngineTest.java index 90d703b9b..594c1816b 100644 --- a/component/src/test/java/com/chutneytesting/component/execution/CampaignExecutionEngineTest.java +++ b/component/src/test/java/com/chutneytesting/component/execution/CampaignExecutionEngineTest.java @@ -30,6 +30,7 @@ import com.chutneytesting.server.core.domain.scenario.TestCaseMetadataImpl; import com.chutneytesting.server.core.domain.scenario.TestCaseRepository; import com.chutneytesting.server.core.domain.scenario.campaign.Campaign; +import com.chutneytesting.server.core.domain.scenario.campaign.CampaignBuilder; import com.fasterxml.jackson.databind.ObjectMapper; import java.time.LocalDateTime; import java.util.List; @@ -125,6 +126,17 @@ private ExecutableComposedTestCase createExecutableComposedTestCase() { } private Campaign createCampaign(Map dataSet, String dataSetId, TestCase... testCases) { - return new Campaign(generateId(), "...", null, stream(testCases).map(TestCase::id).collect(toList()), dataSet, "campaignEnv", false, false, dataSetId, null); + return new CampaignBuilder() + .setId(generateId()) + .setTitle("...") + .setDescription(null) + .setScenarioIds(stream(testCases).map(TestCase::id).collect(toList())) + .setExecutionParameters(dataSet) + .setEnvironment("campaignEnv") + .setParallelRun(false) + .setRetryAuto(false) + .setExternalDatasetId(dataSetId) + .setTags(null) + .build(); } } diff --git a/server-core/src/main/java/com/chutneytesting/server/core/domain/scenario/campaign/Campaign.java b/server-core/src/main/java/com/chutneytesting/server/core/domain/scenario/campaign/Campaign.java index d3d353553..f93f43477 100644 --- a/server-core/src/main/java/com/chutneytesting/server/core/domain/scenario/campaign/Campaign.java +++ b/server-core/src/main/java/com/chutneytesting/server/core/domain/scenario/campaign/Campaign.java @@ -60,4 +60,6 @@ private List initListNullOrEmpty(List list) { } return new ArrayList<>(); } + + } diff --git a/server-core/src/main/java/com/chutneytesting/server/core/domain/scenario/campaign/CampaignBuilder.java b/server-core/src/main/java/com/chutneytesting/server/core/domain/scenario/campaign/CampaignBuilder.java new file mode 100644 index 000000000..20bc6d13f --- /dev/null +++ b/server-core/src/main/java/com/chutneytesting/server/core/domain/scenario/campaign/CampaignBuilder.java @@ -0,0 +1,78 @@ +package com.chutneytesting.server.core.domain.scenario.campaign; + +import java.util.List; +import java.util.Map; + +public class CampaignBuilder { + private Long id; + private String title; + private String description; + private List scenarioIds; + private Map executionParameters; + private String environment; + private boolean parallelRun; + private boolean retryAuto; + private String externalDatasetId; + private List tags; + + public static CampaignBuilder builder() { + return new CampaignBuilder(); + } + + public CampaignBuilder(){ + + } + public CampaignBuilder setId(Long id) { + this.id = id; + return this; + } + + public CampaignBuilder setTitle(String title) { + this.title = title; + return this; + } + + public CampaignBuilder setDescription(String description) { + this.description = description; + return this; + } + + public CampaignBuilder setScenarioIds(List scenarioIds) { + this.scenarioIds = scenarioIds; + return this; + } + + public CampaignBuilder setExecutionParameters(Map executionParameters) { + this.executionParameters = executionParameters; + return this; + } + + public CampaignBuilder setEnvironment(String environment) { + this.environment = environment; + return this; + } + + public CampaignBuilder setParallelRun(boolean parallelRun) { + this.parallelRun = parallelRun; + return this; + } + + public CampaignBuilder setRetryAuto(boolean retryAuto) { + this.retryAuto = retryAuto; + return this; + } + + public CampaignBuilder setExternalDatasetId(String externalDatasetId) { + this.externalDatasetId = externalDatasetId; + return this; + } + + public CampaignBuilder setTags(List tags) { + this.tags = tags; + return this; + } + + public Campaign build() { + return new Campaign(id, title, description, scenarioIds, executionParameters, environment, parallelRun, retryAuto, externalDatasetId, tags); + } +} diff --git a/server-core/src/main/java/com/chutneytesting/server/core/domain/scenario/campaign/CampaignExecutionReport.java b/server-core/src/main/java/com/chutneytesting/server/core/domain/scenario/campaign/CampaignExecutionReport.java index 210d7deaa..e07784ad1 100644 --- a/server-core/src/main/java/com/chutneytesting/server/core/domain/scenario/campaign/CampaignExecutionReport.java +++ b/server-core/src/main/java/com/chutneytesting/server/core/domain/scenario/campaign/CampaignExecutionReport.java @@ -1,5 +1,6 @@ package com.chutneytesting.server.core.domain.scenario.campaign; +import static com.chutneytesting.server.core.domain.execution.report.ServerReportStatus.RUNNING; import static java.time.LocalDateTime.now; import static java.util.Collections.unmodifiableList; import static java.util.Optional.ofNullable; @@ -11,6 +12,7 @@ import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -49,7 +51,7 @@ public CampaignExecutionReport(Long executionId, this.scenarioExecutionReports = new ArrayList<>(); this.campaignName = campaignName; this.startDate = now(); - this.status = ServerReportStatus.RUNNING; + this.status = RUNNING; this.dataSetId = ofNullable(dataSetId); this.dataSetVersion = ofNullable(dataSetVersion); this.userId = userId; @@ -77,6 +79,39 @@ public CampaignExecutionReport(Long executionId, this.userId = userId; } + CampaignExecutionReport( + Long executionId, + Long campaignId, + String campaignName, + boolean partialExecution, + String executionEnvironment, + String userId, + Optional dataSetId, + Optional dataSetVersion, + LocalDateTime startDate, + ServerReportStatus status, + List scenarioExecutionReports + ) { + this.executionId = executionId; + this.campaignId = campaignId; + this.campaignName = campaignName; + this.partialExecution = partialExecution; + this.executionEnvironment = executionEnvironment; + this.dataSetId = dataSetId; + this.dataSetVersion = dataSetVersion; + this.userId = userId; + + if (scenarioExecutionReports == null) { + this.startDate = ofNullable(startDate).orElse(now()); + this.status = ofNullable(status).orElse(RUNNING); + this.scenarioExecutionReports = null; + } else { + this.startDate = findStartDate(scenarioExecutionReports); + this.status = findStatus(scenarioExecutionReports); + this.scenarioExecutionReports = scenarioExecutionReports; + } + } + public void initExecution(List testCases, String executionEnvironment, String userId) { testCases.forEach(testCase -> this.scenarioExecutionReports.add( @@ -108,7 +143,7 @@ public void startScenarioExecution(TestCase testCase, String executionEnvironmen .executionId(-1L) .testCaseTitle(testCase.metadata().title()) .time(now()) - .status(ServerReportStatus.RUNNING) + .status(RUNNING) .duration(0) .environment(executionEnvironment) .datasetId(dataSetId) @@ -167,8 +202,10 @@ private LocalDateTime findStartDate(List scenar } private ServerReportStatus findStatus(List scenarioExecutionReports) { - ServerReportStatus foundStatus = scenarioExecutionReports.stream() - .filter(Objects::nonNull) + + List filteredReports = filterRetry(scenarioExecutionReports); + + ServerReportStatus foundStatus = filteredReports.stream() .map(report -> report.execution) .filter(Objects::nonNull) .map(ExecutionHistory.ExecutionProperties::status) @@ -179,6 +216,30 @@ private ServerReportStatus findStatus(List scen return foundStatus; } + private List filterRetry(List scenarioExecutionReports) { + return scenarioExecutionReports.stream() + .filter(Objects::nonNull) + .collect(Collectors.groupingBy(s -> s.scenarioId)) + .values().stream() + .map(list -> list.size() == 1 ? list.get(0) : list.stream().max(Comparator.comparing(objet -> objet.execution.time())).get()) + .toList(); + } + + public CampaignExecutionReport withoutRetries() { + return CampaignExecutionReportBuilder.builder() + .setExecutionId(executionId) + .setCampaignId(campaignId) + .setCampaignName(campaignName) + .setExecutionEnvironment(executionEnvironment) + .setDataSetId(dataSetId.orElse(null)) + .setDataSetVersion(dataSetVersion.orElse(null)) + .setUserId(userId) + .setStartDate(startDate) + .setStatus(status) + .setScenarioExecutionReport(filterRetry(scenarioExecutionReports)) + .build(); + } + @Override public String toString() { return "CampaignExecutionReport{" + @@ -198,6 +259,4 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(executionId); } - - } diff --git a/server-core/src/main/java/com/chutneytesting/server/core/domain/scenario/campaign/CampaignExecutionReportBuilder.java b/server-core/src/main/java/com/chutneytesting/server/core/domain/scenario/campaign/CampaignExecutionReportBuilder.java new file mode 100644 index 000000000..0d40ec77a --- /dev/null +++ b/server-core/src/main/java/com/chutneytesting/server/core/domain/scenario/campaign/CampaignExecutionReportBuilder.java @@ -0,0 +1,109 @@ +package com.chutneytesting.server.core.domain.scenario.campaign; + +import static java.util.Optional.ofNullable; + +import com.chutneytesting.server.core.domain.execution.report.ServerReportStatus; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +public class CampaignExecutionReportBuilder { + // Mandatory fields + private Long executionId; + private String campaignName; + private boolean partialExecution; + private String executionEnvironment; + private String dataSetId; + private Integer dataSetVersion; + private String userId; + + // Optional fields + private List scenarioExecutionReports = new ArrayList<>(); + private Long campaignId; + private LocalDateTime startDate; + private ServerReportStatus status; + + public static CampaignExecutionReportBuilder builder() { + return new CampaignExecutionReportBuilder(); + } + + private CampaignExecutionReportBuilder() { + + } + + public CampaignExecutionReportBuilder setExecutionId(Long executionId) { + this.executionId = executionId; + return this; + } + + public CampaignExecutionReportBuilder setCampaignName(String campaignName) { + this.campaignName = campaignName; + return this; + } + + public CampaignExecutionReportBuilder setPartialExecution(boolean partialExecution) { + this.partialExecution = partialExecution; + return this; + } + + public CampaignExecutionReportBuilder setExecutionEnvironment(String executionEnvironment) { + this.executionEnvironment = executionEnvironment; + return this; + } + + public CampaignExecutionReportBuilder setStartDate(LocalDateTime startDate) { + this.startDate = startDate; + return this; + } + + public CampaignExecutionReportBuilder setStatus(ServerReportStatus status) { + this.status = status; + return this; + } + + public CampaignExecutionReportBuilder setDataSetId(String dataSetId) { + this.dataSetId = dataSetId; + return this; + } + + public CampaignExecutionReportBuilder setDataSetVersion(Integer dataSetVersion) { + this.dataSetVersion = dataSetVersion; + return this; + } + + public CampaignExecutionReportBuilder setUserId(String userId) { + this.userId = userId; + return this; + } + + public CampaignExecutionReportBuilder addScenarioExecutionReport(ScenarioExecutionReportCampaign scenarioExecutionReport) { + this.scenarioExecutionReports.add(scenarioExecutionReport); + return this; + } + + public CampaignExecutionReportBuilder setScenarioExecutionReport(List scenarioExecutionsReports) { + this.scenarioExecutionReports = new ArrayList<>(scenarioExecutionsReports); + return this; + } + + public CampaignExecutionReportBuilder setCampaignId(Long campaignId) { + this.campaignId = campaignId; + return this; + } + + public CampaignExecutionReport build() { + return new CampaignExecutionReport( + executionId, + campaignId, + campaignName, + partialExecution, + executionEnvironment, + userId, + ofNullable(dataSetId), + ofNullable(dataSetVersion), + startDate, + status, + scenarioExecutionReports + ); + } +} diff --git a/server/src/main/java/com/chutneytesting/ServerConfiguration.java b/server/src/main/java/com/chutneytesting/ServerConfiguration.java index f27d556d7..e8a701a53 100644 --- a/server/src/main/java/com/chutneytesting/ServerConfiguration.java +++ b/server/src/main/java/com/chutneytesting/ServerConfiguration.java @@ -5,6 +5,7 @@ import com.chutneytesting.action.api.EmbeddedActionEngine; import com.chutneytesting.campaign.domain.CampaignExecutionRepository; import com.chutneytesting.campaign.domain.CampaignRepository; +import com.chutneytesting.campaign.domain.CampaignService; import com.chutneytesting.dataset.domain.DataSetRepository; import com.chutneytesting.design.domain.editionlock.TestCaseEditions; import com.chutneytesting.design.domain.editionlock.TestCaseEditionsService; @@ -278,4 +279,9 @@ EmbeddedActionEngine embeddedActionEngine(ExecutionConfiguration executionConfig Clock clock() { return Clock.systemDefaultZone(); } + + @Bean + CampaignService campaignService(CampaignRepository campaignRepository) { + return new CampaignService(campaignRepository); + } } diff --git a/server/src/main/java/com/chutneytesting/campaign/api/CampaignController.java b/server/src/main/java/com/chutneytesting/campaign/api/CampaignController.java index f6ca8a2a5..512616a6a 100644 --- a/server/src/main/java/com/chutneytesting/campaign/api/CampaignController.java +++ b/server/src/main/java/com/chutneytesting/campaign/api/CampaignController.java @@ -9,6 +9,7 @@ import com.chutneytesting.campaign.api.dto.CampaignExecutionReportMapper; import com.chutneytesting.campaign.api.dto.CampaignMapper; import com.chutneytesting.campaign.domain.CampaignRepository; +import com.chutneytesting.campaign.domain.CampaignService; import com.chutneytesting.execution.domain.campaign.CampaignExecutionEngine; import com.chutneytesting.scenario.api.raw.dto.TestCaseIndexDto; import com.chutneytesting.scenario.infra.TestCaseRepositoryAggregator; @@ -39,14 +40,17 @@ public class CampaignController { private final TestCaseRepositoryAggregator repositoryAggregator; private final CampaignRepository campaignRepository; private final CampaignExecutionEngine campaignExecutionEngine; + private final CampaignService campaignService; public CampaignController(TestCaseRepositoryAggregator repositoryAggregator, CampaignRepository campaignRepository, - CampaignExecutionEngine campaignExecutionEngine) { + CampaignExecutionEngine campaignExecutionEngine, + CampaignService campaignService) { this.repositoryAggregator = repositoryAggregator; this.campaignRepository = campaignRepository; this.campaignExecutionEngine = campaignExecutionEngine; + this.campaignService = campaignService; } @PreAuthorize("hasAuthority('CAMPAIGN_WRITE')") @@ -71,7 +75,7 @@ public boolean deleteCampaign(@PathVariable("campaignId") Long campaignId) { @GetMapping(path = "/{campaignId}", produces = MediaType.APPLICATION_JSON_VALUE) public CampaignDto getCampaignById(@PathVariable("campaignId") Long campaignId) { Campaign campaign = campaignRepository.findById(campaignId); - List reports = campaignRepository.findExecutionsById(campaignId); + List reports = campaignService.findExecutionsById(campaignId); campaignExecutionEngine.currentExecution(campaignId) .ifPresent(report -> addCurrentExecution(reports, report)); return toDto(campaign, reports); diff --git a/server/src/main/java/com/chutneytesting/campaign/domain/CampaignService.java b/server/src/main/java/com/chutneytesting/campaign/domain/CampaignService.java new file mode 100644 index 000000000..ac99832e1 --- /dev/null +++ b/server/src/main/java/com/chutneytesting/campaign/domain/CampaignService.java @@ -0,0 +1,26 @@ +package com.chutneytesting.campaign.domain; + +import static java.util.stream.Collectors.toList; + +import com.chutneytesting.server.core.domain.scenario.campaign.CampaignExecutionReport; +import java.util.List; + +public class CampaignService { + + private final CampaignRepository campaignRepository; + + public CampaignService(CampaignRepository campaignRepository) { + this.campaignRepository = campaignRepository; + } + + public CampaignExecutionReport findByExecutionId(Long campaignExecutionId) { + CampaignExecutionReport report = campaignRepository.findByExecutionId(campaignExecutionId); + return report.withoutRetries(); + } + + public List findExecutionsById(Long campaignId) { + return campaignRepository.findExecutionsById(campaignId).stream() + .map(CampaignExecutionReport::withoutRetries) + .collect(toList()); + } +} diff --git a/server/src/main/java/com/chutneytesting/campaign/infra/CampaignExecutionDBRepository.java b/server/src/main/java/com/chutneytesting/campaign/infra/CampaignExecutionDBRepository.java index 8e0ba6a7b..22f1335a8 100644 --- a/server/src/main/java/com/chutneytesting/campaign/infra/CampaignExecutionDBRepository.java +++ b/server/src/main/java/com/chutneytesting/campaign/infra/CampaignExecutionDBRepository.java @@ -2,7 +2,7 @@ import com.chutneytesting.campaign.domain.CampaignExecutionRepository; import com.chutneytesting.campaign.domain.CampaignNotFoundException; -import com.chutneytesting.campaign.infra.jpa.Campaign; +import com.chutneytesting.campaign.infra.jpa.CampaignEntity; import com.chutneytesting.campaign.infra.jpa.CampaignExecution; import com.chutneytesting.execution.domain.campaign.CampaignExecutionNotFoundException; import com.chutneytesting.execution.infra.storage.DatabaseExecutionJpaRepository; @@ -45,7 +45,7 @@ public CampaignExecutionDBRepository( @Transactional(readOnly = true) public List findExecutionHistory(Long campaignId) { - Campaign campaign = campaignJpaRepository.findById(campaignId).orElseThrow(() -> new CampaignNotFoundException(campaignId)); + CampaignEntity campaign = campaignJpaRepository.findById(campaignId).orElseThrow(() -> new CampaignNotFoundException(campaignId)); return campaignExecutionJpaRepository.findFirst20ByCampaignIdOrderByIdDesc(campaignId).stream() .map(ce -> toDomain(campaign, ce, false)) .filter(Objects::nonNull) @@ -85,7 +85,7 @@ private CampaignExecutionReport toDomain(CampaignExecution campaignExecution, bo return toDomain(campaignJpaRepository.findById(campaignExecution.campaignId()).get(), campaignExecution, withRunning); } - private CampaignExecutionReport toDomain(Campaign campaign, CampaignExecution campaignExecution, boolean withRunning) { + private CampaignExecutionReport toDomain(CampaignEntity campaign, CampaignExecution campaignExecution, boolean withRunning) { if (!withRunning && isCampaignExecutionRunning(campaignExecution)) return null; return campaignExecution.toDomain(campaign, isCampaignExecutionRunning(campaignExecution), this::title); } diff --git a/server/src/main/java/com/chutneytesting/campaign/infra/CampaignJpaRepository.java b/server/src/main/java/com/chutneytesting/campaign/infra/CampaignJpaRepository.java index d3d2dd6f0..a2d5c1c0c 100644 --- a/server/src/main/java/com/chutneytesting/campaign/infra/CampaignJpaRepository.java +++ b/server/src/main/java/com/chutneytesting/campaign/infra/CampaignJpaRepository.java @@ -1,8 +1,8 @@ package com.chutneytesting.campaign.infra; -import com.chutneytesting.campaign.infra.jpa.Campaign; +import com.chutneytesting.campaign.infra.jpa.CampaignEntity; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; -public interface CampaignJpaRepository extends CrudRepository, JpaSpecificationExecutor { +public interface CampaignJpaRepository extends CrudRepository, JpaSpecificationExecutor { } diff --git a/server/src/main/java/com/chutneytesting/campaign/infra/DatabaseCampaignRepository.java b/server/src/main/java/com/chutneytesting/campaign/infra/DatabaseCampaignRepository.java index ad3174c36..d1cbf8b23 100644 --- a/server/src/main/java/com/chutneytesting/campaign/infra/DatabaseCampaignRepository.java +++ b/server/src/main/java/com/chutneytesting/campaign/infra/DatabaseCampaignRepository.java @@ -6,6 +6,7 @@ import com.chutneytesting.campaign.domain.CampaignNotFoundException; import com.chutneytesting.campaign.domain.CampaignRepository; +import com.chutneytesting.campaign.infra.jpa.CampaignEntity; import com.chutneytesting.campaign.infra.jpa.CampaignScenario; import com.chutneytesting.server.core.domain.scenario.campaign.Campaign; import com.chutneytesting.server.core.domain.scenario.campaign.CampaignExecutionReport; @@ -35,13 +36,13 @@ public DatabaseCampaignRepository(CampaignJpaRepository campaignJpaRepository, @Override public Campaign createOrUpdate(Campaign campaign) { - com.chutneytesting.campaign.infra.jpa.Campaign campaignJpa = - campaignJpaRepository.save(com.chutneytesting.campaign.infra.jpa.Campaign.fromDomain(campaign, lastCampaignVersion(campaign.id))); + CampaignEntity campaignJpa = + campaignJpaRepository.save(CampaignEntity.fromDomain(campaign, lastCampaignVersion(campaign.id))); return campaignJpa.toDomain(); } private Integer lastCampaignVersion(Long id) { - return ofNullable(id).flatMap(campaignJpaRepository::findById).map(com.chutneytesting.campaign.infra.jpa.Campaign::version).orElse(null); + return ofNullable(id).flatMap(campaignJpaRepository::findById).map(CampaignEntity::version).orElse(null); } @Override @@ -63,7 +64,7 @@ public boolean removeById(Long id) { @Transactional(readOnly = true) public Campaign findById(Long campaignId) throws CampaignNotFoundException { return campaignJpaRepository.findById(campaignId) - .map(com.chutneytesting.campaign.infra.jpa.Campaign::toDomain) + .map(CampaignEntity::toDomain) .orElseThrow(() -> new CampaignNotFoundException(campaignId)); } @@ -73,7 +74,7 @@ public List findByName(String campaignName) { return campaignJpaRepository.findAll((root, query, criteriaBuilder) -> criteriaBuilder.like(criteriaBuilder.lower(root.get("title")), campaignName.toLowerCase())) .stream() - .map(com.chutneytesting.campaign.infra.jpa.Campaign::toDomain) + .map(CampaignEntity::toDomain) .toList(); } @@ -103,7 +104,7 @@ public Long newCampaignExecution(Long campaignId) { @Transactional(readOnly = true) public List findAll() { return StreamSupport.stream(campaignJpaRepository.findAll().spliterator(), false) - .map(com.chutneytesting.campaign.infra.jpa.Campaign::toDomain) + .map(CampaignEntity::toDomain) .toList(); } @@ -122,7 +123,7 @@ public List findCampaignsByScenarioId(String scenarioId) { return campaignScenarioJpaRepository.findAllByScenarioId(scenarioId).stream() .map(CampaignScenario::campaign) - .map(com.chutneytesting.campaign.infra.jpa.Campaign::toDomain) + .map(CampaignEntity::toDomain) .toList(); } diff --git a/server/src/main/java/com/chutneytesting/campaign/infra/jpa/Campaign.java b/server/src/main/java/com/chutneytesting/campaign/infra/jpa/CampaignEntity.java similarity index 87% rename from server/src/main/java/com/chutneytesting/campaign/infra/jpa/Campaign.java rename to server/src/main/java/com/chutneytesting/campaign/infra/jpa/CampaignEntity.java index de9487c8e..27ee39254 100644 --- a/server/src/main/java/com/chutneytesting/campaign/infra/jpa/Campaign.java +++ b/server/src/main/java/com/chutneytesting/campaign/infra/jpa/CampaignEntity.java @@ -4,6 +4,7 @@ import static java.util.stream.Collectors.toMap; import com.chutneytesting.scenario.infra.raw.TagListMapper; +import com.chutneytesting.server.core.domain.scenario.campaign.Campaign; import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -21,7 +22,7 @@ import java.util.Set; @Entity(name = "CAMPAIGN") -public class Campaign implements Serializable { +public class CampaignEntity implements Serializable { @Id @Column(name = "ID") @@ -60,18 +61,18 @@ public class Campaign implements Serializable { @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "campaign") private Set parameters; - public Campaign() { + public CampaignEntity() { } - public Campaign(String title) { + public CampaignEntity(String title) { this(null, title, "", null, false, false, null, null, null, null, null); } - public Campaign(String title, List scenarios) { + public CampaignEntity(String title, List scenarios) { this(null, title, "", null, false, false, null, null, null, scenarios, null); } - public Campaign(Long id, String title, String description, String environment, boolean parallelRun, boolean retryAuto, String datasetId, List tags, Integer version, List campaignScenarios, Set parameters) { + public CampaignEntity(Long id, String title, String description, String environment, boolean parallelRun, boolean retryAuto, String datasetId, List tags, Integer version, List campaignScenarios, Set parameters) { this.id = id; this.title = title; this.description = description; @@ -85,8 +86,8 @@ public Campaign(Long id, String title, String description, String environment, b fromCampaignParameters(parameters); } - public static Campaign fromDomain(com.chutneytesting.server.core.domain.scenario.campaign.Campaign campaign, Integer version) { - return new Campaign( + public static CampaignEntity fromDomain(Campaign campaign, Integer version) { + return new CampaignEntity( campaign.id, campaign.title, campaign.description, @@ -119,8 +120,8 @@ private void fromCampaignParameters(Set campaignParameters) { } } - public com.chutneytesting.server.core.domain.scenario.campaign.Campaign toDomain() { - return new com.chutneytesting.server.core.domain.scenario.campaign.Campaign( + public Campaign toDomain() { + return new Campaign( id, title, description, diff --git a/server/src/main/java/com/chutneytesting/campaign/infra/jpa/CampaignExecution.java b/server/src/main/java/com/chutneytesting/campaign/infra/jpa/CampaignExecution.java index dd89dea55..7bd05636e 100644 --- a/server/src/main/java/com/chutneytesting/campaign/infra/jpa/CampaignExecution.java +++ b/server/src/main/java/com/chutneytesting/campaign/infra/jpa/CampaignExecution.java @@ -101,11 +101,11 @@ public void updateFromDomain(CampaignExecutionReport report, Iterable titleSupplier) { + public CampaignExecutionReport toDomain(CampaignEntity campaign, boolean isRunning, Function titleSupplier) { return toDomain(campaign, true, isRunning, titleSupplier); } - public CampaignExecutionReport toDomain(Campaign campaign, boolean withScenariosExecutions, boolean isRunning, Function scenarioTitleSupplier) { + public CampaignExecutionReport toDomain(CampaignEntity campaign, boolean withScenariosExecutions, boolean isRunning, Function scenarioTitleSupplier) { List scenarioExecutionReportCampaigns = emptyList(); if (withScenariosExecutions) { if (isRunning) { diff --git a/server/src/main/java/com/chutneytesting/campaign/infra/jpa/CampaignParameter.java b/server/src/main/java/com/chutneytesting/campaign/infra/jpa/CampaignParameter.java index aebf806dd..7809deb60 100644 --- a/server/src/main/java/com/chutneytesting/campaign/infra/jpa/CampaignParameter.java +++ b/server/src/main/java/com/chutneytesting/campaign/infra/jpa/CampaignParameter.java @@ -22,7 +22,7 @@ public class CampaignParameter { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "CAMPAIGN_ID") - private Campaign campaign; + private CampaignEntity campaign; @Column(name = "PARAMETER") private String parameter; @@ -37,7 +37,7 @@ public CampaignParameter(String parameter, String value) { this(null, parameter, value); } - public CampaignParameter(Campaign campaign, String parameter, String value) { + public CampaignParameter(CampaignEntity campaign, String parameter, String value) { this.campaign = campaign; this.parameter = parameter; this.value = value; @@ -51,7 +51,7 @@ public String value() { return value; } - public void forCampaign(Campaign campaign) { + public void forCampaign(CampaignEntity campaign) { this.campaign = campaign; } diff --git a/server/src/main/java/com/chutneytesting/campaign/infra/jpa/CampaignScenario.java b/server/src/main/java/com/chutneytesting/campaign/infra/jpa/CampaignScenario.java index 61b27c5ac..c47ebaa39 100644 --- a/server/src/main/java/com/chutneytesting/campaign/infra/jpa/CampaignScenario.java +++ b/server/src/main/java/com/chutneytesting/campaign/infra/jpa/CampaignScenario.java @@ -21,7 +21,7 @@ public class CampaignScenario { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "CAMPAIGN_ID") - private Campaign campaign; + private CampaignEntity campaign; @Column(name = "SCENARIO_ID") private String scenarioId; @@ -36,7 +36,7 @@ public CampaignScenario(String scenarioId, Integer rank) { this(null, scenarioId, rank); } - public CampaignScenario(Campaign campaign, String scenarioId, Integer rank) { + public CampaignScenario(CampaignEntity campaign, String scenarioId, Integer rank) { this.campaign = campaign; this.scenarioId = scenarioId; this.rank = rank; @@ -46,7 +46,7 @@ public String scenarioId() { return scenarioId; } - public Campaign campaign() { + public CampaignEntity campaign() { return campaign; } @@ -54,7 +54,7 @@ public Integer rank() { return rank; } - public void forCampaign(Campaign campaign) { + public void forCampaign(CampaignEntity campaign) { this.campaign = campaign; } diff --git a/server/src/main/java/com/chutneytesting/execution/api/CampaignExecutionUiController.java b/server/src/main/java/com/chutneytesting/execution/api/CampaignExecutionUiController.java index 1e6eb96eb..eb51eeb63 100644 --- a/server/src/main/java/com/chutneytesting/execution/api/CampaignExecutionUiController.java +++ b/server/src/main/java/com/chutneytesting/execution/api/CampaignExecutionUiController.java @@ -5,6 +5,7 @@ import com.chutneytesting.campaign.api.dto.CampaignExecutionReportDto; import com.chutneytesting.campaign.api.dto.CampaignExecutionReportMapper; import com.chutneytesting.campaign.domain.CampaignRepository; +import com.chutneytesting.campaign.domain.CampaignService; import com.chutneytesting.execution.api.report.surefire.SurefireCampaignExecutionReportBuilder; import com.chutneytesting.execution.api.report.surefire.SurefireScenarioExecutionReportBuilder; import com.chutneytesting.execution.domain.campaign.CampaignExecutionEngine; @@ -41,12 +42,20 @@ public class CampaignExecutionUiController { private final SurefireCampaignExecutionReportBuilder surefireCampaignExecutionReportBuilder; private final CampaignRepository campaignRepository; private final SpringUserService userService; + private final CampaignService campaignService; - public CampaignExecutionUiController(CampaignExecutionEngine campaignExecutionEngine, SurefireScenarioExecutionReportBuilder surefireScenarioExecutionReportBuilder, CampaignRepository campaignRepository, SpringUserService userService) { + public CampaignExecutionUiController( + CampaignExecutionEngine campaignExecutionEngine, + SurefireScenarioExecutionReportBuilder surefireScenarioExecutionReportBuilder, + CampaignRepository campaignRepository, + SpringUserService userService, + CampaignService campaignService + ) { this.campaignExecutionEngine = campaignExecutionEngine; this.surefireCampaignExecutionReportBuilder = new SurefireCampaignExecutionReportBuilder(surefireScenarioExecutionReportBuilder); this.campaignRepository = campaignRepository; this.userService = userService; + this.campaignService = campaignService; } @PreAuthorize("hasAuthority('CAMPAIGN_EXECUTE')") @@ -67,7 +76,7 @@ public List executeCampaignByName(@PathVariable("cam @PreAuthorize("hasAuthority('CAMPAIGN_EXECUTE')") @PostMapping(path = {"/replay/{campaignExecutionId}"}, produces = MediaType.APPLICATION_JSON_VALUE) public CampaignExecutionReportDto replayFailedScenario(@PathVariable("campaignExecutionId") Long campaignExecutionId) { - CampaignExecutionReport campaignExecutionReport = campaignRepository.findByExecutionId(campaignExecutionId); + CampaignExecutionReport campaignExecutionReport = campaignService.findByExecutionId(campaignExecutionId); String userId = userService.currentUser().getId(); List failedIds = campaignExecutionReport.scenarioExecutionReports().stream().filter(s -> !ServerReportStatus.SUCCESS.equals(s.execution.status())).map(s -> s.scenarioId).collect(Collectors.toList()); Campaign campaign = campaignRepository.findById(campaignExecutionReport.campaignId); diff --git a/server/src/test/java/changelog/LiquibaseChangelogTest.java b/server/src/test/java/changelog/LiquibaseChangelogTest.java index 498cace12..a7ccce970 100644 --- a/server/src/test/java/changelog/LiquibaseChangelogTest.java +++ b/server/src/test/java/changelog/LiquibaseChangelogTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import com.chutneytesting.campaign.infra.jpa.Campaign; +import com.chutneytesting.campaign.infra.jpa.CampaignEntity; import com.chutneytesting.campaign.infra.jpa.CampaignExecution; import com.chutneytesting.campaign.infra.jpa.CampaignParameter; import com.chutneytesting.execution.infra.storage.jpa.ScenarioExecution; @@ -114,11 +114,11 @@ void set_scenario_sequence_value_after_migration() { @Test @DisplayName("Set campaign sequences correctly") void set_campaign_sequence_value_after_migration() { - Campaign campaign = transactionTemplate.execute(status -> { + CampaignEntity campaign = transactionTemplate.execute(status -> { Set parameters = Set.of( new CampaignParameter("param1", "val1") ); - Campaign c = new Campaign(null, "title", "", null, false, false, null, null, null, null, parameters); + CampaignEntity c = new CampaignEntity(null, "title", "", null, false, false, null, null, null, null, parameters); entityManager.persist(c); return c; }); diff --git a/server/src/test/java/com/chutneytesting/campaign/api/CampaignControllerTest.java b/server/src/test/java/com/chutneytesting/campaign/api/CampaignControllerTest.java index 357336bc1..5380f7e42 100644 --- a/server/src/test/java/com/chutneytesting/campaign/api/CampaignControllerTest.java +++ b/server/src/test/java/com/chutneytesting/campaign/api/CampaignControllerTest.java @@ -18,6 +18,7 @@ import com.chutneytesting.WebConfiguration; import com.chutneytesting.campaign.api.dto.CampaignDto; import com.chutneytesting.campaign.api.dto.CampaignExecutionReportDto; +import com.chutneytesting.campaign.domain.CampaignService; import com.chutneytesting.campaign.infra.FakeCampaignRepository; import com.chutneytesting.execution.domain.campaign.CampaignExecutionEngine; import com.chutneytesting.scenario.api.raw.dto.ImmutableTestCaseIndexDto; @@ -71,7 +72,7 @@ public void setUp() throws Exception { resultExtractor = new ResultExtractor(); repositoryAggregator = mock(TestCaseRepositoryAggregator.class); - CampaignController campaignController = new CampaignController(repositoryAggregator, repository, campaignExecutionEngine); + CampaignController campaignController = new CampaignController(repositoryAggregator, repository, campaignExecutionEngine, new CampaignService(repository)); mockMvc = MockMvcBuilders.standaloneSetup(campaignController) .setControllerAdvice(new RestExceptionHandler(Mockito.mock(ChutneyMetrics.class))) .build(); @@ -266,6 +267,7 @@ public void should_retrieve_executions_and_current_execution_when_found_campaign repository.saveReport(existingCampaign.getId(), report3); repository.saveReport(existingCampaign.getId(), report4); + // When execute(MockMvcRequestBuilders.get(urlTemplate + existingCampaign.getId())) .andExpect(MockMvcResultMatchers.status().isOk()); diff --git a/server/src/test/java/com/chutneytesting/campaign/domain/CampaignExecutionReportTest.java b/server/src/test/java/com/chutneytesting/campaign/domain/CampaignExecutionReportTest.java index c6fdb964c..f8979b106 100644 --- a/server/src/test/java/com/chutneytesting/campaign/domain/CampaignExecutionReportTest.java +++ b/server/src/test/java/com/chutneytesting/campaign/domain/CampaignExecutionReportTest.java @@ -1,5 +1,7 @@ package com.chutneytesting.campaign.domain; +import static com.chutneytesting.server.core.domain.execution.report.ServerReportStatus.FAILURE; +import static com.chutneytesting.server.core.domain.execution.report.ServerReportStatus.SUCCESS; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; @@ -9,10 +11,12 @@ import com.chutneytesting.scenario.domain.gwt.GwtTestCase; import com.chutneytesting.server.core.domain.execution.history.ExecutionHistory; +import com.chutneytesting.server.core.domain.execution.history.ImmutableExecutionHistory; import com.chutneytesting.server.core.domain.execution.report.ServerReportStatus; import com.chutneytesting.server.core.domain.scenario.TestCase; import com.chutneytesting.server.core.domain.scenario.TestCaseMetadataImpl; import com.chutneytesting.server.core.domain.scenario.campaign.CampaignExecutionReport; +import com.chutneytesting.server.core.domain.scenario.campaign.CampaignExecutionReportBuilder; import com.chutneytesting.server.core.domain.scenario.campaign.ScenarioExecutionReportCampaign; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; @@ -32,11 +36,11 @@ public void should_take_the_earliest_scenario_start_date_as_start_date() { ExecutionHistory.ExecutionSummary execution_5mn = mock(ExecutionHistory.ExecutionSummary.class); when(execution_5mn.time()).thenReturn(LocalDateTime.now().minusMinutes(5)); - ScenarioExecutionReportCampaign scenarioReport_5mn = new ScenarioExecutionReportCampaign("1", "...", execution_5mn); + ScenarioExecutionReportCampaign scenarioReport_5mn = new ScenarioExecutionReportCampaign("2", "...", execution_5mn); ExecutionHistory.ExecutionSummary execution_2mn = mock(ExecutionHistory.ExecutionSummary.class); when(execution_2mn.time()).thenReturn(LocalDateTime.now().minusMinutes(2)); - ScenarioExecutionReportCampaign scenarioReport_2mn = new ScenarioExecutionReportCampaign("1", "...", execution_2mn); + ScenarioExecutionReportCampaign scenarioReport_2mn = new ScenarioExecutionReportCampaign("3", "...", execution_2mn); // When CampaignExecutionReport campaignReport = new CampaignExecutionReport(1L, 1L, Lists.list(execution_noTime, scenarioReport_5mn, scenarioReport_2mn), "...", false, "", null, null, ""); @@ -49,7 +53,7 @@ public void should_take_the_earliest_scenario_start_date_as_start_date() { public void should_set_start_date_as_min_possible_date_when_no_scenario_times_are_available() { // Given ScenarioExecutionReportCampaign scenarioReport1 = new ScenarioExecutionReportCampaign("1", "...", mock(ExecutionHistory.ExecutionSummary.class)); - ScenarioExecutionReportCampaign scenarioReport2 = new ScenarioExecutionReportCampaign("1", "...", mock(ExecutionHistory.ExecutionSummary.class)); + ScenarioExecutionReportCampaign scenarioReport2 = new ScenarioExecutionReportCampaign("2", "...", mock(ExecutionHistory.ExecutionSummary.class)); // When CampaignExecutionReport campaignReport = new CampaignExecutionReport(1L, 1L, Lists.list(scenarioReport1, scenarioReport2), "...", false, "", null, null, ""); @@ -83,15 +87,15 @@ public void should_set_to_worst_status_when_instantiate_with_scenario_reports() ExecutionHistory.ExecutionSummary execution_SUCESS = mock(ExecutionHistory.ExecutionSummary.class); when(execution_SUCESS.status()).thenReturn(ServerReportStatus.SUCCESS); - ScenarioExecutionReportCampaign scenarioReport_SUCCESS = new ScenarioExecutionReportCampaign("1", "...", execution_SUCESS); + ScenarioExecutionReportCampaign scenarioReport_SUCCESS = new ScenarioExecutionReportCampaign("2", "...", execution_SUCESS); ExecutionHistory.ExecutionSummary execution_FAILURE = mock(ExecutionHistory.ExecutionSummary.class); - when(execution_FAILURE.status()).thenReturn(ServerReportStatus.FAILURE); - ScenarioExecutionReportCampaign scenarioReport_FAILURE = new ScenarioExecutionReportCampaign("1", "...", execution_FAILURE); + when(execution_FAILURE.status()).thenReturn(FAILURE); + ScenarioExecutionReportCampaign scenarioReport_FAILURE = new ScenarioExecutionReportCampaign("3", "...", execution_FAILURE); // When CampaignExecutionReport campaignReport = new CampaignExecutionReport(1L, 1L, Lists.list(execution_noStatus, scenarioReport_SUCCESS, scenarioReport_FAILURE), "...", false, "", null, null, ""); // Then - assertThat(campaignReport.status()).isEqualTo(ServerReportStatus.FAILURE); + assertThat(campaignReport.status()).isEqualTo(FAILURE); } @Test @@ -157,14 +161,14 @@ public void should_compute_status_from_scenarios_when_end_campaign_execution() { // Given CampaignExecutionReport campaignReport = new CampaignExecutionReport(1L, "...", false, "", null, null, ""); addScenarioExecutions(campaignReport, "1", "title1", ServerReportStatus.SUCCESS); - addScenarioExecutions(campaignReport, "2", "title2", ServerReportStatus.FAILURE); + addScenarioExecutions(campaignReport, "2", "title2", FAILURE); // When campaignReport.endCampaignExecution(); // Then assertThat(campaignReport.scenarioExecutionReports()).hasSize(2); - assertThat(campaignReport.status()).isEqualTo(ServerReportStatus.FAILURE); + assertThat(campaignReport.status()).isEqualTo(FAILURE); } @Test @@ -182,6 +186,44 @@ public void should_calculate_stop_final_status_when_having_not_executed_scenario assertThat(campaignReport.status()).isEqualTo(ServerReportStatus.STOPPED); } + /** + * + */ + @Test + public void should_calculate_filter_retry_scenario_in_status_calculation() { + // Given + String scenarioId = "1"; + ExecutionHistory.ExecutionSummary firstExecution = ImmutableExecutionHistory.ExecutionSummary.builder() + .executionId(1L) + .testCaseTitle("") + .time(LocalDateTime.now().minusMinutes(1l)) + .duration(0l) + .environment("") + .user("") + .status(FAILURE) + .build(); + ScenarioExecutionReportCampaign firstReport = new ScenarioExecutionReportCampaign(scenarioId, "", firstExecution); + ExecutionHistory.ExecutionSummary retryExecution = ImmutableExecutionHistory.ExecutionSummary.builder() + .executionId(2L) + .testCaseTitle("") + .time(LocalDateTime.now()) + .duration(0l) + .environment("") + .user("") + .status(SUCCESS) + .build(); + ScenarioExecutionReportCampaign retryReport = new ScenarioExecutionReportCampaign(scenarioId, "", retryExecution); + CampaignExecutionReport campaignReport = CampaignExecutionReportBuilder.builder() + .addScenarioExecutionReport(firstReport) + .addScenarioExecutionReport(retryReport) + .build(); + // When + ServerReportStatus status = campaignReport.status(); + + // Then + assertThat(status).isEqualTo(SUCCESS); + } + @Test public void should_compute_duration_for_one_scenario_execution() { LocalDateTime now = LocalDateTime.now(); diff --git a/server/src/test/java/com/chutneytesting/campaign/domain/CampaignServiceTest.java b/server/src/test/java/com/chutneytesting/campaign/domain/CampaignServiceTest.java new file mode 100644 index 000000000..11b51b3fc --- /dev/null +++ b/server/src/test/java/com/chutneytesting/campaign/domain/CampaignServiceTest.java @@ -0,0 +1,233 @@ +package com.chutneytesting.campaign.domain; + + +import static com.chutneytesting.server.core.domain.execution.report.ServerReportStatus.FAILURE; +import static com.chutneytesting.server.core.domain.execution.report.ServerReportStatus.SUCCESS; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.chutneytesting.server.core.domain.execution.history.ExecutionHistory; +import com.chutneytesting.server.core.domain.execution.history.ImmutableExecutionHistory; +import com.chutneytesting.server.core.domain.scenario.campaign.CampaignExecutionReport; +import com.chutneytesting.server.core.domain.scenario.campaign.CampaignExecutionReportBuilder; +import com.chutneytesting.server.core.domain.scenario.campaign.ScenarioExecutionReportCampaign; +import java.time.LocalDateTime; +import java.util.List; +import org.junit.jupiter.api.Test; + +class CampaignServiceTest { + @Test + void should_return_campaign_report_by_campaign_execution_id() { + // G + CampaignRepository campaignRepository = mock(CampaignRepository.class); + CampaignService campaignService = new CampaignService(campaignRepository); + + ExecutionHistory.ExecutionSummary execution1 = ImmutableExecutionHistory.ExecutionSummary.builder() + .executionId(1L) + .testCaseTitle("") + .time(LocalDateTime.now()) + .duration(0l) + .environment("") + .user("") + .status(SUCCESS) + .build(); + ScenarioExecutionReportCampaign scenarioExecutionReport1 = new ScenarioExecutionReportCampaign("scenario 1", "", execution1); + ExecutionHistory.ExecutionSummary execution2 = ImmutableExecutionHistory.ExecutionSummary.builder() + .executionId(2L) + .testCaseTitle("") + .time(LocalDateTime.now()) + .duration(0l) + .environment("") + .user("") + .status(SUCCESS) + .build(); + ScenarioExecutionReportCampaign scenarioExecutionReport2 = new ScenarioExecutionReportCampaign("scenario 2", "", execution2); + CampaignExecutionReport campaignReport = CampaignExecutionReportBuilder.builder() + .addScenarioExecutionReport(scenarioExecutionReport1) + .addScenarioExecutionReport(scenarioExecutionReport2) + .build(); + when(campaignRepository.findByExecutionId(anyLong())).thenReturn(campaignReport); + + // W + CampaignExecutionReport report = campaignService.findByExecutionId(0L); + + // T + assertThat(report.scenarioExecutionReports()).hasSize(2); + assertThat(report.status()).isEqualTo(SUCCESS); + } + + @Test + void should_return_campaign_report_by_campaign_execution_id_when_retry_scenario_executions_exist() { + // G + CampaignRepository campaignRepository = mock(CampaignRepository.class); + CampaignService campaignService = new CampaignService(campaignRepository); + + String scenarioId = "scenario 1"; + ExecutionHistory.ExecutionSummary execution1 = ImmutableExecutionHistory.ExecutionSummary.builder() + .executionId(1L) + .testCaseTitle("") + .time(LocalDateTime.now().minusMinutes(1)) + .duration(0l) + .environment("") + .user("") + .status(FAILURE) + .build(); + ScenarioExecutionReportCampaign scenarioExecutionReport1 = new ScenarioExecutionReportCampaign(scenarioId, "", execution1); + ExecutionHistory.ExecutionSummary execution2 = ImmutableExecutionHistory.ExecutionSummary.builder() + .executionId(2L) + .testCaseTitle("") + .time(LocalDateTime.now()) + .duration(0l) + .environment("") + .user("") + .status(SUCCESS) + .build(); + ScenarioExecutionReportCampaign scenarioExecutionReport2 = new ScenarioExecutionReportCampaign(scenarioId, "", execution2); + CampaignExecutionReport campaignReport = CampaignExecutionReportBuilder.builder() + .addScenarioExecutionReport(scenarioExecutionReport1) + .addScenarioExecutionReport(scenarioExecutionReport2) + .build(); + when(campaignRepository.findByExecutionId(anyLong())).thenReturn(campaignReport); + + // W + CampaignExecutionReport report = campaignService.findByExecutionId(0L); + + // T + assertThat(report.scenarioExecutionReports()).hasSize(1); + assertThat(report.status()).isEqualTo(SUCCESS); + } + + @Test + void should_return_all_executions_of_a_campaign() { + // Given + Long campaignId = 1L; + CampaignRepository campaignRepository = mock(CampaignRepository.class); + ExecutionHistory.ExecutionSummary execution1 = ImmutableExecutionHistory.ExecutionSummary.builder() + .executionId(1L) + .testCaseTitle("") + .time(LocalDateTime.now()) + .duration(0l) + .environment("") + .user("") + .status(SUCCESS) + .build(); + ScenarioExecutionReportCampaign scenarioExecutionReport1 = new ScenarioExecutionReportCampaign("scenario 1", "", execution1); + ExecutionHistory.ExecutionSummary execution2 = ImmutableExecutionHistory.ExecutionSummary.builder() + .executionId(2L) + .testCaseTitle("") + .time(LocalDateTime.now()) + .duration(0l) + .environment("") + .user("") + .status(SUCCESS) + .build(); + ScenarioExecutionReportCampaign scenarioExecutionReport2 = new ScenarioExecutionReportCampaign("scenario 2", "", execution2); + List allExecutions = List.of( + CampaignExecutionReportBuilder.builder() + .addScenarioExecutionReport(scenarioExecutionReport1) + .build(), + CampaignExecutionReportBuilder.builder() + .addScenarioExecutionReport(scenarioExecutionReport2) + .build() + ); + when(campaignRepository.findExecutionsById(anyLong())).thenReturn(allExecutions); + CampaignService sut = new CampaignService(campaignRepository); + + // When + List executionsReports = sut.findExecutionsById(campaignId); + + // Then + assertThat(executionsReports).hasSameElementsAs(allExecutions); + } + + @Test + void should_return_all_executions_with_retries_of_a_campaign() { + // Given + Long campaignId = 1L; + CampaignRepository campaignRepository = mock(CampaignRepository.class); + String scenario1Id = "scenario 1"; + ExecutionHistory.ExecutionSummary execution1 = ImmutableExecutionHistory.ExecutionSummary.builder() + .executionId(1L) + .testCaseTitle("") + .time(LocalDateTime.now()) + .duration(0l) + .environment("") + .user("") + .status(SUCCESS) + .build(); + ScenarioExecutionReportCampaign scenarioExecutionReport1 = new ScenarioExecutionReportCampaign(scenario1Id, scenario1Id, execution1); + ExecutionHistory.ExecutionSummary execution2 = ImmutableExecutionHistory.ExecutionSummary.builder() + .executionId(2L) + .testCaseTitle("") + .time(LocalDateTime.now()) + .duration(0l) + .environment("") + .user("") + .status(SUCCESS) + .build(); + String scenario2Id = "scenario 2"; + ScenarioExecutionReportCampaign scenarioExecutionReport2 = new ScenarioExecutionReportCampaign(scenario2Id, "", execution2); + ExecutionHistory.ExecutionSummary execution3 = ImmutableExecutionHistory.ExecutionSummary.builder() + .executionId(3L) + .testCaseTitle("") + .time(LocalDateTime.now()) + .duration(0l) + .environment("") + .user("") + .status(SUCCESS) + .build(); + ScenarioExecutionReportCampaign scenarioExecutionReport3 = new ScenarioExecutionReportCampaign("scenario 3", "", execution3); + ExecutionHistory.ExecutionSummary execution4 = ImmutableExecutionHistory.ExecutionSummary.builder() + .executionId(4L) + .testCaseTitle("") + .time(LocalDateTime.now()) + .duration(0l) + .environment("") + .user("") + .status(SUCCESS) + .build(); + ScenarioExecutionReportCampaign scenarioExecutionReport4 = new ScenarioExecutionReportCampaign(scenario1Id, "", execution4); + ExecutionHistory.ExecutionSummary execution5 = ImmutableExecutionHistory.ExecutionSummary.builder() + .executionId(5L) + .testCaseTitle("") + .time(LocalDateTime.now()) + .duration(0l) + .environment("") + .user("") + .status(SUCCESS) + .build(); + ScenarioExecutionReportCampaign scenarioExecutionReport5 = new ScenarioExecutionReportCampaign(scenario2Id, "", execution5); + List allExecutions = List.of( + CampaignExecutionReportBuilder.builder() + .setExecutionId(1L) + .addScenarioExecutionReport(scenarioExecutionReport1) + .addScenarioExecutionReport(scenarioExecutionReport4) + .addScenarioExecutionReport(scenarioExecutionReport3) + .build(), + CampaignExecutionReportBuilder.builder() + .setExecutionId(2L) + .addScenarioExecutionReport(scenarioExecutionReport1) + .addScenarioExecutionReport(scenarioExecutionReport2) + .build(), + CampaignExecutionReportBuilder.builder() + .setExecutionId(3L) + .addScenarioExecutionReport(scenarioExecutionReport3) + .addScenarioExecutionReport(scenarioExecutionReport2) + .addScenarioExecutionReport(scenarioExecutionReport5) + .build() + ); + when(campaignRepository.findExecutionsById(anyLong())).thenReturn(allExecutions); + CampaignService sut = new CampaignService(campaignRepository); + + // When + List executionsReports = sut.findExecutionsById(campaignId); + + // Then + assertThat(executionsReports).hasSize(3); + assertThat(executionsReports.get(0).scenarioExecutionReports()).hasSize(2); + assertThat(executionsReports.get(1).scenarioExecutionReports()).hasSize(2); + assertThat(executionsReports.get(2).scenarioExecutionReports()).hasSize(2); + } +} diff --git a/server/src/test/java/com/chutneytesting/campaign/infra/CampaignExecutionRepositoryTest.java b/server/src/test/java/com/chutneytesting/campaign/infra/CampaignExecutionRepositoryTest.java index 9f3ceb865..2ffba11db 100644 --- a/server/src/test/java/com/chutneytesting/campaign/infra/CampaignExecutionRepositoryTest.java +++ b/server/src/test/java/com/chutneytesting/campaign/infra/CampaignExecutionRepositoryTest.java @@ -3,6 +3,7 @@ import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; +import com.chutneytesting.campaign.infra.jpa.CampaignEntity; import com.chutneytesting.execution.infra.storage.jpa.ScenarioExecution; import com.chutneytesting.scenario.infra.jpa.Scenario; import com.chutneytesting.server.core.domain.execution.report.ServerReportStatus; @@ -44,7 +45,7 @@ abstract class AllTests extends AbstractLocalDatabaseTest { @Test public void should_persist_1_execution_when_saving_1_campaign_execution_report() { Scenario scenario = givenScenario(); - com.chutneytesting.campaign.infra.jpa.Campaign campaign = givenCampaign(scenario); + CampaignEntity campaign = givenCampaign(scenario); ScenarioExecution scenarioExecution = givenScenarioExecution(scenario.getId(), ServerReportStatus.NOT_EXECUTED); ScenarioExecutionReportCampaign scenarioExecutionReport = new ScenarioExecutionReportCampaign(scenario.getId().toString(), scenario.getTitle(), scenarioExecution.toDomain()); @@ -82,7 +83,7 @@ public void should_persist_1_execution_when_saving_1_campaign_execution_report() public void should_persist_2_executions_when_saving_2_campaign_execution_report() { Scenario scenarioOne = givenScenario(); Scenario scenarioTwo = givenScenario(); - com.chutneytesting.campaign.infra.jpa.Campaign campaign = givenCampaign(scenarioOne, scenarioTwo); + CampaignEntity campaign = givenCampaign(scenarioOne, scenarioTwo); ScenarioExecution scenarioOneExecution = givenScenarioExecution(scenarioOne.getId(), ServerReportStatus.SUCCESS); ScenarioExecutionReportCampaign scenarioOneExecutionReport = new ScenarioExecutionReportCampaign(scenarioOne.getId().toString(), scenarioOne.getTitle(), scenarioOneExecution.toDomain()); @@ -139,7 +140,7 @@ public void should_persist_2_executions_when_saving_2_campaign_execution_report( public void campaign_execution_history_should_list_not_executed_scenarios() { Scenario scenarioOne = givenScenario(); Scenario scenarioTwo = givenScenario(); - com.chutneytesting.campaign.infra.jpa.Campaign campaign = givenCampaign(scenarioOne, scenarioTwo); + CampaignEntity campaign = givenCampaign(scenarioOne, scenarioTwo); ScenarioExecution scenarioOneExecution = givenScenarioExecution(scenarioOne.getId(), ServerReportStatus.SUCCESS); ScenarioExecutionReportCampaign scenarioOneExecutionReport = new ScenarioExecutionReportCampaign(scenarioOne.getId().toString(), scenarioOne.getTitle(), scenarioOneExecution.toDomain()); @@ -182,7 +183,7 @@ public void campaign_execution_history_should_list_not_executed_scenarios() { @Test public void should_remove_all_campaign_executions_when_removing_campaign_execution_report() { Scenario scenario = givenScenario(); - com.chutneytesting.campaign.infra.jpa.Campaign campaign = givenCampaign(scenario); + CampaignEntity campaign = givenCampaign(scenario); ScenarioExecution scenarioExecution = givenScenarioExecution(scenario.getId(), ServerReportStatus.NOT_EXECUTED); ScenarioExecutionReportCampaign scenarioExecutionReport = new ScenarioExecutionReportCampaign(scenario.getId().toString(), scenario.getTitle(), scenarioExecution.toDomain()); @@ -206,7 +207,7 @@ public void should_remove_all_campaign_executions_when_removing_campaign_executi public void should_get_2_last_campaign_report_created() { clearTables(); Scenario scenario = givenScenario(); - com.chutneytesting.campaign.infra.jpa.Campaign campaign = givenCampaign(scenario); + CampaignEntity campaign = givenCampaign(scenario); ScenarioExecution scenarioExecutionOne = givenScenarioExecution(scenario.getId(), ServerReportStatus.NOT_EXECUTED); ScenarioExecutionReportCampaign scenarioExecutionOneReport = new ScenarioExecutionReportCampaign(scenario.getId().toString(), scenario.getTitle(), scenarioExecutionOne.toDomain()); diff --git a/server/src/test/java/com/chutneytesting/campaign/infra/FakeCampaignRepository.java b/server/src/test/java/com/chutneytesting/campaign/infra/FakeCampaignRepository.java index c41c25470..c477d39e0 100644 --- a/server/src/test/java/com/chutneytesting/campaign/infra/FakeCampaignRepository.java +++ b/server/src/test/java/com/chutneytesting/campaign/infra/FakeCampaignRepository.java @@ -1,6 +1,7 @@ package com.chutneytesting.campaign.infra; import static java.util.Collections.emptyMap; +import static java.util.Optional.ofNullable; import static org.assertj.core.util.Lists.newArrayList; import com.chutneytesting.campaign.domain.CampaignNotFoundException; @@ -13,7 +14,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Random; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; @@ -43,7 +43,7 @@ public Campaign createOrUpdate(Campaign campaign) { @Override public void saveReport(Long campaignId, CampaignExecutionReport report) { - Optional.ofNullable(campaignsById.get(campaignId)).ifPresent(campaign -> { + ofNullable(campaignsById.get(campaignId)).ifPresent(campaign -> { Campaign c = new Campaign(campaign.id, campaign.title, campaign.title, campaign.scenarioIds, campaign.executionParameters, campaign.executionEnvironment(), false, false, null, null); createOrUpdate(c); }); @@ -82,7 +82,7 @@ public List findByName(String campaignName) { @Override public List findExecutionsById(Long campaignId) { - return campaignsExecutionById.get(campaignId); + return ofNullable(campaignsExecutionById.get(campaignId)).orElse(newArrayList()); } @Override diff --git a/server/src/test/java/com/chutneytesting/execution/infra/storage/DatabaseExecutionHistoryRepositoryTest.java b/server/src/test/java/com/chutneytesting/execution/infra/storage/DatabaseExecutionHistoryRepositoryTest.java index 3b7203530..ce2b4315f 100644 --- a/server/src/test/java/com/chutneytesting/execution/infra/storage/DatabaseExecutionHistoryRepositoryTest.java +++ b/server/src/test/java/com/chutneytesting/execution/infra/storage/DatabaseExecutionHistoryRepositoryTest.java @@ -8,7 +8,7 @@ import static util.WaitUtils.awaitDuring; import com.chutneytesting.campaign.infra.CampaignExecutionDBRepository; -import com.chutneytesting.campaign.infra.jpa.Campaign; +import com.chutneytesting.campaign.infra.jpa.CampaignEntity; import com.chutneytesting.execution.infra.storage.jpa.ScenarioExecution; import com.chutneytesting.scenario.infra.jpa.Scenario; import com.chutneytesting.server.core.domain.execution.history.ExecutionHistory; @@ -278,7 +278,7 @@ public void should_truncate_report_info_and_error_on_save_or_update() { public void should_map_campaign_only_when_executing_from_campaign() { // Given Scenario scenario = givenScenario(); - Campaign campaign = givenCampaign(scenario); + CampaignEntity campaign = givenCampaign(scenario); ScenarioExecution scenarioExecutionOne = givenScenarioExecution(scenario.getId(), ServerReportStatus.FAILURE); ScenarioExecutionReportCampaign scenarioExecutionOneReport = new ScenarioExecutionReportCampaign(scenario.getId().toString(), scenario.getTitle(), scenarioExecutionOne.toDomain()); @@ -306,7 +306,7 @@ public void should_map_campaign_only_when_executing_from_campaign() { public void should_retrieve_scenario_execution_summary() { // Given Scenario scenario = givenScenario(); - Campaign campaign = givenCampaign(scenario); + CampaignEntity campaign = givenCampaign(scenario); ScenarioExecution scenarioExecutionOne = givenScenarioExecution(scenario.getId(), ServerReportStatus.FAILURE); ScenarioExecutionReportCampaign scenarioExecutionOneReport = new ScenarioExecutionReportCampaign(scenario.getId().toString(), scenario.getTitle(), scenarioExecutionOne.toDomain()); diff --git a/server/src/test/java/com/chutneytesting/scenario/infra/raw/DatabaseTestCaseRepositoryTest.java b/server/src/test/java/com/chutneytesting/scenario/infra/raw/DatabaseTestCaseRepositoryTest.java index 753ab80d5..663970c6b 100644 --- a/server/src/test/java/com/chutneytesting/scenario/infra/raw/DatabaseTestCaseRepositoryTest.java +++ b/server/src/test/java/com/chutneytesting/scenario/infra/raw/DatabaseTestCaseRepositoryTest.java @@ -11,7 +11,7 @@ import static util.WaitUtils.awaitDuring; import com.chutneytesting.campaign.infra.CampaignExecutionDBRepository; -import com.chutneytesting.campaign.infra.jpa.Campaign; +import com.chutneytesting.campaign.infra.jpa.CampaignEntity; import com.chutneytesting.execution.infra.storage.jpa.ScenarioExecution; import com.chutneytesting.scenario.domain.gwt.GwtScenario; import com.chutneytesting.scenario.domain.gwt.GwtStep; @@ -167,7 +167,7 @@ public void should_not_find_removed_standalone_scenario_but_still_exist_in_datab public void should_not_find_removed_scenario_used_in_campaign() { // Given: a scenarioTemplate in the repository with campaign association and existing execution Scenario scenario = givenScenario(); - Campaign campaign = givenCampaign(scenario); + CampaignEntity campaign = givenCampaign(scenario); ScenarioExecution scenarioExecution = givenScenarioExecution(scenario.getId(), ServerReportStatus.NOT_EXECUTED); diff --git a/server/src/test/java/util/infra/AbstractLocalDatabaseTest.java b/server/src/test/java/util/infra/AbstractLocalDatabaseTest.java index 4765cbd8c..234b6da43 100644 --- a/server/src/test/java/util/infra/AbstractLocalDatabaseTest.java +++ b/server/src/test/java/util/infra/AbstractLocalDatabaseTest.java @@ -2,7 +2,7 @@ import static java.time.Instant.now; -import com.chutneytesting.campaign.infra.jpa.Campaign; +import com.chutneytesting.campaign.infra.jpa.CampaignEntity; import com.chutneytesting.campaign.infra.jpa.CampaignScenario; import com.chutneytesting.execution.infra.storage.jpa.ScenarioExecution; import com.chutneytesting.scenario.infra.jpa.Scenario; @@ -87,9 +87,9 @@ protected String givenScenarioId(boolean componentId) { return componentId ? clusterId + "-" + objectId : String.valueOf(objectId); } - protected Campaign givenCampaign(Scenario... scenarios) { + protected CampaignEntity givenCampaign(Scenario... scenarios) { ArrayList campaignScenarios = new ArrayList<>(); - Campaign campaign = new Campaign("", campaignScenarios); + CampaignEntity campaign = new CampaignEntity("", campaignScenarios); return transactionTemplate.execute(ts -> { for (int i = 0; i < scenarios.length; i++) { Scenario scenario = scenarios[i];