Skip to content

Commit

Permalink
Added integration tests for templates health check + fix tests #3616
Browse files Browse the repository at this point in the history
- restdoc test path problem fixed (was wrong usecase)
- template servcie + config service + repository
  added missing implementation + tests to find all project ids
  which uses a template
- Existing integration test for templates extended with healthcheck
  parts (scenario1). Has no errors in output because products do
  not support templates, so no conflict detected (correct)
- Created new test (scenario9) for templates which fails with errors
  because product does support templates...
  • Loading branch information
de-jcup committed Jan 28, 2025
1 parent c892d6a commit 1c7578d
Show file tree
Hide file tree
Showing 20 changed files with 540 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ public void restdoc_admin_executes_templates_healthcheck() throws Exception {
when(templateHealthCheckService.executeHealthCheck()).thenReturn(healthCheckResult);

String apiEndpoint = https(PORT_USED).buildAdminExecutesTemplatesCheck();
Class<? extends Annotation> useCase = UseCaseAdminFetchesAllTemplateIds.class;
Class<? extends Annotation> useCase = UseCaseAdminExecutesTemplatesHealthcheck.class;

/* execute + test @formatter:off */
this.mockMvc.perform(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import com.mercedesbenz.sechub.domain.administration.project.ProjectDetailInformation;
import com.mercedesbenz.sechub.domain.scan.asset.AssetDetailData;
import com.mercedesbenz.sechub.domain.scan.project.FalsePositiveProjectData;
import com.mercedesbenz.sechub.domain.scan.template.TemplatesHealthCheckResult;
import com.mercedesbenz.sechub.integrationtest.JSONTestSupport;
import com.mercedesbenz.sechub.integrationtest.internal.IntegrationTestContext;
import com.mercedesbenz.sechub.integrationtest.internal.IntegrationTestExampleConstants;
Expand Down Expand Up @@ -1480,6 +1481,12 @@ public List<String> fetchTemplateList() {
return JSONConverter.get().fromJSONtoListOf(String.class, json);
}

public TemplatesHealthCheckResult executeTemplatesHealthcheck() {
String url = getUrlBuilder().buildAdminExecutesTemplatesCheck();
String json = getRestHelper().getJSON(url);
return TemplatesHealthCheckResult.fromJson(json);
}

public AsUser uploadAssetFile(String assetId, File file) {
String url = getUrlBuilder().buildAdminUploadsAssetFile(assetId);
String checkSum = TestAPI.createSHA256Of(file);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1712,4 +1712,10 @@ public static List<ScanProjectConfig> fetchScanProjectConfigurations(TestProject
return JSONConverter.get().fromJSONtoListOf(ScanProjectConfig.class, json);

}

public static void clearAllExistingTemplates() {
String url = getURLBuilder().buildIntegrationTestClearAllTemplates();
getSuperAdminRestHelper().post(url);

}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
// SPDX-License-Identifier: MIT
package com.mercedesbenz.sechub.integrationtest.scenario1;

import static com.mercedesbenz.sechub.integrationtest.api.TestAPI.SUPER_ADMIN;
import static com.mercedesbenz.sechub.integrationtest.api.TestAPI.*;
import static com.mercedesbenz.sechub.integrationtest.api.TestAPI.as;
import static com.mercedesbenz.sechub.integrationtest.api.TestAPI.executeResilient;
import static com.mercedesbenz.sechub.integrationtest.api.TestAPI.fetchScanProjectConfigurations;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.*;

import java.util.List;

Expand All @@ -18,11 +16,22 @@
import com.mercedesbenz.sechub.commons.model.template.TemplateType;
import com.mercedesbenz.sechub.domain.scan.project.ScanProjectConfig;
import com.mercedesbenz.sechub.domain.scan.project.ScanProjectConfigID;
import com.mercedesbenz.sechub.domain.scan.template.TemplateHealthCheckEntry;
import com.mercedesbenz.sechub.domain.scan.template.TemplateHealthCheckProblemType;
import com.mercedesbenz.sechub.domain.scan.template.TemplatesHealthCheckResult;
import com.mercedesbenz.sechub.domain.scan.template.TemplatesHealthCheckStatus;
import com.mercedesbenz.sechub.integrationtest.api.IntegrationTestExtension;
import com.mercedesbenz.sechub.integrationtest.api.TestAPI;
import com.mercedesbenz.sechub.integrationtest.api.WithTestScenario;

@ExtendWith(IntegrationTestExtension.class)
@WithTestScenario(Scenario1.class)
/**
* Info: There are similarities to TemplateScenario9IntTest, but here we have no
* product in executor configurations which supports templates. This means that
* testing templates here, can only check common parts - e.g. info that template
* exists but is not assigned to any project.
*/
class TemplateScenario1IntTest {

private String templateId;
Expand Down Expand Up @@ -59,27 +68,43 @@ void beforeEach() {
definitionWithId = TemplateDefinition.from(fullTemplateDefinitionJson);

updateDefinition = TemplateDefinition.from(fullTemplateDefinitionJson.replace(templateId, "will-not-be-changed-by-update"));

/*
* we need to clear old template data , to be able to restart the test for
* development
*/
TestAPI.clearAllExistingTemplates();

}

@Test
void template_crud_test() {
void template_crud_and_healthcheck_test() {
/* prepare */
as(SUPER_ADMIN).createProject(Scenario1.PROJECT_1, SUPER_ADMIN); // not done in this scenario automatically

/* check preconditions */
assertTemplateNotInsideTemplateList();

/* execute + test */

assertTemplateHealthCheckSaysOKwithoutAnyEntries(); // beforeEach drops any old template data, so we can test here

assertTemplateCanBeCreated();

assertTemplateCanBeUpdated();

assertTemplateHealthCheckSaysOkButInfoThatTemplateIsNotAssigned();

assertTemplateCanBeAssignedToProject();

assertTemplateCanBeUnassignedFromProject();

assertTemplateCanBeAssignedToProject();

assertTemplateHealthCheckSaysOkWithoutEntries(); // ok without entries... why? because template is assigned, no asset file
// exists, but... there is no product which would support templates, so no
// runtime problems!

assertTemplateCanBeDeletedAndAssignmentIsPurged();

assertTemplateCanBeRecreatedWithSameId();
Expand All @@ -101,6 +126,40 @@ void template_crud_test() {

}

private void assertTemplateHealthCheckSaysOKwithoutAnyEntries() {
TemplatesHealthCheckResult result = as(SUPER_ADMIN).executeTemplatesHealthcheck();

executeResilient(() -> {
assertThat(result.getStatus()).isEqualTo(TemplatesHealthCheckStatus.OK);
assertThat(result.getEntries()).isEmpty();

});
}

private void assertTemplateHealthCheckSaysOkWithoutEntries() {
TemplatesHealthCheckResult result = as(SUPER_ADMIN).executeTemplatesHealthcheck();

executeResilient(() -> {
assertThat(result.getStatus()).isEqualTo(TemplatesHealthCheckStatus.OK);
assertThat(result.getEntries()).hasSize(0);

});
}

private void assertTemplateHealthCheckSaysOkButInfoThatTemplateIsNotAssigned() {
TemplatesHealthCheckResult result = as(SUPER_ADMIN).executeTemplatesHealthcheck();

executeResilient(() -> {
assertThat(result.getStatus()).isEqualTo(TemplatesHealthCheckStatus.OK);
assertThat(result.getEntries()).hasSize(1);
TemplateHealthCheckEntry firstEntry = result.getEntries().iterator().next();
assertThat(firstEntry.getType()).isEqualTo(TemplateHealthCheckProblemType.INFO);
assertThat(firstEntry.getDescription()).contains("The template is defined, but not assigned to any project");

});

}

private void assertTemplateNotInsideTemplateList() {
List<String> templateIds = as(SUPER_ADMIN).fetchTemplateList();
executeResilient(() -> assertThat(templateIds).doesNotContain(templateId));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// SPDX-License-Identifier: MIT
package com.mercedesbenz.sechub.integrationtest.scenario9;

import static com.mercedesbenz.sechub.integrationtest.api.TestAPI.*;
import static com.mercedesbenz.sechub.integrationtest.api.TestAPI.as;
import static com.mercedesbenz.sechub.integrationtest.scenario9.Scenario9.*;
import static org.assertj.core.api.Assertions.*;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

import com.mercedesbenz.sechub.commons.model.template.TemplateDefinition;
import com.mercedesbenz.sechub.commons.model.template.TemplateDefinition.TemplateVariable;
import com.mercedesbenz.sechub.commons.model.template.TemplateType;
import com.mercedesbenz.sechub.domain.scan.template.TemplateHealthCheckEntry;
import com.mercedesbenz.sechub.domain.scan.template.TemplateHealthCheckProblemType;
import com.mercedesbenz.sechub.domain.scan.template.TemplatesHealthCheckResult;
import com.mercedesbenz.sechub.domain.scan.template.TemplatesHealthCheckStatus;
import com.mercedesbenz.sechub.integrationtest.api.IntegrationTestExtension;
import com.mercedesbenz.sechub.integrationtest.api.TestAPI;
import com.mercedesbenz.sechub.integrationtest.api.WithTestScenario;

@ExtendWith(IntegrationTestExtension.class)
@WithTestScenario(Scenario9.class)
/**
* This is similar to TemplateScenario1IntTest, but here we got errors inside
* template check because the product (PDS) is supporting templates and the scan
* type (Web scan) is supported as well!
*/
class TemplateScenario9IntTest {

private String templateId;

private TemplateDefinition createDefinition;

@BeforeEach
void beforeEach() {

templateId = "template-1_" + System.nanoTime();

/* @formatter:off */
createDefinition = TemplateDefinition.builder().
templateId(templateId).
templateType(TemplateType.WEBSCAN_LOGIN).
assetId("asset1").
build();
/* @formatter:on */
TemplateVariable usernameVariable = new TemplateVariable();
usernameVariable.setName("username");

TemplateVariable passwordVariable = new TemplateVariable();
passwordVariable.setName("password");

createDefinition.getVariables().add(usernameVariable);
createDefinition.getVariables().add(passwordVariable);

/*
* we need to clear old template data , to be able to restart the test for
* development
*/
TestAPI.clearAllExistingTemplates();

}

@Test
void template_healthcheck_test_for_situation_that_pds_product_is_able_to_use_templates_and_scan_type_also_supported() {
/* prepare */

/* execute + test */
assertTemplateHealthCheckSaysOKwithoutAnyEntries(); // beforeEach drops any old template data, so we can test here

as(SUPER_ADMIN).createOrUpdateTemplate(templateId, createDefinition);

assertTemplateHealthCheckSaysOkButInfoThatTemplateIsNotAssigned();

as(SUPER_ADMIN).assignTemplateToProject(templateId, PROJECT_1);

assertTemplateHealthCheckSaysErrorBecauseAssetNotAvailable();

}

private void assertTemplateHealthCheckSaysOKwithoutAnyEntries() {
TemplatesHealthCheckResult result = as(SUPER_ADMIN).executeTemplatesHealthcheck();

executeResilient(() -> {
assertThat(result.getStatus()).isEqualTo(TemplatesHealthCheckStatus.OK);
assertThat(result.getEntries()).isEmpty();

});
}

private void assertTemplateHealthCheckSaysOkButInfoThatTemplateIsNotAssigned() {
TemplatesHealthCheckResult result = as(SUPER_ADMIN).executeTemplatesHealthcheck();

executeResilient(() -> {
assertThat(result.getStatus()).isEqualTo(TemplatesHealthCheckStatus.OK);
assertThat(result.getEntries()).hasSize(1);
TemplateHealthCheckEntry firstEntry = result.getEntries().iterator().next();
assertThat(firstEntry.getType()).isEqualTo(TemplateHealthCheckProblemType.INFO);
assertThat(firstEntry.getDescription()).contains("The template is defined, but not assigned to any project");

});

}

private void assertTemplateHealthCheckSaysErrorBecauseAssetNotAvailable() {
TemplatesHealthCheckResult result = as(SUPER_ADMIN).executeTemplatesHealthcheck();

executeResilient(() -> {
assertThat(result.getStatus()).isEqualTo(TemplatesHealthCheckStatus.ERROR);
assertThat(result.getEntries()).hasSize(1);
TemplateHealthCheckEntry firstEntry = result.getEntries().iterator().next();
assertThat(firstEntry.getType()).isEqualTo(TemplateHealthCheckProblemType.ERROR);
assertThat(firstEntry.getDescription()).contains("The file 'asset1/PDS_INTTEST_PRODUCT_WS_SARIF.zip' does not exist!");

});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import com.mercedesbenz.sechub.domain.scan.project.ScanProjectConfig;
import com.mercedesbenz.sechub.domain.scan.project.ScanProjectConfigRepository;
import com.mercedesbenz.sechub.domain.scan.report.ScanReportCountService;
import com.mercedesbenz.sechub.domain.scan.template.TemplateService;
import com.mercedesbenz.sechub.sharedkernel.ProductIdentifier;
import com.mercedesbenz.sechub.sharedkernel.Profiles;
import com.mercedesbenz.sechub.sharedkernel.mapping.MappingIdentifier;
Expand Down Expand Up @@ -97,6 +98,9 @@ public class IntegrationTestScanRestController {
@Autowired
private ScanProjectConfigRepository scanProjectConfigRepository;

@Autowired
private TemplateService templateService;

@RequestMapping(path = APIConstants.API_ANONYMOUS + "integrationtest/autocleanup/inspection/scan/days", method = RequestMethod.GET, produces = {
MediaType.APPLICATION_JSON_VALUE })
public long fetchScheduleAutoCleanupConfiguredDays() {
Expand Down Expand Up @@ -221,7 +225,6 @@ public MappingData fetchScanMappingData(@PathVariable("mappingId") String mappin

}

@SuppressWarnings("deprecation")
@RequestMapping(path = APIConstants.API_ANONYMOUS + "integrationtest/config/namepattern/{namePatternProviderId}/{name}", method = RequestMethod.GET)
public String getIdForNameByProvider(@PathVariable("namePatternProviderId") String namePatternProviderId, @PathVariable("name") String name) {
MappingIdentifier mappingIdentifier = MappingIdentifier.valueOf(namePatternProviderId);
Expand All @@ -234,6 +237,14 @@ public String getIdForNameByProvider(@PathVariable("namePatternProviderId") Stri

}

@RequestMapping(path = APIConstants.API_ANONYMOUS + "integrationtest/templates/clear-all", method = RequestMethod.POST)
public void clearAllTemplates() {
List<String> templateIds = templateService.fetchAllTemplateIds();
for (String templateId : templateIds) {
templateService.deleteTemplate(templateId);
}
}

@RequestMapping(path = APIConstants.API_ANONYMOUS + "integrationtest/job/{jobUUID}/pds/uuids", method = RequestMethod.GET)
public List<UUID> getPDSJobUUIDSForSecHubJOob(@PathVariable("jobUUID") UUID sechubJob) {
List<UUID> list = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ public class ScanProjectConfig {
public static final String QUERY_FIND_ALL_DATA_FOR_CONFIG_ID = "SELECT c." + PROPERTY_DATA + " FROM ScanProjectConfig c where c." + PROPERTY_KEY + "."
+ ScanProjectConfigCompositeKey.PROPERTY_CONFIG_ID + " =:configId";

public static final String QUERY_FIND_ALL_PROJECT_IDS_FOR_SET_OF_CONFIG_IDS_AND_DATA = "SELECT c." + PROPERTY_KEY + "."
+ ScanProjectConfigCompositeKey.PROPERTY_PROJECT_ID + " FROM ScanProjectConfig c where c." + PROPERTY_KEY + "."
+ ScanProjectConfigCompositeKey.PROPERTY_CONFIG_ID + " in :configIds AND c." + PROPERTY_DATA + " =:data";

@EmbeddedId
ScanProjectConfigCompositeKey key;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,7 @@ public interface ScanProjectConfigRepository extends JpaRepository<ScanProjectCo
@Query(value = ScanProjectConfig.QUERY_FIND_ALL_DATA_FOR_CONFIG_ID)
List<String> findAllDataForConfigId(@Param("configId") String configId);

@Query(value = ScanProjectConfig.QUERY_FIND_ALL_PROJECT_IDS_FOR_SET_OF_CONFIG_IDS_AND_DATA)
Set<String> findAllProjectsWhereConfigurationHasGivenData(@Param("configIds") Set<String> configIds, @Param("data") String data);

}
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,18 @@ public void deleteAllConfigurationsOfGivenConfigIdsAndValue(Set<String> configId
repository.deleteAllConfigurationsOfGivenConfigIdsAndValue(configIds, value);
}

public List<String> findAllData(ScanProjectConfigID scanConfigType) {
return repository.findAllDataForConfigId(scanConfigType.getId());
/**
* Find all data for given configuration identifier
*
* @param configId
* @return all data inside a list, never <code>null</code>
*/
public List<String> findAllData(ScanProjectConfigID configId) {
return repository.findAllDataForConfigId(configId.getId());
}

public Set<String> findAllProjectsWhereConfigurationHasGivenData(Set<String> possibleConfigIds, String data) {
return repository.findAllProjectsWhereConfigurationHasGivenData(possibleConfigIds, data);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.mercedesbenz.sechub.commons.model.template.TemplateDataResolver;
import com.mercedesbenz.sechub.commons.model.template.TemplateDefinition;
import com.mercedesbenz.sechub.commons.model.template.TemplateType;
import com.mercedesbenz.sechub.sharedkernel.ProductIdentifier;

@Component
/**
Expand Down Expand Up @@ -85,4 +86,17 @@ public boolean isScanTypeSupportingTemplate(ScanType scanType, TemplateDefinitio
return false;
}

public boolean isProductAbleToHandleTemplates(ProductIdentifier productIdentifier) {
if (productIdentifier == null) {
return false;
}
if (productIdentifier.name().startsWith("PDS")) {
/*
* The PDS server implementation is always same and is able to handle templates.
*/
return true;
}
return false;
}

}
Loading

0 comments on commit 1c7578d

Please sign in to comment.