diff options
-rw-r--r-- | cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/policyexecutor/PolicyExecutor.java | 13 | ||||
-rw-r--r-- | cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/policyexecutor/PolicyExecutorConfigurationSpec.groovy (renamed from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/PolicyExecutorConfigurationSpec.groovy) | 6 | ||||
-rw-r--r-- | cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/policyexecutor/PolicyExecutorSpec.groovy (renamed from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/PolicyExecutorSpec.groovy) | 30 | ||||
-rw-r--r-- | k6-tests/ncmp/common/utils.js | 9 | ||||
-rw-r--r-- | k6-tests/ncmp/ncmp-kpi.js | 9 | ||||
-rwxr-xr-x | k6-tests/ncmp/run-all-tests.sh | 4 |
6 files changed, 40 insertions, 31 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/policyexecutor/PolicyExecutor.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/policyexecutor/PolicyExecutor.java index 89b48f3755..b3aa848394 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/policyexecutor/PolicyExecutor.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/policyexecutor/PolicyExecutor.java @@ -20,7 +20,9 @@ package org.onap.cps.ncmp.impl.data.policyexecutor; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -28,6 +30,7 @@ import java.util.Map; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.onap.cps.ncmp.api.data.models.OperationType; +import org.onap.cps.ncmp.api.exceptions.NcmpException; import org.onap.cps.ncmp.api.exceptions.PolicyExecutorException; import org.onap.cps.ncmp.api.exceptions.ServerNcmpException; import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle; @@ -58,6 +61,8 @@ public class PolicyExecutor { @Qualifier("policyExecutorWebClient") private final WebClient policyExecutorWebClient; + private final ObjectMapper objectMapper; + /** * Use the Policy Executor to check permission for a cm write operation. * Wil throw an exception when the operation is not permitted (work in progress) @@ -108,7 +113,13 @@ public class PolicyExecutor { data.put("resourceIdentifier", resourceIdentifier); data.put("targetIdentifier", yangModelCmHandle.getAlternateId()); if (!OperationType.DELETE.equals(operationType)) { - data.put("cmChangeRequest", changeRequestAsJson); + try { + final Object changeRequestAsObject = objectMapper.readValue(changeRequestAsJson, Object.class); + data.put("cmChangeRequest", changeRequestAsObject); + } catch (final JsonProcessingException e) { + throw new NcmpException("Cannot convert Change Request data to Object", + "Invalid Json: " + changeRequestAsJson); + } } final Map<String, Object> request = new HashMap<>(2); 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/policyexecutor/PolicyExecutorConfigurationSpec.groovy index c086eab810..c859bb0a09 100644 --- 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/policyexecutor/PolicyExecutorConfigurationSpec.groovy @@ -18,10 +18,10 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.impl.data +package org.onap.cps.ncmp.impl.data.policyexecutor +import com.fasterxml.jackson.databind.ObjectMapper 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 @@ -30,7 +30,7 @@ import org.springframework.test.context.ContextConfiguration import spock.lang.Specification @SpringBootTest -@ContextConfiguration(classes = [PolicyExecutor, PolicyExecutorWebClientConfiguration, PolicyExecutorHttpClientConfig, WebClientBuilderTestConfig ]) +@ContextConfiguration(classes = [ObjectMapper, PolicyExecutor, PolicyExecutorWebClientConfiguration, PolicyExecutorHttpClientConfig, WebClientBuilderTestConfig ]) class PolicyExecutorConfigurationSpec extends Specification { @Autowired 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/policyexecutor/PolicyExecutorSpec.groovy index a5776676dc..63a915ab64 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/policyexecutor/PolicyExecutorSpec.groovy @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.impl.data +package org.onap.cps.ncmp.impl.data.policyexecutor import ch.qos.logback.classic.Level import ch.qos.logback.classic.Logger @@ -26,9 +26,9 @@ 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.NcmpException 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.http.HttpStatus @@ -47,12 +47,13 @@ class PolicyExecutorSpec extends Specification { def mockWebClient = Mock(WebClient) def mockRequestBodyUriSpec = Mock(WebClient.RequestBodyUriSpec) def mockResponseSpec = Mock(WebClient.ResponseSpec) + def spiedObjectMapper = Spy(ObjectMapper) - PolicyExecutor objectUnderTest = new PolicyExecutor(mockWebClient) + PolicyExecutor objectUnderTest = new PolicyExecutor(mockWebClient, spiedObjectMapper) def logAppender = Spy(ListAppender<ILoggingEvent>) - ObjectMapper objectMapper = new ObjectMapper() + def someValidJson = '{"Hello":"World"}' def setup() { setupLogger() @@ -72,7 +73,7 @@ class PolicyExecutorSpec extends Specification { 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') + objectUnderTest.checkPermission(new YangModelCmHandle(), operationType, 'my credentials','my resource',someValidJson) then: 'system logs the operation is allowed' assert getLogEntry(2) == 'Policy Executor allows the operation' and: 'no exception occurs' @@ -85,7 +86,7 @@ class PolicyExecutorSpec extends Specification { 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') + objectUnderTest.checkPermission(new YangModelCmHandle(), PATCH, 'my credentials','my resource',someValidJson) then: 'Policy Executor exception is thrown' def thrownException = thrown(PolicyExecutorException) assert thrownException.message == 'Policy Executor did not allow request. Decision #123 : other' @@ -96,7 +97,7 @@ class PolicyExecutorSpec extends Specification { 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') + objectUnderTest.checkPermission(new YangModelCmHandle(), PATCH, 'my credentials','my resource',someValidJson) then: 'Server Ncmp exception is thrown' def thrownException = thrown(ServerNcmpException) assert thrownException.message == 'Policy Executor invocation failed' @@ -107,7 +108,7 @@ class PolicyExecutorSpec extends Specification { given: 'invalid response from Policy executor' mockResponseSpec.toEntity(*_) >> invalidResponse when: 'permission is checked for an operation' - objectUnderTest.checkPermission(new YangModelCmHandle(), CREATE, 'my credentials','my resource','my change') + objectUnderTest.checkPermission(new YangModelCmHandle(), CREATE, 'my credentials','my resource',someValidJson) then: 'system logs the expected message' assert getLogEntry(1) == expectedMessage where: 'following invalid responses are received' @@ -116,17 +117,26 @@ class PolicyExecutorSpec extends Specification { Mono.just(new ResponseEntity<>(null, HttpStatus.OK)) || 'No valid response body from policy, ignored' } + def 'Permission check with an invalid change request json.'() { + when: 'permission is checked for an invalid change request' + objectUnderTest.checkPermission(new YangModelCmHandle(), CREATE, 'my credentials', 'my resource', 'invalid json string') + then: 'an ncmp exception thrown' + def ncmpException = thrown(NcmpException) + ncmpException.message == 'Cannot convert Change Request data to Object' + ncmpException.details.contains('invalid json string') + } + 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') + objectUnderTest.checkPermission(new YangModelCmHandle(), PATCH, 'my credentials','my resource',someValidJson) 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)) + JsonNode jsonNode = spiedObjectMapper.readTree(spiedObjectMapper.writeValueAsString(mockResponseAsMap)) def mono = Mono.just(new ResponseEntity<>(jsonNode, httpStatus)) mockResponseSpec.toEntity(*_) >> mono } diff --git a/k6-tests/ncmp/common/utils.js b/k6-tests/ncmp/common/utils.js index 43036b1789..98c9eb86f1 100644 --- a/k6-tests/ncmp/common/utils.js +++ b/k6-tests/ncmp/common/utils.js @@ -54,6 +54,7 @@ export function getRandomCmHandleId() { export function makeCustomSummaryReport(data, options) { const summaryCsvLines = [ '#,Test Name,Unit,Limit,Actual', + makeSummaryCsvLine('0', 'HTTP request failures for all tests', 'rate of failed requests', 'http_req_failed', data, options), makeSummaryCsvLine('1', 'Registration of CM-handles', 'CM-handles/second', 'cmhandles_created_per_second', data, options), makeSummaryCsvLine('2', 'De-registration of CM-handles', 'CM-handles/second', 'cmhandles_deleted_per_second', data, options), makeSummaryCsvLine('3', 'CM-handle ID search with Module filter', 'milliseconds', 'id_search_duration', data, options), @@ -62,14 +63,6 @@ export function makeCustomSummaryReport(data, options) { makeSummaryCsvLine('5b', 'NCMP overhead for Synchronous single CM-handle pass-through read with alternate id', 'milliseconds', 'ncmp_overhead_passthrough_read_alt_id', data, options), makeSummaryCsvLine('6', 'NCMP overhead for Synchronous single CM-handle pass-through write', 'milliseconds', 'ncmp_overhead_passthrough_write', data, options), makeSummaryCsvLine('7', 'Data operations batch read', 'events/second', 'data_operations_batch_read_cmhandles_per_second', data, options), - makeSummaryCsvLine('1x', 'Failures of Registration of CM-handles', 'number of failed requests', 'http_req_failed{group:::setup}', data, options), - makeSummaryCsvLine('2x', 'Failures of De-registration of CM-handles', 'number of failed requests', 'http_req_failed{group:::teardown}', data, options), - makeSummaryCsvLine('3x', 'Failures of CM-handle ID search with Module filter', 'number of failed requests', 'http_req_failed{scenario:id_search_module}', data, options), - makeSummaryCsvLine('4x', 'Failures of CM-handle search with Module filter', 'number of failed requests', 'http_req_failed{scenario:cm_search_module}', data, options), - makeSummaryCsvLine('5x', 'Failures of Synchronous single CM-handle pass-through read', 'number of failed requests', 'http_req_failed{scenario:passthrough_read}', data, options), - makeSummaryCsvLine('6x', 'Failures of Synchronous single CM-handle pass-through write', 'number of failed requests', 'http_req_failed{scenario:passthrough_write}', data, options), - makeSummaryCsvLine('7ax', 'Failures of Data operations batch read', 'number of failed requests', 'http_req_failed{scenario:data_operation_send_async_http_request}', data, options), - makeSummaryCsvLine('7bx', 'Failures of Data operations batch read consume kafka responses', 'number of failed requests', 'kafka_reader_error_count{scenario:data_operation_consume_kafka_responses}', data, options), ]; return summaryCsvLines.join('\n') + '\n'; } diff --git a/k6-tests/ncmp/ncmp-kpi.js b/k6-tests/ncmp/ncmp-kpi.js index 16c6f7d2b1..3fc138c4e5 100644 --- a/k6-tests/ncmp/ncmp-kpi.js +++ b/k6-tests/ncmp/ncmp-kpi.js @@ -102,6 +102,7 @@ export const options = { } }, thresholds: { + 'http_req_failed': ['rate == 0'], 'cmhandles_created_per_second': ['avg >= 22'], 'cmhandles_deleted_per_second': ['avg >= 22'], 'ncmp_overhead_passthrough_read': ['avg <= 100'], @@ -110,14 +111,6 @@ export const options = { 'id_search_duration': ['avg <= 625'], 'cm_search_duration': ['avg <= 13000'], 'data_operations_batch_read_cmhandles_per_second': ['avg >= 150'], - 'http_req_failed{scenario:id_search_module}': ['rate == 0'], - 'http_req_failed{scenario:cm_search_module}': ['rate == 0'], - 'http_req_failed{scenario:passthrough_read}': ['rate == 0'], - 'http_req_failed{scenario:passthrough_write}': ['rate == 0'], - 'http_req_failed{group:::setup}':['rate == 0'], - 'http_req_failed{group:::teardown}':['rate == 0'], - 'http_req_failed{scenario:data_operation_send_async_http_request}': ['rate == 0'], - 'kafka_reader_error_count{scenario:data_operation_consume_kafka_responses}': ['count == 0'], }, }; diff --git a/k6-tests/ncmp/run-all-tests.sh b/k6-tests/ncmp/run-all-tests.sh index 2db32ecd76..1fa661a472 100755 --- a/k6-tests/ncmp/run-all-tests.sh +++ b/k6-tests/ncmp/run-all-tests.sh @@ -19,7 +19,9 @@ pushd "$(dirname "$0")" >/dev/null || exit 1 number_of_failures=0 echo "Running K6 performance tests..." -k6 --quiet run ncmp-kpi.js > summary.csv || ((number_of_failures++)) + +# Redirecting stderr to /dev/null to prevent large log files +k6 --quiet run ncmp-kpi.js > summary.csv 2>/dev/null || ((number_of_failures++)) if [ -f summary.csv ]; then |