Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(server): get campaign fetches executions from db #32

Merged
merged 2 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,13 @@
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

Expand Down Expand Up @@ -241,9 +244,14 @@ private ServerReportStatus findStatus(List<ScenarioExecutionCampaign> scenarioEx
private List<ScenarioExecutionCampaign> filterRetry(List<ScenarioExecutionCampaign> 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())
.collect(Collectors.toMap(
s -> s.scenarioId,
Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(s -> s.execution.time())),
LinkedHashMap::new // Keep the insertion order
))
.values()
.stream()
.toList();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,16 @@ public class CampaignController {
private final CampaignRepository campaignRepository;

private final CampaignExecutionRepository campaignExecutionRepository;
private final CampaignExecutionEngine campaignExecutionEngine;
private final CampaignService campaignService;

public CampaignController(TestCaseRepositoryAggregator repositoryAggregator,
CampaignRepository campaignRepository,
CampaignExecutionRepository campaignExecutionRepository,
CampaignExecutionEngine campaignExecutionEngine,
CampaignService campaignService) {

this.repositoryAggregator = repositoryAggregator;
this.campaignRepository = campaignRepository;
this.campaignExecutionRepository = campaignExecutionRepository;
this.campaignExecutionEngine = campaignExecutionEngine;
this.campaignService = campaignService;
}

Expand All @@ -97,8 +94,6 @@ public boolean deleteCampaign(@PathVariable("campaignId") Long campaignId) {
public CampaignDto getCampaignById(@PathVariable("campaignId") Long campaignId) {
Campaign campaign = campaignRepository.findById(campaignId);
List<CampaignExecution> reports = campaignService.findExecutionsById(campaignId);
campaignExecutionEngine.currentExecution(campaignId)
.ifPresent(report -> addCurrentExecution(reports, report));
return toDto(campaign, reports);
}

Expand All @@ -122,12 +117,7 @@ public List<CampaignDto> getAllCampaigns() {
@PreAuthorize("hasAuthority('CAMPAIGN_READ')")
@GetMapping(path = "/lastexecutions/{limit}", produces = MediaType.APPLICATION_JSON_VALUE)
public List<CampaignExecutionReportDto> getLastExecutions(@PathVariable("limit") Long limit) {
List<CampaignExecution> lastExecutions = campaignExecutionEngine.currentExecutions();

// Complete current executions with finished ones up to the limit
if (lastExecutions.size() < limit) {
lastExecutions.addAll(campaignExecutionRepository.getLastExecutions(limit - lastExecutions.size()));
}
List<CampaignExecution> lastExecutions = campaignExecutionRepository.getLastExecutions(limit);

return lastExecutions.stream()
.map(CampaignExecutionReportMapper::toDto)
Expand All @@ -143,10 +133,4 @@ public List<CampaignDto> getCampaignsByScenarioId(@PathVariable("scenarioId") St
.collect(Collectors.toList());
}

private void addCurrentExecution(List<CampaignExecution> currentCampaignExecutions, CampaignExecution campaignExecution) {
if (currentCampaignExecutions == null) {
currentCampaignExecutions = new ArrayList<>();
}
currentCampaignExecutions.add(0, campaignExecution);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public void stopExecution(Long campaignId) {
public CampaignExecution getLastExecution(Long campaignId) {
return campaignExecutionJpaRepository
.findFirstByCampaignIdOrderByIdDesc(campaignId)
.map(campaignExecution -> toDomain(campaignExecution, true))
.map(this::toDomain)
.orElseThrow(() -> new CampaignExecutionNotFoundException(campaignId));
}

Expand All @@ -106,7 +106,7 @@ public void deleteExecutions(Set<Long> executionsIds) {
public List<CampaignExecution> getExecutionHistory(Long campaignId) {
CampaignEntity campaign = campaignJpaRepository.findById(campaignId).orElseThrow(() -> new CampaignNotFoundException(campaignId));
return campaignExecutionJpaRepository.findByCampaignIdOrderByIdDesc(campaignId).stream()
.map(ce -> toDomainWithCampaign(campaign, ce, false))
.map(ce -> toDomainWithCampaign(campaign, ce))
.filter(Objects::nonNull)
.collect(Collectors.toCollection(ArrayList::new));
}
Expand All @@ -129,7 +129,7 @@ public void saveCampaignExecution(Long campaignId, CampaignExecution campaignExe
public List<CampaignExecution> getLastExecutions(Long numberOfExecution) {
return campaignExecutionJpaRepository.findAll(
PageRequest.of(0, numberOfExecution.intValue(), Sort.by(Sort.Direction.DESC, "id"))).stream()
.map(ce -> toDomain(ce, false))
.map(this::toDomain)
.filter(Objects::nonNull)
.toList();
}
Expand All @@ -138,7 +138,7 @@ public List<CampaignExecution> getLastExecutions(Long numberOfExecution) {
@Transactional(readOnly = true)
public CampaignExecution getCampaignExecutionById(Long campaignExecId) {
return campaignExecutionJpaRepository.findById(campaignExecId)
.map(ce -> toDomain(ce, true))
.map(this::toDomain)
.orElseThrow(() -> new CampaignExecutionNotFoundException(null, campaignExecId));
}

Expand All @@ -160,18 +160,13 @@ public Long generateCampaignExecutionId(Long campaignId, String environment) {
campaignExecutionJpaRepository.save(newExecution);
return newExecution.id();
}
private CampaignExecution toDomain(CampaignExecutionEntity campaignExecution, boolean withRunning) {
private CampaignExecution toDomain(CampaignExecutionEntity campaignExecution) {
return toDomainWithCampaign(
campaignJpaRepository.findById(campaignExecution.campaignId()).orElseThrow(() -> new CampaignExecutionNotFoundException(campaignExecution.campaignId(), campaignExecution.id())),
campaignExecution,
withRunning);
campaignExecution);
}

private CampaignExecution toDomainWithCampaign(CampaignEntity campaign, CampaignExecutionEntity campaignExecutionEntity, boolean withRunning) {
// TODO try to manage it with optional and not with null
if (!withRunning && isCampaignExecutionRunning(campaignExecutionEntity)) {
return null;
}
private CampaignExecution toDomainWithCampaign(CampaignEntity campaign, CampaignExecutionEntity campaignExecutionEntity) {
return campaignExecutionEntity.toDomain(campaign, isCampaignExecutionRunning(campaignExecutionEntity), this::title);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public void setUp() throws Exception {
resultExtractor = new ResultExtractor();

repositoryAggregator = mock(TestCaseRepositoryAggregator.class);
CampaignController campaignController = new CampaignController(repositoryAggregator, repository, repository, campaignExecutionEngine, new CampaignService(repository));
CampaignController campaignController = new CampaignController(repositoryAggregator, repository, repository, new CampaignService(repository));
mockMvc = MockMvcBuilders.standaloneSetup(campaignController)
.setControllerAdvice(new RestExceptionHandler(Mockito.mock(ChutneyMetrics.class)))
.build();
Expand Down Expand Up @@ -262,9 +262,6 @@ public void should_find_no_campaign_related_to_an_orphan_scenario() throws Excep
@Test
public void should_retrieve_executions_and_current_execution_when_found_campaign() throws Exception {
// Given
CampaignExecution currentExecution = new CampaignExecution(42L, existingCampaign.getTitle(), false, "", null, null, "");
when(campaignExecutionEngine.currentExecution(existingCampaign.getId()))
.thenReturn(Optional.of(currentExecution));

CampaignExecution report1 = new CampaignExecution(1L, existingCampaign.getId(), emptyList(), "...", false, "", null, null, "");
CampaignExecution report2 = new CampaignExecution(2L, existingCampaign.getId(), emptyList(), "...", false, "", null, null, "");
Expand All @@ -283,18 +280,16 @@ public void should_retrieve_executions_and_current_execution_when_found_campaign

// Then
// get campaign with all executions
verify(campaignExecutionEngine).currentExecution(existingCampaign.getId());
assertThat(receivedCampaign.getCampaignExecutionReports()).hasSize(5);
assertThat(receivedCampaign.getCampaignExecutionReports().get(0).getExecutionId()).isEqualTo(42L);
assertThat(receivedCampaign.getCampaignExecutionReports()).hasSize(4);
assertThat(receivedCampaign.getCampaignExecutionReports().get(0).getExecutionId()).isEqualTo(1L);
assertThat(receivedCampaign.getCampaignExecutionReports().get(1).getExecutionId()).isEqualTo(2L);
assertThat(receivedCampaign.getCampaignExecutionReports().get(2).getExecutionId()).isEqualTo(3L);
assertThat(receivedCampaign.getCampaignExecutionReports().get(3).getExecutionId()).isEqualTo(4L);
}

@Test
public void should_retrieve_user_execution_when_found_campaign() throws Exception {
public void should_retrieve_execution_when_found_campaign() throws Exception {
// Given
CampaignExecution currentExecution = new CampaignExecution(42L, existingCampaign.getTitle(), false, "", null, null, "user_1");
when(campaignExecutionEngine.currentExecution(existingCampaign.getId()))
.thenReturn(Optional.of(currentExecution));

CampaignExecution report1 = new CampaignExecution(1L, existingCampaign.getId(), emptyList(), existingCampaign.getTitle(), false, "", null, null, "user_2");

repository.saveCampaignExecution(existingCampaign.getId(), report1);
Expand All @@ -306,12 +301,10 @@ public void should_retrieve_user_execution_when_found_campaign() throws Exceptio

// Then
// get campaign with all executions
verify(campaignExecutionEngine).currentExecution(existingCampaign.getId());
assertThat(receivedCampaign.getCampaignExecutionReports()).hasSize(2);
assertThat(receivedCampaign.getCampaignExecutionReports().get(0).getExecutionId()).isEqualTo(42L);
assertThat(receivedCampaign.getCampaignExecutionReports()).hasSize(1);
assertThat(receivedCampaign.getCampaignExecutionReports().get(0).getExecutionId()).isEqualTo(1L);

assertThat(receivedCampaign.getCampaignExecutionReports().get(0).getUserId()).isEqualTo("user_1");
assertThat(receivedCampaign.getCampaignExecutionReports().get(1).getUserId()).isEqualTo("user_2");
assertThat(receivedCampaign.getCampaignExecutionReports().get(0).getUserId()).isEqualTo("user_2");
}

@Test
Expand All @@ -330,8 +323,8 @@ public void should_add_current_executions_when_last_executions_asked_for() throw
awaitDuring(100, MILLISECONDS); // Avoid reports with same startDate...
CampaignExecution campaignExecution2 = new CampaignExecution(5L, 2L, emptyList(), anotherExistingCampaign.getTitle(), false, "", null, null, "");

when(campaignExecutionEngine.currentExecutions())
.thenReturn(Lists.list(campaignExecution1, campaignExecution2));
repository.saveCampaignExecution(campaignExecution1.executionId, campaignExecution1);
repository.saveCampaignExecution(campaignExecution2.executionId, campaignExecution2);

// When
// last executions asked for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@


import static com.chutneytesting.server.core.domain.execution.report.ServerReportStatus.FAILURE;
import static com.chutneytesting.server.core.domain.execution.report.ServerReportStatus.RUNNING;
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;
Expand Down Expand Up @@ -87,6 +88,69 @@ void should_return_campaign_report_by_campaign_execution_id() {

}

@Test
void should_keep_scenarios_executions_order_on_running_campaign_report() {
// Given
Long campaignId = 1L;
CampaignExecutionRepository campaignExecutionRepository = mock(CampaignExecutionRepository.class);
ExecutionHistory.ExecutionSummary execution1 = ImmutableExecutionHistory.ExecutionSummary.builder()
.executionId(1L)
.testCaseTitle("")
.time(LocalDateTime.now())
.duration(0L)
.environment("")
.user("")
.scenarioId("")
.status(FAILURE)
.build();

ScenarioExecutionCampaign scenarioExecutionReport1 = new ScenarioExecutionCampaign("scenario 1", "", execution1);
ExecutionHistory.ExecutionSummary execution2 = ImmutableExecutionHistory.ExecutionSummary.builder()
.executionId(2L)
.testCaseTitle("")
.time(LocalDateTime.now())
.duration(0L)
.environment("")
.user("")
.scenarioId("")
.status(SUCCESS)
.build();

ScenarioExecutionCampaign scenarioExecutionReport2 = new ScenarioExecutionCampaign("scenario 1", "", execution2);
ExecutionHistory.ExecutionSummary execution3 = ImmutableExecutionHistory.ExecutionSummary.builder()
.executionId(2L)
.testCaseTitle("")
.time(LocalDateTime.now())
.duration(0L)
.environment("")
.user("")
.status(RUNNING)
.scenarioId("")
.build();
ScenarioExecutionCampaign scenarioExecutionReport3 = new ScenarioExecutionCampaign("scenario 2", "", execution3);
List<CampaignExecution> allExecutions = List.of(
CampaignExecutionReportBuilder.builder()
// scenario exec report order is important for this test
.addScenarioExecutionReport(scenarioExecutionReport1)
.addScenarioExecutionReport(scenarioExecutionReport2)
.addScenarioExecutionReport(scenarioExecutionReport3)
.build()
);
when(campaignExecutionRepository.getExecutionHistory(anyLong())).thenReturn(allExecutions);
CampaignService sut = new CampaignService(campaignExecutionRepository);

// When
List<CampaignExecution> executionsReports = sut.findExecutionsById(campaignId);

// Then
assertThat(executionsReports).hasSize(1);
assertThat(executionsReports.get(0).status()).isEqualTo(RUNNING);
assertThat(executionsReports.get(0).scenarioExecutionReports()).hasSize(2);
assertThat(executionsReports.get(0).scenarioExecutionReports().get(0).scenarioId).isEqualTo("scenario 1");
assertThat(executionsReports.get(0).scenarioExecutionReports().get(1).scenarioId).isEqualTo("scenario 2");

}

@Test
void should_return_campaign_report_by_campaign_execution_id_when_retry_scenario_executions_exist() {
// G
Expand Down
Loading