X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=integration-test%2Fsrc%2Ftest%2Fgroovy%2Forg%2Fonap%2Fcps%2Fintegration%2Fbase%2FCpsIntegrationSpecBase.groovy;h=51b02387edd6098aad6717c6ab381b2172200672;hb=c454bb912798d90ee0d6cb6fc56c8926dc120bb1;hp=b59e0ff553527264a9cbc3a2327726afbeada804;hpb=a3096b9d22b7a3517c7933dfeb10984f6bedf063;p=cps.git diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy index b59e0ff55..51b02387e 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy @@ -20,68 +20,111 @@ package org.onap.cps.integration.base +import java.time.OffsetDateTime +import java.time.format.DateTimeFormatter import org.onap.cps.api.CpsAnchorService import org.onap.cps.api.CpsDataService import org.onap.cps.api.CpsDataspaceService import org.onap.cps.api.CpsModuleService import org.onap.cps.api.CpsQueryService import org.onap.cps.integration.DatabaseTestContainer -import org.onap.cps.spi.config.CpsSessionFactory +import org.onap.cps.integration.KafkaTestContainer +import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService +import org.onap.cps.ncmp.api.NetworkCmProxyDataService +import org.onap.cps.ncmp.api.NetworkCmProxyQueryService +import org.onap.cps.ncmp.api.impl.inventory.CmHandleState +import org.onap.cps.ncmp.api.impl.inventory.sync.ModuleSyncWatchdog +import org.onap.cps.ncmp.api.models.DmiPluginRegistration +import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle import org.onap.cps.spi.exceptions.DataspaceNotFoundException import org.onap.cps.spi.model.DataNode import org.onap.cps.spi.repository.DataspaceRepository -import org.onap.cps.spi.impl.utils.CpsValidatorImpl import org.onap.cps.spi.utils.SessionManager +import org.onap.cps.utils.JsonObjectMapper import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.EnableAutoConfiguration import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc import org.springframework.boot.test.context.SpringBootTest import org.springframework.context.annotation.ComponentScan -import org.springframework.context.annotation.Lazy import org.springframework.data.jpa.repository.config.EnableJpaRepositories +import org.springframework.http.HttpStatus +import org.springframework.http.MediaType +import org.springframework.test.web.client.ExpectedCount +import org.springframework.test.web.client.MockRestServiceServer +import org.springframework.test.web.servlet.MockMvc +import org.springframework.web.client.RestTemplate import org.testcontainers.spock.Testcontainers import spock.lang.Shared import spock.lang.Specification +import spock.util.concurrent.PollingConditions -import java.time.OffsetDateTime +import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME +import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR +import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo +import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus -@SpringBootTest(classes = [TestConfig, CpsValidatorImpl, SessionManager, CpsSessionFactory]) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = [CpsDataspaceService]) @Testcontainers @EnableAutoConfiguration +@AutoConfigureMockMvc @EnableJpaRepositories(basePackageClasses = [DataspaceRepository]) -@ComponentScan(basePackages = ['org.onap.cps.api', 'org.onap.cps.spi.repository']) +@ComponentScan(basePackages = ['org.onap.cps']) @EntityScan('org.onap.cps.spi.entities') -class CpsIntegrationSpecBase extends Specification { +abstract class CpsIntegrationSpecBase extends Specification { @Shared DatabaseTestContainer databaseTestContainer = DatabaseTestContainer.getInstance() + @Shared + KafkaTestContainer kafkaTestContainer = KafkaTestContainer.getInstance() + + @Autowired + MockMvc mvc + @Autowired - @Lazy CpsDataspaceService cpsDataspaceService @Autowired - @Lazy CpsAnchorService cpsAnchorService @Autowired - @Lazy CpsDataService cpsDataService @Autowired - @Lazy CpsModuleService cpsModuleService @Autowired - @Lazy CpsQueryService cpsQueryService @Autowired - @Lazy SessionManager sessionManager - def static GENERAL_TEST_DATASPACE = 'generalTestDataspace' - def static BOOKSTORE_SCHEMA_SET = 'bookstoreSchemaSet' + @Autowired + NetworkCmProxyCmHandleQueryService networkCmProxyCmHandleQueryService + + @Autowired + NetworkCmProxyDataService networkCmProxyDataService + + @Autowired + NetworkCmProxyQueryService networkCmProxyQueryService + + @Autowired + RestTemplate restTemplate + + @Autowired + ModuleSyncWatchdog moduleSyncWatchdog + + @Autowired + JsonObjectMapper jsonObjectMapper + + MockRestServiceServer mockDmiServer = null + + static DMI_URL = 'http://mock-dmi-server' + static NO_MODULE_SET_TAG = '' + static GENERAL_TEST_DATASPACE = 'generalTestDataspace' + static BOOKSTORE_SCHEMA_SET = 'bookstoreSchemaSet' def static initialized = false def now = OffsetDateTime.now() @@ -90,10 +133,17 @@ class CpsIntegrationSpecBase extends Specification { if (!initialized) { cpsDataspaceService.createDataspace(GENERAL_TEST_DATASPACE) createStandardBookStoreSchemaSet(GENERAL_TEST_DATASPACE) - initialized = true; + initialized = true } + mockDmiServer = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build() + } + + def static readResourceDataFile(filename) { + return new File('src/test/resources/data/' + filename).text } + // *** CPS Integration Test Utilities *** + def static countDataNodesInTree(DataNode dataNode) { return 1 + countDataNodesInTree(dataNode.getChildDataNodes()) } @@ -106,10 +156,6 @@ class CpsIntegrationSpecBase extends Specification { return nodeCount } - def static readResourceDataFile(filename) { - return new File('src/test/resources/data/' + filename).text - } - def getBookstoreYangResourcesNameToContentMap() { def bookstoreModelFileContent = readResourceDataFile('bookstore/bookstore.yang') def bookstoreTypesFileContent = readResourceDataFile('bookstore/bookstore-types.yang') @@ -127,7 +173,7 @@ class CpsIntegrationSpecBase extends Specification { def dataspaceExists(dataspaceName) { try { cpsDataspaceService.getDataspace(dataspaceName) - } catch (DataspaceNotFoundException dataspaceNotFoundException) { + } catch (DataspaceNotFoundException ignored) { return false } return true @@ -141,29 +187,58 @@ class CpsIntegrationSpecBase extends Specification { } def createJsonArray(name, numberOfElements, keyName, keyValuePrefix, dataPerKey) { - def json = '{"' + name + '":[' - (1..numberOfElements).each { - json += '{"' + keyName + '":"' + keyValuePrefix + '-' + it + '"' - if (!dataPerKey.isEmpty()) { - json += ',' + dataPerKey - } - json += '}' - if (it < numberOfElements) { - json += ',' - } - } - json += ']}' + def innerJson = (1..numberOfElements).collect { + '{"' + keyName + '":"' + keyValuePrefix + '-' + it + '"' + (dataPerKey.empty? '': ',' + dataPerKey) + '}' + }.join(',') + return '{"' + name + '":[' + innerJson + ']}' } def createLeafList(name, numberOfElements, valuePrefix) { - def json = '"' + name + '":[' - (1..numberOfElements).each { - json += '"' + valuePrefix + '-' + it + '"' - if (it < numberOfElements) { - json += ',' - } - } - json += ']' + def innerJson = (1..numberOfElements).collect {'"' + valuePrefix + '-' + it + '"'}.join(',') + return '"' + name + '":[' + innerJson + ']' + } + + // *** NCMP Integration Test Utilities *** + + def registerCmHandle(dmiPlugin, cmHandleId, moduleSetTag) { + def cmHandleToCreate = new NcmpServiceCmHandle(cmHandleId: cmHandleId, moduleSetTag: moduleSetTag) + networkCmProxyDataService.updateDmiRegistrationAndSyncModule(new DmiPluginRegistration(dmiPlugin: dmiPlugin, createdCmHandles: [cmHandleToCreate])) + moduleSyncWatchdog.moduleSyncAdvisedCmHandles() + new PollingConditions().within(3, () -> { + CmHandleState.READY == networkCmProxyDataService.getCmHandleCompositeState(cmHandleId).cmHandleState + }) } + def deregisterCmHandle(dmiPlugin, cmHandleId) { + deregisterCmHandles(dmiPlugin, [cmHandleId]) + } + + def deregisterCmHandles(dmiPlugin, cmHandleIds) { + networkCmProxyDataService.updateDmiRegistrationAndSyncModule(new DmiPluginRegistration(dmiPlugin: dmiPlugin, removedCmHandles: cmHandleIds)) + } + + def mockDmiResponsesForModuleSync(dmiPlugin, cmHandleId, dmiModuleReferencesResponse, dmiModuleResourcesResponse) { + mockDmiServer.expect(requestTo("${dmiPlugin}/dmi/v1/ch/${cmHandleId}/modules")) + .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON).body(dmiModuleReferencesResponse)) + mockDmiServer.expect(requestTo("${dmiPlugin}/dmi/v1/ch/${cmHandleId}/moduleResources")) + .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON).body(dmiModuleResourcesResponse)) + } + + def mockDmiIsNotAvailableForModuleSync(dmiPlugin, cmHandleId) { + mockDmiServer.expect(requestTo("${dmiPlugin}/dmi/v1/ch/${cmHandleId}/modules")) + .andRespond(withStatus(HttpStatus.SERVICE_UNAVAILABLE)) + } + + def mockDmiWillRespondToHealthChecks(dmiPlugin) { + mockDmiServer.expect(ExpectedCount.between(0, Integer.MAX_VALUE), requestTo("${dmiPlugin}/actuator/health")) + .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON).body('{"status":"UP"}')) + } + + def overrideCmHandleLastUpdateTime(cmHandleId, newUpdateTime) { + String ISO_TIMESTAMP_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; + DateTimeFormatter ISO_TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern(ISO_TIMESTAMP_PATTERN); + def jsonForUpdate = '{ "state": { "last-update-time": "%s" } }'.formatted(ISO_TIMESTAMP_FORMATTER.format(newUpdateTime)) + cpsDataService.updateNodeLeaves(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, + NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='${cmHandleId}']", jsonForUpdate, now) + } }