aboutsummaryrefslogtreecommitdiffstats
path: root/cps-service/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'cps-service/src/test')
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy23
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdateEventFactorySpec.groovy10
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy61
3 files changed, 68 insertions, 26 deletions
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
index ba9c156d7..6c899c793 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* Copyright (C) 2021 Nordix Foundation
* Modifications Copyright (C) 2021 Pantheon.tech
- * Modifications Copyright (C) 2021 Bell Canada.
+ * Modifications Copyright (C) 2021-2022 Bell Canada.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@ import org.onap.cps.TestUtils
import org.onap.cps.api.CpsAdminService
import org.onap.cps.api.CpsModuleService
import org.onap.cps.notification.NotificationService
+import org.onap.cps.notification.Operation
import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.exceptions.DataValidationException
@@ -40,7 +41,6 @@ import java.time.OffsetDateTime
class CpsDataServiceImplSpec extends Specification {
def mockCpsDataPersistenceService = Mock(CpsDataPersistenceService)
def mockCpsAdminService = Mock(CpsAdminService)
- def mockCpsModuleService = Mock(CpsModuleService)
def mockYangTextSchemaSourceSetCache = Mock(YangTextSchemaSourceSetCache)
def mockNotificationService = Mock(NotificationService)
@@ -49,7 +49,6 @@ class CpsDataServiceImplSpec extends Specification {
def setup() {
objectUnderTest.cpsDataPersistenceService = mockCpsDataPersistenceService
objectUnderTest.cpsAdminService = mockCpsAdminService
- objectUnderTest.cpsModuleService = mockCpsModuleService
objectUnderTest.yangTextSchemaSourceSetCache = mockYangTextSchemaSourceSetCache
objectUnderTest.notificationService = mockNotificationService
}
@@ -69,7 +68,7 @@ class CpsDataServiceImplSpec extends Specification {
1 * mockCpsDataPersistenceService.storeDataNode(dataspaceName, anchorName,
{ dataNode -> dataNode.xpath == '/test-tree' })
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, '/', Operation.CREATE)
}
def 'Saving child data fragment under existing node.'() {
@@ -82,7 +81,7 @@ class CpsDataServiceImplSpec extends Specification {
1 * mockCpsDataPersistenceService.addChildDataNode(dataspaceName, anchorName, '/test-tree',
{ dataNode -> dataNode.xpath == '/test-tree/branch[@name=\'New\']' })
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, '/test-tree', Operation.CREATE)
}
def 'Saving list element data fragment under existing node.'() {
@@ -102,7 +101,7 @@ class CpsDataServiceImplSpec extends Specification {
}
)
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, '/test-tree', Operation.UPDATE)
}
def 'Saving empty list element data fragment.'() {
@@ -134,7 +133,7 @@ class CpsDataServiceImplSpec extends Specification {
then: 'the persistence service method is invoked with correct parameters'
1 * mockCpsDataPersistenceService.updateDataLeaves(dataspaceName, anchorName, expectedNodeXpath, leaves)
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, parentNodeXpath, Operation.UPDATE)
where: 'following parameters were used'
scenario | parentNodeXpath | jsonData || expectedNodeXpath | leaves
'top level node' | '/' | '{"test-tree": {"branch": []}}' || '/test-tree' | Collections.emptyMap()
@@ -167,7 +166,7 @@ class CpsDataServiceImplSpec extends Specification {
1 * mockCpsDataPersistenceService.updateDataLeaves(dataspaceName, anchorName,
"/dmi-registry/cm-handles[@id='cmHandle001']", ['id': 'cmHandle001'])
and: 'the data updated event is sent to the notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, '/dmi-registry', Operation.UPDATE)
}
def 'Replace data node: #scenario.'() {
@@ -179,7 +178,7 @@ class CpsDataServiceImplSpec extends Specification {
1 * mockCpsDataPersistenceService.replaceDataNodeTree(dataspaceName, anchorName,
{ dataNode -> dataNode.xpath == expectedNodeXpath })
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, parentNodeXpath, Operation.UPDATE)
where: 'following parameters were used'
scenario | parentNodeXpath | jsonData || expectedNodeXpath
'top level node' | '/' | '{"test-tree": {"branch": []}}' || '/test-tree'
@@ -203,7 +202,7 @@ class CpsDataServiceImplSpec extends Specification {
}
)
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, '/test-tree', Operation.UPDATE)
}
def 'Replace whole list content with empty list element.'() {
@@ -224,7 +223,7 @@ class CpsDataServiceImplSpec extends Specification {
then: 'the persistence service method is invoked with correct parameters'
1 * mockCpsDataPersistenceService.deleteListDataNode(dataspaceName, anchorName, '/test-tree/branch')
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, '/test-tree/branch', Operation.DELETE)
}
def 'Delete data node under anchor and dataspace.'() {
@@ -235,7 +234,7 @@ class CpsDataServiceImplSpec extends Specification {
then: 'the persistence service method is invoked with the correct parameters'
1 * mockCpsDataPersistenceService.deleteDataNode(dataspaceName, anchorName, '/data-node')
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, '/data-node', Operation.DELETE)
}
def setupSchemaSetMocks(String... yangResources) {
diff --git a/cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdateEventFactorySpec.groovy b/cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdateEventFactorySpec.groovy
index aa0c7c0b3..67ed3d90f 100644
--- a/cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdateEventFactorySpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdateEventFactorySpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (c) 2021 Bell Canada.
+ * Copyright (c) 2021-2022 Bell Canada.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import java.time.format.DateTimeFormatter
import org.onap.cps.utils.DateTimeUtility
import org.onap.cps.api.CpsAdminService
import org.onap.cps.api.CpsDataService
+import org.onap.cps.event.model.Content
import org.onap.cps.event.model.Data
import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.model.Anchor
@@ -45,7 +46,6 @@ class CpsDataUpdateEventFactorySpec extends Specification {
def dateTimeFormat = 'yyyy-MM-dd\'T\'HH:mm:ss.SSSZ'
def 'Create a CPS data updated event successfully: #scenario'() {
-
given: 'cps admin service is able to return anchor details'
mockCpsAdminService.getAnchor(myDataspaceName, myAnchorName) >>
new Anchor(myAnchorName, myDataspaceName, mySchemasetName)
@@ -54,13 +54,10 @@ class CpsDataUpdateEventFactorySpec extends Specification {
def dataNode = new DataNodeBuilder().withXpath(xpath).withLeaves(['leafName': 'leafValue']).build()
mockCpsDataService.getDataNode(
myDataspaceName, myAnchorName, xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
-
when: 'CPS data updated event is created'
def cpsDataUpdatedEvent = objectUnderTest.createCpsDataUpdatedEvent(myDataspaceName,
- myAnchorName, DateTimeUtility.toOffsetDateTime(inputObservedTimestamp))
-
+ myAnchorName, DateTimeUtility.toOffsetDateTime(inputObservedTimestamp), Operation.CREATE)
then: 'CPS data updated event is created with correct envelope'
-
with(cpsDataUpdatedEvent) {
type == 'org.onap.cps.data-updated-event'
source == new URI('urn:cps:org.onap.cps')
@@ -79,6 +76,7 @@ class CpsDataUpdateEventFactorySpec extends Specification {
assert anchorName == myAnchorName
assert dataspaceName == myDataspaceName
assert schemaSetName == mySchemasetName
+ assert operation == Content.Operation.CREATE
assert data == new Data().withAdditionalProperty('leafName', 'leafValue')
}
where:
diff --git a/cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy
index ca704edb4..306e187a0 100644
--- a/cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (c) 2021 Bell Canada.
+ * Copyright (c) 2021-2022 Bell Canada.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -61,7 +61,7 @@ class NotificationServiceSpec extends Specification {
given: 'notification is disabled'
spyNotificationProperties.isEnabled() >> false
when: 'dataUpdatedEvent is received'
- objectUnderTest.processDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp)
+ objectUnderTest.processDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp, '/', Operation.CREATE)
then: 'the notification is not sent'
0 * mockNotificationPublisher.sendNotification(_)
}
@@ -71,10 +71,12 @@ class NotificationServiceSpec extends Specification {
spyNotificationProperties.isEnabled() >> true
and: 'event factory can create event successfully'
def cpsDataUpdatedEvent = new CpsDataUpdatedEvent()
- mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(dataspaceName, myAnchorName, myObservedTimestamp) >>
- cpsDataUpdatedEvent
+ mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(dataspaceName, myAnchorName, myObservedTimestamp,
+ Operation.CREATE) >>
+ cpsDataUpdatedEvent
when: 'dataUpdatedEvent is received'
- def future = objectUnderTest.processDataUpdatedEvent(dataspaceName, myAnchorName, myObservedTimestamp)
+ def future = objectUnderTest.processDataUpdatedEvent(dataspaceName, myAnchorName, myObservedTimestamp,
+ '/', Operation.CREATE)
and: 'wait for async processing to complete'
future.get(10, TimeUnit.SECONDS)
then: 'async process completed successfully'
@@ -87,14 +89,57 @@ class NotificationServiceSpec extends Specification {
'dataspace name matches filter' | myDataspacePublishedName || 1
}
+ def 'Send UPDATE operation when non-root data nodes are changed.'() {
+ given: 'notification is enabled'
+ spyNotificationProperties.isEnabled() >> true
+ and: 'event factory creates event if operation is UPDATE'
+ def cpsDataUpdatedEvent = new CpsDataUpdatedEvent()
+ mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp,
+ Operation.UPDATE) >> cpsDataUpdatedEvent
+ when: 'dataUpdatedEvent is received for non-root xpath'
+ def future = objectUnderTest.processDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp, '/non-root-node',
+ operation)
+ and: 'wait for async processing to complete'
+ future.get(10, TimeUnit.SECONDS)
+ then: 'async process completed successfully'
+ future.isDone()
+ and: 'notification is sent'
+ 1 * mockNotificationPublisher.sendNotification(cpsDataUpdatedEvent)
+ where:
+ operation << [Operation.CREATE, Operation.UPDATE, Operation.DELETE]
+ }
+
+ def 'Send same operation when root nodes are changed.'() {
+ given: 'notification is enabled'
+ spyNotificationProperties.isEnabled() >> true
+ and: 'event factory creates event if operation is #operation'
+ def cpsDataUpdatedEvent = new CpsDataUpdatedEvent()
+ mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp,
+ operation) >> cpsDataUpdatedEvent
+ when: 'dataUpdatedEvent is received for root xpath'
+ def future = objectUnderTest.processDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp, '/',
+ operation)
+ and: 'wait for async processing to complete'
+ future.get(10, TimeUnit.SECONDS)
+ then: 'async process completed successfully'
+ future.isDone()
+ and: 'notification is sent'
+ 1 * mockNotificationPublisher.sendNotification(cpsDataUpdatedEvent)
+ where:
+ operation << [Operation.CREATE, Operation.UPDATE, Operation.DELETE]
+ }
+
+
def 'Error handling in notification service.'() {
given: 'notification is enabled'
spyNotificationProperties.isEnabled() >> true
and: 'event factory can not create event successfully'
- mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp) >>
- { throw new Exception("Could not create event") }
+ mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(myDataspacePublishedName, myAnchorName,
+ myObservedTimestamp, Operation.CREATE) >>
+ { throw new Exception("Could not create event") }
when: 'event is sent for processing'
- def future = objectUnderTest.processDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp)
+ def future = objectUnderTest.processDataUpdatedEvent(myDataspacePublishedName, myAnchorName,
+ myObservedTimestamp, '/', Operation.CREATE)
and: 'wait for async processing to complete'
future.get(10, TimeUnit.SECONDS)
then: 'async process completed successfully'