diff options
Diffstat (limited to 'cps-ncmp-service/src/test')
16 files changed, 315 insertions, 67 deletions
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/async/NcmpAsyncDataOperationEventConsumerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/async/NcmpAsyncDataOperationEventConsumerSpec.groovy index 7f8469aafc..6353288713 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/async/NcmpAsyncDataOperationEventConsumerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/async/NcmpAsyncDataOperationEventConsumerSpec.groovy @@ -92,7 +92,7 @@ class NcmpAsyncDataOperationEventConsumerSpec extends MessagingBaseSpec { response.operationId == 'some-operation-id' response.statusCode == 'any-success-status-code' response.statusMessage == 'Successfully applied changes' - response.responseContent as String == '[some-key:some-value]' + response.result as String == '[some-key:some-value]' } def 'Filter an event with type #eventType'() { @@ -110,7 +110,7 @@ class NcmpAsyncDataOperationEventConsumerSpec extends MessagingBaseSpec { def createConsumerRecord(eventTypeAsString) { def jsonData = TestUtils.getResourceFileContent('dataOperationEvent.json') - def testEventSentAsBytes = objectMapper.writeValueAsBytes(jsonObjectMapper.convertJsonString(jsonData, DataOperationEvent.class)) + def testEventSentAsBytes = jsonObjectMapper.asJsonBytes(jsonObjectMapper.convertJsonString(jsonData, DataOperationEvent.class)) CloudEvent cloudEvent = getCloudEvent(eventTypeAsString, testEventSentAsBytes) diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/EventPublisherSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/EventPublisherSpec.groovy new file mode 100644 index 0000000000..59a43caf9e --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/EventPublisherSpec.groovy @@ -0,0 +1,86 @@ +/* + * ============LICENSE_START======================================================== + * Copyright (c) 2023 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.api.impl.events + +import ch.qos.logback.classic.Level +import ch.qos.logback.classic.Logger +import ch.qos.logback.core.read.ListAppender +import org.apache.kafka.clients.producer.ProducerRecord +import org.apache.kafka.clients.producer.RecordMetadata +import org.apache.kafka.common.TopicPartition +import org.onap.cps.ncmp.init.SubscriptionModelLoader +import org.slf4j.LoggerFactory +import org.springframework.kafka.support.SendResult +import spock.lang.Specification + +class EventPublisherSpec extends Specification { + + def objectUnderTest = new EventsPublisher(null, null) + def logger = (Logger) LoggerFactory.getLogger(objectUnderTest.getClass()) + def loggingListAppender + + void setup() { + logger.setLevel(Level.DEBUG) + loggingListAppender = new ListAppender() + logger.addAppender(loggingListAppender) + loggingListAppender.start() + } + + void cleanup() { + ((Logger) LoggerFactory.getLogger(SubscriptionModelLoader.class)).detachAndStopAllAppenders() + } + + def 'Callback handling on success.'() { + given: 'a send result' + def producerRecord = new ProducerRecord('topic-1', 'my value') + def topicPartition = new TopicPartition('topic-2', 0) + def recordMetadata = new RecordMetadata(topicPartition, 0, 0, 0, 0, 0) + def sendResult = new SendResult(producerRecord, recordMetadata) + when: 'the callback handler processes success' + def callbackHandler = objectUnderTest.handleCallback('topic-3') + callbackHandler.onSuccess(sendResult) + then: 'an event is logged with level DEBUG' + def loggingEvent = getLoggingEvent() + loggingEvent.level == Level.DEBUG + and: 'it contains the topic (from the record metadata) and the "value" (from the producer record)' + loggingEvent.formattedMessage.contains('topic-2') + loggingEvent.formattedMessage.contains('my value') + } + + + def 'Callback handling on failure.'() { + when: 'the callback handler processes a failure' + def callbackHandler = objectUnderTest.handleCallback('my topic') + callbackHandler.onFailure(new Exception('my exception')) + then: 'an event is logged with level ERROR' + def loggingEvent = getLoggingEvent() + loggingEvent.level == Level.ERROR + and: 'it contains the topic and exception message' + loggingEvent.formattedMessage.contains('my topic') + loggingEvent.formattedMessage.contains('my exception') + } + + def getLoggingEvent() { + return loggingListAppender.list[0] + } + + +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avc/AvcEventConsumerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avc/AvcEventConsumerSpec.groovy index 5cc70e2809..22852bea43 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avc/AvcEventConsumerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avc/AvcEventConsumerSpec.groovy @@ -55,9 +55,6 @@ class AvcEventConsumerSpec extends MessagingBaseSpec { @Autowired JsonObjectMapper jsonObjectMapper - @Autowired - ObjectMapper objectMapper - def cloudEventKafkaConsumer = new KafkaConsumer<>(eventConsumerConfigProperties('ncmp-group', CloudEventDeserializer)) def 'Consume and forward valid message'() { @@ -69,7 +66,7 @@ class AvcEventConsumerSpec extends MessagingBaseSpec { def jsonData = TestUtils.getResourceFileContent('sampleAvcInputEvent.json') def testEventSent = jsonObjectMapper.convertJsonString(jsonData, AvcEvent.class) def testCloudEventSent = CloudEventBuilder.v1() - .withData(objectMapper.writeValueAsBytes(testEventSent)) + .withData(jsonObjectMapper.asJsonBytes(testEventSent)) .withId('sample-eventid') .withType('sample-test-type') .withSource(URI.create('sample-test-source')) diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avc/SubscriptionEventMapperSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avc/SubscriptionEventMapperSpec.groovy index f2ff1f7b23..6d02ac719e 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avc/SubscriptionEventMapperSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avc/SubscriptionEventMapperSpec.groovy @@ -60,7 +60,7 @@ class SubscriptionEventMapperSpec extends Specification { assert result.topic == null } - def 'Map null subscription event to yang model subscription event where #scenario'() { + def 'Map empty subscription event to yang model subscription event'() { given: 'a new Subscription Event with no data' def testEventToMap = new SubscriptionEvent() when: 'the event is mapped to a yang model subscription' @@ -76,5 +76,4 @@ class SubscriptionEventMapperSpec extends Specification { and: 'the topic is null' assert result.topic == null } - }
\ No newline at end of file diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarderSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarderSpec.groovy index a9eaaee916..41597edec8 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarderSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarderSpec.groovy @@ -23,8 +23,12 @@ package org.onap.cps.ncmp.api.impl.events.avcsubscription import com.fasterxml.jackson.databind.ObjectMapper import com.hazelcast.map.IMap import org.apache.kafka.clients.consumer.ConsumerRecord +import org.mapstruct.factory.Mappers import org.onap.cps.ncmp.api.impl.events.EventsPublisher +import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistence +import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle +import org.onap.cps.ncmp.api.impl.yangmodels.YangModelSubscriptionEvent.TargetCmHandle import org.onap.cps.ncmp.api.inventory.InventoryPersistence import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec import org.onap.cps.ncmp.event.model.SubscriptionEvent @@ -52,6 +56,10 @@ class SubscriptionEventForwarderSpec extends MessagingBaseSpec { IMap<String, Set<String>> mockForwardedSubscriptionEventCache = Mock(IMap<String, Set<String>>) @SpringBean SubscriptionEventResponseOutcome mockSubscriptionEventResponseOutcome = Mock(SubscriptionEventResponseOutcome) + @SpringBean + SubscriptionPersistence mockSubscriptionPersistence = Mock(SubscriptionPersistence) + @SpringBean + SubscriptionEventMapper subscriptionEventMapper = Mappers.getMapper(SubscriptionEventMapper) @Autowired JsonObjectMapper jsonObjectMapper @@ -60,11 +68,17 @@ class SubscriptionEventForwarderSpec extends MessagingBaseSpec { def jsonData = TestUtils.getResourceFileContent('avcSubscriptionCreationEvent.json') def testEventSent = jsonObjectMapper.convertJsonString(jsonData, SubscriptionEvent.class) def consumerRecord = new ConsumerRecord<String, SubscriptionEvent>('topic-name', 0, 0, 'event-key', testEventSent) + and: 'the some of the cm handles will be accepted and some of rejected' + def cmHandlesToBeSavedInDb = [new TargetCmHandle('CMHandle1', SubscriptionStatus.ACCEPTED), + new TargetCmHandle('CMHandle2',SubscriptionStatus.ACCEPTED), + new TargetCmHandle('CMHandle3',SubscriptionStatus.REJECTED)] + and: 'a yang model subscription event will be saved into the db' + def yangModelSubscriptionEventWithAcceptedAndRejectedCmHandles = subscriptionEventMapper.toYangModelSubscriptionEvent(testEventSent) + yangModelSubscriptionEventWithAcceptedAndRejectedCmHandles.getPredicates().setTargetCmHandles(cmHandlesToBeSavedInDb) and: 'the InventoryPersistence returns private properties for the supplied CM Handles' 1 * mockInventoryPersistence.getYangModelCmHandles(["CMHandle1", "CMHandle2", "CMHandle3"]) >> [ createYangModelCmHandleWithDmiProperty(1, 1,"shape","circle"), - createYangModelCmHandleWithDmiProperty(2, 1,"shape","square"), - createYangModelCmHandleWithDmiProperty(3, 2,"shape","triangle") + createYangModelCmHandleWithDmiProperty(2, 1,"shape","square") ] and: 'the thread creation delay is reduced to 2 seconds for testing' objectUnderTest.dmiResponseTimeoutInMs = 2000 @@ -75,7 +89,7 @@ class SubscriptionEventForwarderSpec extends MessagingBaseSpec { then: 'An asynchronous call is made to the blocking variable' block.get() then: 'the event is added to the forwarded subscription event cache' - 1 * mockForwardedSubscriptionEventCache.put("SCO-9989752cm-subscription-001", ["DMIName1", "DMIName2"] as Set, 600, TimeUnit.SECONDS) + 1 * mockForwardedSubscriptionEventCache.put("SCO-9989752cm-subscription-001", ["DMIName1"] as Set, 600, TimeUnit.SECONDS) and: 'the event is forwarded twice with the CMHandle private properties and provides a valid listenable future' 1 * mockSubscriptionEventPublisher.publishEvent("ncmp-dmi-cm-avc-subscription-DMIName1", "SCO-9989752-cm-subscription-001-DMIName1", consumerRecord.headers(), subscriptionEvent -> { @@ -84,22 +98,13 @@ class SubscriptionEventForwarderSpec extends MessagingBaseSpec { targets["CMHandle2"] == ["shape":"square"] } ) - 1 * mockSubscriptionEventPublisher.publishEvent("ncmp-dmi-cm-avc-subscription-DMIName2", "SCO-9989752-cm-subscription-001-DMIName2", - consumerRecord.headers(), subscriptionEvent -> { - Map targets = subscriptionEvent.getEvent().getPredicates().getTargets().get(0) - targets["CMHandle3"] == ["shape":"triangle"] - } - ) + and: 'the persistence service save the yang model subscription event' + 1 * mockSubscriptionPersistence.saveSubscriptionEvent(yangModelSubscriptionEventWithAcceptedAndRejectedCmHandles) and: 'a separate thread has been created where the map is polled' 1 * mockForwardedSubscriptionEventCache.containsKey("SCO-9989752cm-subscription-001") >> true - 1 * mockForwardedSubscriptionEventCache.get(_) >> DMINamesInMap 1 * mockSubscriptionEventResponseOutcome.sendResponse(*_) and: 'the subscription id is removed from the event cache map returning the asynchronous blocking variable' 1 * mockForwardedSubscriptionEventCache.remove("SCO-9989752cm-subscription-001") >> {block.set(_)} - where: - scenario | DMINamesInMap - 'there are dmis which have not responded' | ["DMIName1", "DMIName2"] as Set - 'all dmis have responded' | [] as Set } def 'Forward CM create subscription where target CM Handles are #scenario'() { @@ -125,6 +130,13 @@ class SubscriptionEventForwarderSpec extends MessagingBaseSpec { def jsonData = TestUtils.getResourceFileContent('avcSubscriptionCreationEvent.json') def testEventSent = jsonObjectMapper.convertJsonString(jsonData, SubscriptionEvent.class) def consumerRecord = new ConsumerRecord<String, SubscriptionEvent>('topic-name', 0, 0, 'event-key', testEventSent) + and: 'the cm handles will be rejected' + def rejectedCmHandles = [new TargetCmHandle('CMHandle1', SubscriptionStatus.REJECTED), + new TargetCmHandle('CMHandle2',SubscriptionStatus.REJECTED), + new TargetCmHandle('CMHandle3',SubscriptionStatus.REJECTED)] + and: 'a yang model subscription event will be saved into the db with rejected cm handles' + def yangModelSubscriptionEventWithRejectedCmHandles = subscriptionEventMapper.toYangModelSubscriptionEvent(testEventSent) + yangModelSubscriptionEventWithRejectedCmHandles.getPredicates().setTargetCmHandles(rejectedCmHandles) and: 'the InventoryPersistence returns no private properties for the supplied CM Handles' 1 * mockInventoryPersistence.getYangModelCmHandles(["CMHandle1", "CMHandle2", "CMHandle3"]) >> [] and: 'the thread creation delay is reduced to 2 seconds for testing' @@ -135,7 +147,7 @@ class SubscriptionEventForwarderSpec extends MessagingBaseSpec { objectUnderTest.forwardCreateSubscriptionEvent(testEventSent, consumerRecord.headers()) then: 'the event is not added to the forwarded subscription event cache' 0 * mockForwardedSubscriptionEventCache.put("SCO-9989752cm-subscription-001", ["DMIName1", "DMIName2"] as Set) - and: 'the event is forwarded twice with the CMHandle private properties and provides a valid listenable future' + and: 'the event is not being forwarded with the CMHandle private properties and does not provides a valid listenable future' 0 * mockSubscriptionEventPublisher.publishEvent("ncmp-dmi-cm-avc-subscription-DMIName1", "SCO-9989752-cm-subscription-001-DMIName1", consumerRecord.headers(),subscriptionEvent -> { Map targets = subscriptionEvent.getEvent().getPredicates().getTargets().get(0) @@ -154,8 +166,10 @@ class SubscriptionEventForwarderSpec extends MessagingBaseSpec { 0 * mockForwardedSubscriptionEventCache.get(_) and: 'the subscription id is removed from the event cache map returning the asynchronous blocking variable' 0 * mockForwardedSubscriptionEventCache.remove("SCO-9989752cm-subscription-001") >> {block.set(_)} + and: 'the persistence service save target cm handles of the yang model subscription event as rejected ' + 1 * mockSubscriptionPersistence.saveSubscriptionEvent(yangModelSubscriptionEventWithRejectedCmHandles) and: 'subscription outcome has been sent' - 1 * mockSubscriptionEventResponseOutcome.sendResponse('SCO-9989752', 'cm-subscription-001', true) + 1 * mockSubscriptionEventResponseOutcome.sendResponse('SCO-9989752', 'cm-subscription-001') } static def createYangModelCmHandleWithDmiProperty(id, dmiId,propertyName, propertyValue) { diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseConsumerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseConsumerSpec.groovy index 26bb7e78ee..5355dd8b9a 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseConsumerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseConsumerSpec.groovy @@ -26,6 +26,7 @@ import org.apache.kafka.clients.consumer.ConsumerRecord import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistenceImpl import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec import org.onap.cps.ncmp.api.models.SubscriptionEventResponse +import org.onap.cps.spi.model.DataNodeBuilder import org.onap.cps.utils.JsonObjectMapper import org.springframework.boot.test.context.SpringBootTest @@ -50,6 +51,13 @@ class SubscriptionEventResponseConsumerSpec extends MessagingBaseSpec { objectUnderTest.notificationFeatureEnabled = isNotificationFeatureEnabled and: 'subscription model loader is enabled' objectUnderTest.subscriptionModelLoaderEnabled = true + and: 'a data node exist in db' + def leaves1 = [status:'ACCEPTED', cmHandleId:'cmhandle1'] as Map + def dataNode = new DataNodeBuilder().withDataspace('NCMP-Admin') + .withAnchor('AVC-Subscriptions').withXpath('/subscription-registry/subscription') + .withLeaves(leaves1).build() + and: 'subscription persistence service returns data node' + mockSubscriptionPersistence.getCmHandlesForSubscriptionEvent(*_) >> [dataNode] when: 'the valid event is consumed' objectUnderTest.consumeSubscriptionEventResponse(consumerRecord) then: 'the forwarded subscription event cache returns only the received dmiName existing for the subscription create event' @@ -58,15 +66,13 @@ class SubscriptionEventResponseConsumerSpec extends MessagingBaseSpec { and: 'the forwarded subscription event cache returns an empty Map when the dmiName has been removed' 1 * mockForwardedSubscriptionEventCache.get('some-client-idsome-subscription-name') >> ([] as Set) and: 'the subscription event is removed from the map' - 1 * mockForwardedSubscriptionEventCache.remove('some-client-idsome-subscription-name') + numberOfExpectedCallToRemove * mockForwardedSubscriptionEventCache.remove('some-client-idsome-subscription-name') and: 'a response outcome has been created' - numberOfExpectedCallToSendResponse * mockSubscriptionEventResponseOutcome.sendResponse('some-client-id', 'some-subscription-name', isFullOutcomeResponse) + numberOfExpectedCallToSendResponse * mockSubscriptionEventResponseOutcome.sendResponse('some-client-id', 'some-subscription-name') where: 'the following values are used' - scenario | isNotificationFeatureEnabled | isFullOutcomeResponse || numberOfExpectedCallToSendResponse - 'Response sent' | true | true || 1 - 'Response not sent' | true | false || 0 - 'Response not sent' | false | true || 0 - 'Response not sent' | false | false || 0 + scenario | isNotificationFeatureEnabled || numberOfExpectedCallToRemove || numberOfExpectedCallToSendResponse + 'Response sent' | true || 1 || 1 + 'Response not sent' | false || 0 || 0 } def 'Consume Subscription Event Response where another DMI has not yet responded'() { diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseOutcomeSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseOutcomeSpec.groovy index 3570a9e366..bb0e7b73a0 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseOutcomeSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseOutcomeSpec.groovy @@ -21,9 +21,11 @@ package org.onap.cps.ncmp.api.impl.events.avcsubscription import com.fasterxml.jackson.databind.ObjectMapper +import org.apache.kafka.common.header.internals.RecordHeaders import org.mapstruct.factory.Mappers import org.onap.cps.ncmp.api.impl.events.EventsPublisher import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistence +import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus import org.onap.cps.ncmp.api.impl.utils.DataNodeBaseSpec import org.onap.cps.ncmp.events.avc.subscription.v1.SubscriptionEventOutcome import org.onap.cps.ncmp.utils.TestUtils @@ -48,22 +50,47 @@ class SubscriptionEventResponseOutcomeSpec extends DataNodeBaseSpec { @Autowired JsonObjectMapper jsonObjectMapper + def 'Send response to the client apps successfully'() { + given: 'a subscription client id and subscription name' + def clientId = 'some-client-id' + def subscriptionName = 'some-subscription-name' + and: 'the persistence service return a data node' + mockSubscriptionPersistence.getCmHandlesForSubscriptionEvent(*_) >> [dataNode4] + and: 'the response is being generated from the db' + def eventOutcome = objectUnderTest.generateResponse(clientId, subscriptionName) + when: 'the response is being sent' + objectUnderTest.sendResponse(clientId, subscriptionName) + then: 'the publisher publish the response with expected parameters' + 1 * mockSubscriptionEventOutcomePublisher.publishEvent('cm-avc-subscription-response', clientId + subscriptionName, new RecordHeaders(), eventOutcome) + } + + def 'Check cm handle id to status map to see if it is a full outcome response'() { + when: 'is full outcome response evaluated' + def response = objectUnderTest.isFullOutcomeResponse(cmHandleIdToStatusMap) + then: 'the result will be as expected' + response == expectedResult + where: 'the following values are used' + scenario | cmHandleIdToStatusMap || expectedResult + 'The map contains PENDING status' | ['CMHandle1': SubscriptionStatus.PENDING] as Map || false + 'The map contains ACCEPTED status' | ['CMHandle1': SubscriptionStatus.ACCEPTED] as Map || true + 'The map contains REJECTED status' | ['CMHandle1': SubscriptionStatus.REJECTED] as Map || true + 'The map contains PENDING and ACCEPTED statuses' | ['CMHandle1': SubscriptionStatus.PENDING,'CMHandle2': SubscriptionStatus.ACCEPTED] as Map || false + 'The map contains REJECTED and ACCEPTED statuses' | ['CMHandle1': SubscriptionStatus.REJECTED,'CMHandle2': SubscriptionStatus.ACCEPTED] as Map || true + 'The map contains PENDING and REJECTED statuses' | ['CMHandle1': SubscriptionStatus.PENDING,'CMHandle2': SubscriptionStatus.REJECTED] as Map || false + } + def 'Generate response via fetching data nodes from database.'() { given: 'a db call to get data nodes for subscription event' - 1 * mockSubscriptionPersistence.getDataNodesForSubscriptionEvent() >> [dataNode4] + 1 * mockSubscriptionPersistence.getCmHandlesForSubscriptionEvent(*_) >> [dataNode4] when: 'a response is generated' - def result = objectUnderTest.generateResponse('some-client-id', 'some-subscription-name', isFullOutcomeResponse) + def result = objectUnderTest.generateResponse('some-client-id', 'some-subscription-name') then: 'the result will have the same values as same as in dataNode4' - result.eventType == expectedEventType + result.eventType == SubscriptionEventOutcome.EventType.PARTIAL_OUTCOME result.getEvent().getSubscription().getClientID() == 'some-client-id' result.getEvent().getSubscription().getName() == 'some-subscription-name' result.getEvent().getPredicates().getPendingTargets() == ['CMHandle3'] result.getEvent().getPredicates().getRejectedTargets() == ['CMHandle1'] result.getEvent().getPredicates().getAcceptedTargets() == ['CMHandle2'] - where: 'the following values are used' - scenario | isFullOutcomeResponse || expectedEventType - 'is full outcome' | true || SubscriptionEventOutcome.EventType.COMPLETE_OUTCOME - 'is partial outcome' | false || SubscriptionEventOutcome.EventType.PARTIAL_OUTCOME } def 'Form subscription outcome message with a list of cm handle id to status mapping'() { diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionOutcomeMapperSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionOutcomeMapperSpec.groovy index b05e983c03..7f1a628291 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionOutcomeMapperSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionOutcomeMapperSpec.groovy @@ -57,4 +57,5 @@ class SubscriptionOutcomeMapperSpec extends Specification { 'is full outcome' || SubscriptionEventOutcome.EventType.COMPLETE_OUTCOME 'is partial outcome' || SubscriptionEventOutcome.EventType.PARTIAL_OUTCOME } + }
\ No newline at end of file diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerImplSpec.groovy index bfebc44bae..261b6e069d 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerImplSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerImplSpec.groovy @@ -63,7 +63,7 @@ class LcmEventsCmHandleStateHandlerImplSpec extends Specification { 'ADVISED to ADVISED' | ADVISED | ADVISED || 0 | 0 'READY to READY' | READY | READY || 0 | 0 'LOCKED to LOCKED' | LOCKED | LOCKED || 0 | 0 - + 'DELETED to ADVISED' | DELETED | ADVISED || 0 | 1 } def 'Update and Publish Events on State Change from NO_EXISTING state to ADVISED'() { @@ -94,6 +94,17 @@ class LcmEventsCmHandleStateHandlerImplSpec extends Specification { 1 * mockLcmEventsService.publishLcmEvent(cmHandleId, _, _) } + def 'Update and Publish Events on State Change from DELETING to ADVISED'() { + given: 'Cm Handle represented as YangModelCmHandle in DELETING state' + yangModelCmHandle = new YangModelCmHandle(id: cmHandleId, dmiProperties: [], publicProperties: [], compositeState: compositeState) + when: 'update state is invoked' + objectUnderTest.updateCmHandleState(yangModelCmHandle, ADVISED) + then: 'the cm handle is saved using inventory persistence' + 1 * mockInventoryPersistence.saveCmHandle(yangModelCmHandle) + and: 'event service is called to publish event' + 1 * mockLcmEventsService.publishLcmEvent(cmHandleId, _, _) + } + def 'Update and Publish Events on State Change to READY'() { given: 'Cm Handle represented as YangModelCmHandle' compositeState = new CompositeState(cmHandleState: ADVISED) @@ -167,7 +178,7 @@ class LcmEventsCmHandleStateHandlerImplSpec extends Specification { assert (args[0] as Collection<YangModelCmHandle>).id.containsAll('cmhandle1', 'cmhandle2') } } - and: 'event service is called to publish event' + and: 'event service is called to publish events' 2 * mockLcmEventsService.publishLcmEvent(_, _, _) } @@ -183,9 +194,23 @@ class LcmEventsCmHandleStateHandlerImplSpec extends Specification { assert (args[0] as Map<String, CompositeState>).keySet().containsAll(['cmhandle1','cmhandle2']) } } - and: 'event service is called to publish event' + and: 'event service is called to publish events' 2 * mockLcmEventsService.publishLcmEvent(_, _, _) + } + def 'Batch of existing cm handles is deleted'() { + given: 'A batch of deleted cm handles' + def cmHandleStateMap = setupBatch('DELETED') + when: 'updating a batch of changes' + objectUnderTest.updateCmHandleStateBatch(cmHandleStateMap) + then : 'existing cm handles composite state is persisted' + 1 * mockInventoryPersistence.saveCmHandleStateBatch(_) >> { + args -> { + assert (args[0] as Map<String, CompositeState>).isEmpty() + } + } + and: 'event service is called to publish events' + 2 * mockLcmEventsService.publishLcmEvent(_, _, _) } def setupBatch(type) { @@ -197,6 +222,12 @@ class LcmEventsCmHandleStateHandlerImplSpec extends Specification { return [(yangModelCmHandle1): ADVISED, (yangModelCmHandle2): ADVISED] } + if ('DELETED' == type) { + yangModelCmHandle1.compositeState = new CompositeState(cmHandleState: READY) + yangModelCmHandle2.compositeState = new CompositeState(cmHandleState: READY) + return [(yangModelCmHandle1): DELETED, (yangModelCmHandle2): DELETED] + } + if ('UPDATE' == type) { yangModelCmHandle1.compositeState = new CompositeState(cmHandleState: ADVISED) yangModelCmHandle2.compositeState = new CompositeState(cmHandleState: READY) @@ -209,4 +240,4 @@ class LcmEventsCmHandleStateHandlerImplSpec extends Specification { return [(yangModelCmHandle1): ADVISED, (yangModelCmHandle2): READY] } } -}
\ No newline at end of file +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy index c7ee4e0745..59e62e34d0 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy @@ -23,8 +23,11 @@ package org.onap.cps.ncmp.api.impl.operations import com.fasterxml.jackson.databind.ObjectMapper import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration +import org.onap.cps.ncmp.api.impl.events.EventsPublisher import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder +import org.onap.cps.ncmp.api.impl.utils.context.CpsApplicationContext import org.onap.cps.ncmp.api.models.DataOperationRequest +import org.onap.cps.ncmp.event.model.NcmpAsyncRequestResponseEvent import org.onap.cps.ncmp.utils.TestUtils import org.onap.cps.utils.JsonObjectMapper import org.spockframework.spring.SpringBean @@ -42,7 +45,7 @@ import static org.onap.cps.ncmp.api.impl.operations.OperationType.READ import static org.onap.cps.ncmp.api.impl.operations.OperationType.UPDATE @SpringBootTest -@ContextConfiguration(classes = [NcmpConfiguration.DmiProperties, DmiDataOperations]) +@ContextConfiguration(classes = [EventsPublisher, CpsApplicationContext, NcmpConfiguration.DmiProperties, DmiDataOperations]) class DmiDataOperationsSpec extends DmiOperationsBaseSpec { @SpringBean @@ -59,6 +62,9 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec { @Autowired DmiDataOperations objectUnderTest + @SpringBean + EventsPublisher eventsPublisher = Stub() + def 'call get resource data for #expectedDatastoreInUrl from DMI without topic #scenario.'() { given: 'a cm handle for #cmHandleId' mockYangModelCmHandleRetrieval(dmiProperties) diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeHelperSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeHelperSpec.groovy index ee726a908e..819f1fa08e 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeHelperSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeHelperSpec.groovy @@ -70,4 +70,17 @@ class DataNodeHelperSpec extends DataNodeBaseSpec { result.keySet() == ['CMHandle3', 'CMHandle2', 'CMHandle1'] as Set result.values() as List == [SubscriptionStatus.PENDING, SubscriptionStatus.ACCEPTED, SubscriptionStatus.REJECTED] } + + + def 'Get cm handle id to status map as expected from a nested data node.'() { + given: 'a nested data node' + def dataNode = new DataNodeBuilder().withDataspace('NCMP-Admin') + .withAnchor('AVC-Subscriptions').withXpath('/subscription-registry/subscription') + .withLeaves([clientID:'SCO-9989752', isTagged:false, subscriptionName:'cm-subscription-001']) + .withChildDataNodes([dataNode4]).build() + when:'cm handle id to status is being extracted' + def result = DataNodeHelper.getCmHandleIdToStatusMapFromDataNodes([dataNode]); + then: 'the keys are retrieved as expected' + result.keySet() == ['CMHandle3','CMHandle2','CMHandle1'] as Set + } } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/context/CpsApplicationContextSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/context/CpsApplicationContextSpec.groovy new file mode 100644 index 0000000000..b7fa449251 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/context/CpsApplicationContextSpec.groovy @@ -0,0 +1,19 @@ +package org.onap.cps.ncmp.api.impl.utils.context + +import com.fasterxml.jackson.databind.ObjectMapper +import org.onap.cps.utils.JsonObjectMapper +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.ContextConfiguration +import spock.lang.Specification; + +@SpringBootTest(classes = [ObjectMapper, JsonObjectMapper]) +@ContextConfiguration(classes = [CpsApplicationContext.class]) +class CpsApplicationContextSpec extends Specification { + + def 'Verify if cps application context contains a requested bean.'() { + when: 'cps bean is requested from application context' + def jsonObjectMapper = CpsApplicationContext.getCpsBean(JsonObjectMapper.class) + then: 'requested bean of JsonObjectMapper is not null' + assert jsonObjectMapper != null + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataOperationRequestUtilsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/data/operation/ResourceDataOperationRequestUtilsSpec.groovy index 334b455ef7..401254f546 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataOperationRequestUtilsSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/data/operation/ResourceDataOperationRequestUtilsSpec.groovy @@ -18,23 +18,46 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.impl.utils +package org.onap.cps.ncmp.api.impl.utils.data.operation import com.fasterxml.jackson.databind.ObjectMapper +import io.cloudevents.CloudEvent +import io.cloudevents.core.CloudEventUtils +import io.cloudevents.jackson.PojoCloudEventDataMapper +import io.cloudevents.kafka.CloudEventDeserializer +import io.cloudevents.kafka.impl.KafkaHeaders +import org.apache.kafka.clients.consumer.KafkaConsumer +import org.onap.cps.ncmp.api.impl.events.EventsPublisher +import org.onap.cps.ncmp.api.impl.utils.context.CpsApplicationContext import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle import org.onap.cps.ncmp.api.inventory.CmHandleState import org.onap.cps.ncmp.api.inventory.CompositeStateBuilder +import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec import org.onap.cps.ncmp.api.models.DataOperationRequest +import org.onap.cps.ncmp.events.async1_0_0.DataOperationEvent import org.onap.cps.ncmp.utils.TestUtils import org.onap.cps.utils.JsonObjectMapper import org.spockframework.spring.SpringBean -import spock.lang.Specification +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.test.context.ContextConfiguration +import java.time.Duration -class DataOperationRequestUtilsSpec extends Specification { +@ContextConfiguration(classes = [EventsPublisher, CpsApplicationContext, ObjectMapper]) +class ResourceDataOperationRequestUtilsSpec extends MessagingBaseSpec { + + def cloudEventKafkaConsumer = new KafkaConsumer<>(eventConsumerConfigProperties('test', CloudEventDeserializer)) + def static clientTopic = 'my-topic-name' + def static dataOperationType = 'org.onap.cps.ncmp.events.async1_0_0.DataOperationEvent' @SpringBean JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) + @SpringBean + EventsPublisher eventPublisher = new EventsPublisher<CloudEvent>(legacyEventKafkaTemplate, cloudEventKafkaTemplate) + + @Autowired + ObjectMapper objectMapper + def 'Process per data operation request with #serviceName.'() { given: 'data operation request with 3 operations' def dataOperationRequestJsonData = TestUtils.getResourceFileContent('dataOperationRequest.json') @@ -42,7 +65,7 @@ class DataOperationRequestUtilsSpec extends Specification { and: '4 known cm handles: ch1-dmi1, ch2-dmi1, ch3-dmi2, ch4-dmi2' def yangModelCmHandles = getYangModelCmHandles() when: 'data operation request is processed' - def operationsOutPerDmiServiceName = ResourceDataOperationRequestUtils.processPerDefinitionInDataOperationsRequest(dataOperationRequest, yangModelCmHandles) + def operationsOutPerDmiServiceName = ResourceDataOperationRequestUtils.processPerDefinitionInDataOperationsRequest(clientTopic,'request-id', dataOperationRequest, yangModelCmHandles) and: 'converted to a json node' def dmiDataOperationRequestBody = jsonObjectMapper.asJsonString(operationsOutPerDmiServiceName.get(serviceName)) def dmiDataOperationRequestBodyAsJsonNode = jsonObjectMapper.convertToJsonNode(dmiDataOperationRequestBody).get(operationIndex) @@ -65,9 +88,37 @@ class DataOperationRequestUtilsSpec extends Specification { 'dmi2' | 2 || 'operational-15' | 'ncmp-datastore:passthrough-operational' | ['ch4-dmi2'] } + def 'Process per data operation request with non-ready, non-existing cm handle and publish event to client specified topic'() { + given: 'consumer subscribing to client topic' + cloudEventKafkaConsumer.subscribe([clientTopic]) + and: 'data operation request having non-ready and non-existing cm handle ids' + def dataOperationRequestJsonData = TestUtils.getResourceFileContent('dataOperationRequest.json') + def dataOperationRequest = jsonObjectMapper.convertJsonString(dataOperationRequestJsonData, DataOperationRequest.class) + when: 'data operation request is processed' + ResourceDataOperationRequestUtils.processPerDefinitionInDataOperationsRequest(clientTopic, 'request-id', dataOperationRequest, yangModelCmHandles) + and: 'subscribed client specified topic is polled and first record is selected' + def consumerRecordOut = cloudEventKafkaConsumer.poll(Duration.ofMillis(1500))[0] + then: 'verify cloud compliant headers' + def consumerRecordOutHeaders = consumerRecordOut.headers() + assert KafkaHeaders.getParsedKafkaHeader(consumerRecordOutHeaders, 'ce_id') != null + assert KafkaHeaders.getParsedKafkaHeader(consumerRecordOutHeaders, 'ce_type') == dataOperationType + and: 'verify that extension is included into header' + assert KafkaHeaders.getParsedKafkaHeader(consumerRecordOutHeaders, 'ce_correlationid') == 'request-id' + assert KafkaHeaders.getParsedKafkaHeader(consumerRecordOutHeaders, 'ce_destination') == clientTopic + and: 'map consumer record to expected event type' + def dataOperationResponseEvent = CloudEventUtils.mapData(consumerRecordOut.value(), + PojoCloudEventDataMapper.from(objectMapper, DataOperationEvent.class)).getValue() + and: 'data operation response event response size is 3' + dataOperationResponseEvent.data.responses.size() == 3 + and: 'verify published response data as json string' + jsonObjectMapper.asJsonString(dataOperationResponseEvent.data.responses) + == '[{"operationId":"operational-14","ids":["unknown-cm-handle"],"statusCode":"100","statusMessage":"cm handle id(s) not found"},{"operationId":"operational-14","ids":["non-ready-cm handle"],"statusCode":"101","statusMessage":"cm handle(s) not ready"},{"operationId":"running-12","ids":["non-ready-cm handle"],"statusCode":"101","statusMessage":"cm handle(s) not ready"}]' + } + static def getYangModelCmHandles() { def dmiProperties = [new YangModelCmHandle.Property('prop', 'some DMI property')] def readyState = new CompositeStateBuilder().withCmHandleState(CmHandleState.READY).withLastUpdatedTimeNow().build() + def advisedState = new CompositeStateBuilder().withCmHandleState(CmHandleState.ADVISED).withLastUpdatedTimeNow().build() return [new YangModelCmHandle(id: 'ch1-dmi1', dmiServiceName: 'dmi1', dmiProperties: dmiProperties, compositeState: readyState), new YangModelCmHandle(id: 'ch2-dmi1', dmiServiceName: 'dmi1', dmiProperties: dmiProperties, compositeState: readyState), new YangModelCmHandle(id: 'ch6-dmi1', dmiServiceName: 'dmi1', dmiProperties: dmiProperties, compositeState: readyState), @@ -75,6 +126,7 @@ class DataOperationRequestUtilsSpec extends Specification { new YangModelCmHandle(id: 'ch3-dmi2', dmiServiceName: 'dmi2', dmiProperties: dmiProperties, compositeState: readyState), new YangModelCmHandle(id: 'ch4-dmi2', dmiServiceName: 'dmi2', dmiProperties: dmiProperties, compositeState: readyState), new YangModelCmHandle(id: 'ch7-dmi2', dmiServiceName: 'dmi2', dmiProperties: dmiProperties, compositeState: readyState), + new YangModelCmHandle(id: 'non-ready-cm handle', dmiServiceName: 'dmi2', dmiProperties: dmiProperties, compositeState: advisedState) ] } } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/SubscriptionModelLoaderSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/SubscriptionModelLoaderSpec.groovy index a14a0f286c..b4e7813db9 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/SubscriptionModelLoaderSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/SubscriptionModelLoaderSpec.groovy @@ -23,8 +23,6 @@ package org.onap.cps.ncmp.init import ch.qos.logback.classic.Level import ch.qos.logback.classic.Logger import ch.qos.logback.core.read.ListAppender -import org.junit.jupiter.api.AfterEach -import org.junit.jupiter.api.BeforeEach import org.onap.cps.api.CpsAdminService import org.onap.cps.api.CpsDataService import org.onap.cps.api.CpsModuleService @@ -53,22 +51,19 @@ class SubscriptionModelLoaderSpec extends Specification { def applicationReadyEvent = new ApplicationReadyEvent(new SpringApplication(), null, applicationContext, null) def yangResourceToContentMap - def logger - def appender + def logger = (Logger) LoggerFactory.getLogger(objectUnderTest.getClass()) + def loggingListAppender - @BeforeEach void setup() { yangResourceToContentMap = objectUnderTest.createYangResourceToContentMap() - logger = (Logger) LoggerFactory.getLogger(objectUnderTest.getClass()) - appender = new ListAppender() logger.setLevel(Level.DEBUG) - appender.start() - logger.addAppender(appender) + loggingListAppender = new ListAppender() + logger.addAppender(loggingListAppender) + loggingListAppender.start() applicationContext.refresh() } - @AfterEach - void teardown() { + void cleanup() { ((Logger) LoggerFactory.getLogger(SubscriptionModelLoader.class)).detachAndStopAllAppenders() applicationContext.close() } @@ -123,7 +118,7 @@ class SubscriptionModelLoaderSpec extends Specification { and: 'the data service to create a top level datanode was not called' 0 * mockCpsDataService.saveData(*_) and: 'the log message contains the correct exception message' - def logs = appender.list.toString() + def logs = loggingListAppender.list.toString() assert logs.contains("Retrieval of NCMP dataspace fails") } @@ -168,7 +163,7 @@ class SubscriptionModelLoaderSpec extends Specification { when: 'the method to onboard model is called' objectUnderTest.onboardSubscriptionModel(yangResourceToContentMap) then: 'the log message contains the correct exception message' - def debugMessage = appender.list[0].toString() + def debugMessage = loggingListAppender.list[0].toString() assert debugMessage.contains("Creating schema set failed") and: 'exception is thrown' thrown(NcmpStartUpException) @@ -183,7 +178,7 @@ class SubscriptionModelLoaderSpec extends Specification { then: 'no exception thrown' noExceptionThrown() and: 'the log message contains the correct exception message' - def infoMessage = appender.list[0].toString() + def infoMessage = loggingListAppender.list[0].toString() assert infoMessage.contains("already exists") } @@ -194,7 +189,7 @@ class SubscriptionModelLoaderSpec extends Specification { when: 'the method to onboard model is called' objectUnderTest.onboardSubscriptionModel(yangResourceToContentMap) then: 'the log message contains the correct exception message' - def debugMessage = appender.list[0].toString() + def debugMessage = loggingListAppender.list[0].toString() assert debugMessage.contains("Schema Set not found") and: 'exception is thrown' thrown(NcmpStartUpException) @@ -209,7 +204,7 @@ class SubscriptionModelLoaderSpec extends Specification { then: 'no exception thrown' noExceptionThrown() and: 'the log message contains the correct exception message' - def infoMessage = appender.list[0].toString() + def infoMessage = loggingListAppender.list[0].toString() assert infoMessage.contains("already exists") } @@ -220,7 +215,7 @@ class SubscriptionModelLoaderSpec extends Specification { when: 'the method to onboard model is called' objectUnderTest.onboardSubscriptionModel(yangResourceToContentMap) then: 'the log message contains the correct exception message' - def debugMessage = appender.list[0].toString() + def debugMessage = loggingListAppender.list[0].toString() assert debugMessage.contains("Creating data node for subscription model failed: Invalid JSON") and: 'exception is thrown' thrown(NcmpStartUpException) diff --git a/cps-ncmp-service/src/test/resources/dataOperationEvent.json b/cps-ncmp-service/src/test/resources/dataOperationEvent.json index 0a32f38c0a..08a58b39b9 100644 --- a/cps-ncmp-service/src/test/resources/dataOperationEvent.json +++ b/cps-ncmp-service/src/test/resources/dataOperationEvent.json @@ -8,7 +8,7 @@ ], "statusCode": "any-success-status-code", "statusMessage": "Successfully applied changes", - "responseContent": { + "result": { "some-key": "some-value" } } diff --git a/cps-ncmp-service/src/test/resources/dataOperationRequest.json b/cps-ncmp-service/src/test/resources/dataOperationRequest.json index 98ed39b9ae..d2e0d64892 100644 --- a/cps-ncmp-service/src/test/resources/dataOperationRequest.json +++ b/cps-ncmp-service/src/test/resources/dataOperationRequest.json @@ -9,7 +9,8 @@ "targetIds": [ "ch3-dmi2", "unknown-cm-handle", - "ch6-dmi1" + "ch6-dmi1", + "non-ready-cm handle" ] }, { @@ -19,7 +20,8 @@ "targetIds": [ "ch1-dmi1", "ch7-dmi2", - "ch2-dmi1" + "ch2-dmi1", + "non-ready-cm handle" ] }, { |