diff options
author | Sourabh Sourabh <sourabh.sourabh@est.tech> | 2024-08-29 09:48:19 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2024-08-29 09:48:19 +0000 |
commit | 5514e69a41af3b53997906fe77de9fd662ace568 (patch) | |
tree | e6528604680a702430388fb2da6e4b0265a5c640 /cps-ncmp-service/src/test/groovy/org/onap | |
parent | 607a8563a6e9b935c6feb2604ae0752a07a91895 (diff) | |
parent | a05ca3d3152de44ac3078e2455834dedb5789b1b (diff) |
Merge "Invoke Policy Executor and handle not-allowed response"
Diffstat (limited to 'cps-ncmp-service/src/test/groovy/org/onap')
4 files changed, 144 insertions, 29 deletions
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/DmiHttpClientConfigSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/DmiHttpClientConfigSpec.groovy index e0ae204c8d..23f5edd890 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/DmiHttpClientConfigSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/DmiHttpClientConfigSpec.groovy @@ -29,7 +29,7 @@ import spock.lang.Specification @SpringBootTest @ContextConfiguration(classes = [DmiHttpClientConfig]) -@EnableConfigurationProperties(DmiHttpClientConfig) +@EnableConfigurationProperties class DmiHttpClientConfigSpec extends Specification { @Autowired diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/PolicyExecutorHttpClientConfigSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/PolicyExecutorHttpClientConfigSpec.groovy index 1946a452b1..ca71c345c1 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/PolicyExecutorHttpClientConfigSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/PolicyExecutorHttpClientConfigSpec.groovy @@ -34,7 +34,7 @@ class PolicyExecutorHttpClientConfigSpec extends Specification { @Autowired PolicyExecutorHttpClientConfig policyExecutorHttpClientConfig - def 'Test http client configuration properties of data with custom and default values'() { + def 'Http client configuration properties for policy executor http client.'() { expect: 'properties are populated correctly for all services' with(policyExecutorHttpClientConfig.allServices) { assert maximumInMemorySizeInMegabytes == 31 diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/PolicyExecutorConfigurationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/PolicyExecutorConfigurationSpec.groovy new file mode 100644 index 0000000000..c086eab810 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/PolicyExecutorConfigurationSpec.groovy @@ -0,0 +1,45 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.impl.data + +import org.onap.cps.ncmp.config.PolicyExecutorHttpClientConfig +import org.onap.cps.ncmp.impl.data.policyexecutor.PolicyExecutor +import org.onap.cps.ncmp.impl.policyexecutor.PolicyExecutorWebClientConfiguration +import org.onap.cps.ncmp.utils.WebClientBuilderTestConfig +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.ContextConfiguration +import spock.lang.Specification + +@SpringBootTest +@ContextConfiguration(classes = [PolicyExecutor, PolicyExecutorWebClientConfiguration, PolicyExecutorHttpClientConfig, WebClientBuilderTestConfig ]) +class PolicyExecutorConfigurationSpec extends Specification { + + @Autowired + PolicyExecutor objectUnderTest + + def 'Policy executor configuration properties.'() { + expect: 'properties used from application.yml' + assert objectUnderTest.enabled + assert objectUnderTest.serverAddress == 'http://localhost' + assert objectUnderTest.serverPort == '8785' + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/PolicyExecutorSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/PolicyExecutorSpec.groovy index 4b09afa2ae..a5776676dc 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/PolicyExecutorSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/PolicyExecutorSpec.groovy @@ -1,69 +1,139 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + package org.onap.cps.ncmp.impl.data import ch.qos.logback.classic.Level import ch.qos.logback.classic.Logger import ch.qos.logback.classic.spi.ILoggingEvent import ch.qos.logback.core.read.ListAppender +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.ObjectMapper +import org.onap.cps.ncmp.api.exceptions.PolicyExecutorException +import org.onap.cps.ncmp.api.exceptions.ServerNcmpException import org.onap.cps.ncmp.impl.data.policyexecutor.PolicyExecutor import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle import org.slf4j.LoggerFactory -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.test.context.ContextConfiguration +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity +import org.springframework.web.reactive.function.client.WebClient +import reactor.core.publisher.Mono import spock.lang.Specification +import static org.onap.cps.ncmp.api.data.models.OperationType.CREATE +import static org.onap.cps.ncmp.api.data.models.OperationType.DELETE import static org.onap.cps.ncmp.api.data.models.OperationType.PATCH +import static org.onap.cps.ncmp.api.data.models.OperationType.UPDATE -@SpringBootTest -@ContextConfiguration(classes = [PolicyExecutor]) class PolicyExecutorSpec extends Specification { - @Autowired - PolicyExecutor objectUnderTest + def mockWebClient = Mock(WebClient) + def mockRequestBodyUriSpec = Mock(WebClient.RequestBodyUriSpec) + def mockResponseSpec = Mock(WebClient.ResponseSpec) + + PolicyExecutor objectUnderTest = new PolicyExecutor(mockWebClient) def logAppender = Spy(ListAppender<ILoggingEvent>) + ObjectMapper objectMapper = new ObjectMapper() + def setup() { setupLogger() + objectUnderTest.enabled = true + mockWebClient.post() >> mockRequestBodyUriSpec + mockRequestBodyUriSpec.uri(*_) >> mockRequestBodyUriSpec + mockRequestBodyUriSpec.header(*_) >> mockRequestBodyUriSpec + mockRequestBodyUriSpec.body(*_) >> mockRequestBodyUriSpec + mockRequestBodyUriSpec.retrieve() >> mockResponseSpec } def cleanup() { ((Logger) LoggerFactory.getLogger(PolicyExecutor)).detachAndStopAllAppenders() } - def 'Configuration properties.'() { - expect: 'properties used from application.yml' - assert objectUnderTest.enabled - assert objectUnderTest.serverAddress == 'http://localhost' - assert objectUnderTest.serverPort == '8785' + def 'Permission check with allow response.'() { + given: 'allow response' + mockResponse([decision:'allow'], HttpStatus.OK) + when: 'permission is checked for an operation' + objectUnderTest.checkPermission(new YangModelCmHandle(), operationType, 'my credentials','my resource','my change') + then: 'system logs the operation is allowed' + assert getLogEntry(2) == 'Policy Executor allows the operation' + and: 'no exception occurs' + noExceptionThrown() + where: 'all write operations are tested' + operationType << [ CREATE, DELETE, PATCH, UPDATE ] + } + + def 'Permission check with other response (not allowed).'() { + given: 'other response' + mockResponse([decision:'other', decisionId:123, message:'I dont like Mondays' ], HttpStatus.OK) + when: 'permission is checked for an operation' + objectUnderTest.checkPermission(new YangModelCmHandle(), PATCH, 'my credentials','my resource','my change') + then: 'Policy Executor exception is thrown' + def thrownException = thrown(PolicyExecutorException) + assert thrownException.message == 'Policy Executor did not allow request. Decision #123 : other' + assert thrownException.details == 'I dont like Mondays' + } + + def 'Permission check with non 2xx response.'() { + given: 'other response' + mockResponse([], HttpStatus.I_AM_A_TEAPOT) + when: 'permission is checked for an operation' + objectUnderTest.checkPermission(new YangModelCmHandle(), PATCH, 'my credentials','my resource','my change') + then: 'Server Ncmp exception is thrown' + def thrownException = thrown(ServerNcmpException) + assert thrownException.message == 'Policy Executor invocation failed' + assert thrownException.details == 'HTTP status code: 418' } - def 'Permission check logging.'() { + def 'Permission check with invalid response from Policy Executor.'() { + given: 'invalid response from Policy executor' + mockResponseSpec.toEntity(*_) >> invalidResponse when: 'permission is checked for an operation' - def yangModelCmHandle = new YangModelCmHandle(id:'ch-1', alternateId:'fdn1') - objectUnderTest.checkPermission(yangModelCmHandle, PATCH, 'my credentials','my resource','my change') - then: 'correct details are logged ' - assert getLogEntry(0) == 'Policy Executor Enabled' - assert getLogEntry(3).contains('my credentials') - assert getLogEntry(4).contains('cm_patch') - assert getLogEntry(5).contains('fdn1') - assert getLogEntry(6).contains('ch-1') - assert getLogEntry(7).contains('my resource') - assert getLogEntry(8).contains('my change') + objectUnderTest.checkPermission(new YangModelCmHandle(), CREATE, 'my credentials','my resource','my change') + then: 'system logs the expected message' + assert getLogEntry(1) == expectedMessage + where: 'following invalid responses are received' + invalidResponse || expectedMessage + Mono.empty() || 'No valid response from policy, ignored' + Mono.just(new ResponseEntity<>(null, HttpStatus.OK)) || 'No valid response body from policy, ignored' } - def 'Permission check with feature disabled.'() { + def 'Permission check feature disabled.'() { given: 'feature is disabled' objectUnderTest.enabled = false when: 'permission is checked for an operation' objectUnderTest.checkPermission(new YangModelCmHandle(), PATCH, 'my credentials','my resource','my change') - then: 'nothing is logged' - assert logAppender.list.isEmpty() + then: 'system logs that the feature not enabled' + assert getLogEntry(0) == 'Policy Executor Enabled: false' + } + + def mockResponse(mockResponseAsMap, httpStatus) { + JsonNode jsonNode = objectMapper.readTree(objectMapper.writeValueAsString(mockResponseAsMap)) + def mono = Mono.just(new ResponseEntity<>(jsonNode, httpStatus)) + mockResponseSpec.toEntity(*_) >> mono } def setupLogger() { def logger = LoggerFactory.getLogger(PolicyExecutor) - logger.setLevel(Level.DEBUG) + logger.setLevel(Level.TRACE) logger.addAppender(logAppender) logAppender.start() } |