aboutsummaryrefslogtreecommitdiffstats
path: root/cps-service/src/test/groovy/org
diff options
context:
space:
mode:
Diffstat (limited to 'cps-service/src/test/groovy/org')
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy75
-rwxr-xr-xcps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy6
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdateEventFactorySpec.groovy37
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy17
4 files changed, 80 insertions, 55 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 97eac5aaa9..6a0a4649a6 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
@@ -22,6 +22,7 @@
package org.onap.cps.api.impl
+import java.time.OffsetDateTime
import org.onap.cps.TestUtils
import org.onap.cps.api.CpsAdminService
import org.onap.cps.api.CpsModuleService
@@ -55,18 +56,19 @@ class CpsDataServiceImplSpec extends Specification {
def dataspaceName = 'some dataspace'
def anchorName = 'some anchor'
def schemaSetName = 'some schema set'
+ def observedTimestamp = OffsetDateTime.now()
def 'Saving json data.'() {
given: 'schema set for given anchor and dataspace references test-tree model'
setupSchemaSetMocks('test-tree.yang')
when: 'save data method is invoked with test-tree json data'
def jsonData = TestUtils.getResourceFileContent('test-tree.json')
- objectUnderTest.saveData(dataspaceName, anchorName, jsonData)
+ objectUnderTest.saveData(dataspaceName, anchorName, jsonData, observedTimestamp)
then: 'the persistence service method is invoked with correct parameters'
1 * mockCpsDataPersistenceService.storeDataNode(dataspaceName, anchorName,
- { dataNode -> dataNode.xpath == '/test-tree' })
+ { dataNode -> dataNode.xpath == '/test-tree' })
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
}
def 'Saving child data fragment under existing node.'() {
@@ -74,12 +76,12 @@ class CpsDataServiceImplSpec extends Specification {
setupSchemaSetMocks('test-tree.yang')
when: 'save data method is invoked with test-tree json data'
def jsonData = '{"branch": [{"name": "New"}]}'
- objectUnderTest.saveData(dataspaceName, anchorName, '/test-tree', jsonData)
+ objectUnderTest.saveData(dataspaceName, anchorName, '/test-tree', jsonData, observedTimestamp)
then: 'the persistence service method is invoked with correct parameters'
1 * mockCpsDataPersistenceService.addChildDataNode(dataspaceName, anchorName, '/test-tree',
- { dataNode -> dataNode.xpath == '/test-tree/branch[@name=\'New\']' })
+ { dataNode -> dataNode.xpath == '/test-tree/branch[@name=\'New\']' })
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
}
def 'Saving list-node data fragment under existing node.'() {
@@ -87,19 +89,19 @@ class CpsDataServiceImplSpec extends Specification {
setupSchemaSetMocks('test-tree.yang')
when: 'save data method is invoked with list-node json data'
def jsonData = '{"branch": [{"name": "A"}, {"name": "B"}]}'
- objectUnderTest.saveListNodeData(dataspaceName, anchorName, '/test-tree', jsonData)
+ objectUnderTest.saveListNodeData(dataspaceName, anchorName, '/test-tree', jsonData, observedTimestamp)
then: 'the persistence service method is invoked with correct parameters'
1 * mockCpsDataPersistenceService.addListDataNodes(dataspaceName, anchorName, '/test-tree',
- { dataNodeCollection ->
- {
- assert dataNodeCollection.size() == 2
- assert dataNodeCollection.collect { it.getXpath() }
- .containsAll(['/test-tree/branch[@name=\'A\']', '/test-tree/branch[@name=\'B\']'])
- }
+ { dataNodeCollection ->
+ {
+ assert dataNodeCollection.size() == 2
+ assert dataNodeCollection.collect { it.getXpath() }
+ .containsAll(['/test-tree/branch[@name=\'A\']', '/test-tree/branch[@name=\'B\']'])
}
+ }
)
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
}
def 'Saving empty list-node data fragment.'() {
@@ -107,7 +109,7 @@ class CpsDataServiceImplSpec extends Specification {
setupSchemaSetMocks('test-tree.yang')
when: 'save data method is invoked with empty list-node data fragment'
def jsonData = '{"branch": []}'
- objectUnderTest.saveListNodeData(dataspaceName, anchorName, '/test-tree', jsonData)
+ objectUnderTest.saveListNodeData(dataspaceName, anchorName, '/test-tree', jsonData, observedTimestamp)
then: 'invalid data exception is thrown'
thrown(DataValidationException)
}
@@ -127,11 +129,11 @@ class CpsDataServiceImplSpec extends Specification {
given: 'schema set for given anchor and dataspace references test-tree model'
setupSchemaSetMocks('test-tree.yang')
when: 'update data method is invoked with json data #jsonData and parent node xpath #parentNodeXpath'
- objectUnderTest.updateNodeLeaves(dataspaceName, anchorName, parentNodeXpath, jsonData)
+ objectUnderTest.updateNodeLeaves(dataspaceName, anchorName, parentNodeXpath, jsonData, observedTimestamp)
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)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
where: 'following parameters were used'
scenario | parentNodeXpath | jsonData || expectedNodeXpath | leaves
'top level node' | '/' | '{"test-tree": {"branch": []}}' || '/test-tree' | Collections.emptyMap()
@@ -142,7 +144,8 @@ class CpsDataServiceImplSpec extends Specification {
given: 'schema set for given anchor and dataspace references bookstore model'
setupSchemaSetMocks('bookstore.yang')
when: 'update data method is invoked with json data #jsonData and parent node xpath'
- objectUnderTest.updateNodeLeaves(dataspaceName, anchorName, '/bookstore/categories[@code=2]', jsonData)
+ objectUnderTest.updateNodeLeaves(dataspaceName, anchorName, '/bookstore/categories[@code=2]',
+ jsonData, observedTimestamp)
then: 'the persistence service method is invoked with correct parameters'
thrown(DataValidationException)
where: 'following parameters were used'
@@ -157,23 +160,25 @@ class CpsDataServiceImplSpec extends Specification {
and: 'the expected json string'
def jsonData = '{"cm-handles":[{"id":"cmHandle001", "additional-properties":[{"name":"P1"}]}]}'
when: 'update data method is invoked with json data and parent node xpath'
- objectUnderTest.updateNodeLeavesAndExistingDescendantLeaves(dataspaceName, anchorName, '/dmi-registry', jsonData)
+ objectUnderTest.updateNodeLeavesAndExistingDescendantLeaves(dataspaceName, anchorName,
+ '/dmi-registry', jsonData, observedTimestamp)
then: 'the persistence service method is invoked with correct parameters'
- 1 * mockCpsDataPersistenceService.updateDataLeaves(dataspaceName, anchorName, "/dmi-registry/cm-handles[@id='cmHandle001']", ['id': 'cmHandle001'])
+ 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)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
}
def 'Replace data node: #scenario.'() {
given: 'schema set for given anchor and dataspace references test-tree model'
setupSchemaSetMocks('test-tree.yang')
when: 'replace data method is invoked with json data #jsonData and parent node xpath #parentNodeXpath'
- objectUnderTest.replaceNodeTree(dataspaceName, anchorName, parentNodeXpath, jsonData)
+ objectUnderTest.replaceNodeTree(dataspaceName, anchorName, parentNodeXpath, jsonData, observedTimestamp)
then: 'the persistence service method is invoked with correct parameters'
1 * mockCpsDataPersistenceService.replaceDataNodeTree(dataspaceName, anchorName,
- { dataNode -> dataNode.xpath == expectedNodeXpath })
+ { dataNode -> dataNode.xpath == expectedNodeXpath })
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
where: 'following parameters were used'
scenario | parentNodeXpath | jsonData || expectedNodeXpath
'top level node' | '/' | '{"test-tree": {"branch": []}}' || '/test-tree'
@@ -185,19 +190,19 @@ class CpsDataServiceImplSpec extends Specification {
setupSchemaSetMocks('test-tree.yang')
when: 'replace list data method is invoked with list-node json data'
def jsonData = '{"branch": [{"name": "A"}, {"name": "B"}]}'
- objectUnderTest.replaceListNodeData(dataspaceName, anchorName, '/test-tree', jsonData)
+ objectUnderTest.replaceListNodeData(dataspaceName, anchorName, '/test-tree', jsonData, observedTimestamp)
then: 'the persistence service method is invoked with correct parameters'
1 * mockCpsDataPersistenceService.replaceListDataNodes(dataspaceName, anchorName, '/test-tree',
- { dataNodeCollection ->
- {
- assert dataNodeCollection.size() == 2
- assert dataNodeCollection.collect { it.getXpath() }
- .containsAll(['/test-tree/branch[@name=\'A\']', '/test-tree/branch[@name=\'B\']'])
- }
+ { dataNodeCollection ->
+ {
+ assert dataNodeCollection.size() == 2
+ assert dataNodeCollection.collect { it.getXpath() }
+ .containsAll(['/test-tree/branch[@name=\'A\']', '/test-tree/branch[@name=\'B\']'])
}
+ }
)
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
}
def 'Replace with empty list-node data fragment.'() {
@@ -205,7 +210,7 @@ class CpsDataServiceImplSpec extends Specification {
setupSchemaSetMocks('test-tree.yang')
when: 'replace list data method is invoked with empty list-node data fragment'
def jsonData = '{"branch": []}'
- objectUnderTest.replaceListNodeData(dataspaceName, anchorName, '/test-tree', jsonData)
+ objectUnderTest.replaceListNodeData(dataspaceName, anchorName, '/test-tree', jsonData, observedTimestamp)
then: 'invalid data exception is thrown'
thrown(DataValidationException)
}
@@ -214,11 +219,11 @@ class CpsDataServiceImplSpec extends Specification {
given: 'schema set for given anchor and dataspace references test-tree model'
setupSchemaSetMocks('test-tree.yang')
when: 'delete list data method is invoked with list-node json data'
- objectUnderTest.deleteListNodeData(dataspaceName, anchorName, '/test-tree/branch')
+ objectUnderTest.deleteListNodeData(dataspaceName, anchorName, '/test-tree/branch', observedTimestamp)
then: 'the persistence service method is invoked with correct parameters'
1 * mockCpsDataPersistenceService.deleteListDataNodes(dataspaceName, anchorName, '/test-tree/branch')
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
}
def setupSchemaSetMocks(String... yangResources) {
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy
index fec8b7fa79..eefa86e903 100755
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy
@@ -22,6 +22,7 @@
package org.onap.cps.api.impl
+import java.time.OffsetDateTime
import org.onap.cps.TestUtils
import org.onap.cps.api.CpsAdminService
import org.onap.cps.notification.NotificationService
@@ -44,6 +45,7 @@ class E2ENetworkSliceSpec extends Specification {
def dataspaceName = 'someDataspace'
def anchorName = 'someAnchor'
def schemaSetName = 'someSchemaSet'
+ def noTimestamp = null
def setup() {
cpsDataServiceImpl.cpsDataPersistenceService = mockDataStoreService
@@ -92,7 +94,7 @@ class E2ENetworkSliceSpec extends Specification {
YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap)
mockModuleStoreService.getYangSchemaResources(dataspaceName, schemaSetName) >> schemaContext
when: 'saveData method is invoked'
- cpsDataServiceImpl.saveData(dataspaceName, anchorName, jsonData)
+ cpsDataServiceImpl.saveData(dataspaceName, anchorName, jsonData, noTimestamp)
then: 'Parameters are validated and processing is delegated to persistence service'
1 * mockDataStoreService.storeDataNode('someDataspace', 'someAnchor', _) >>
{ args -> dataNodeStored = args[2]}
@@ -124,7 +126,7 @@ class E2ENetworkSliceSpec extends Specification {
mockYangTextSchemaSourceSetCache.get('someDataspace', 'someSchemaSet') >> YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap)
mockModuleStoreService.getYangSchemaResources('someDataspace', 'someSchemaSet') >> schemaContext
when: 'saveData method is invoked'
- cpsDataServiceImpl.saveData('someDataspace', 'someAnchor', jsonData)
+ cpsDataServiceImpl.saveData('someDataspace', 'someAnchor', jsonData, noTimestamp)
then: 'parameters are validated and processing is delegated to persistence service'
1 * mockDataStoreService.storeDataNode('someDataspace', 'someAnchor', _) >>
{ args -> dataNodeStored = args[2]}
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 2ce77bd1a8..aa0c7c0b39 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,12 +1,13 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Bell Canada. All rights reserved.
+ * Copyright (c) 2021 Bell Canada.
* ================================================================================
* 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.
@@ -19,6 +20,9 @@
package org.onap.cps.notification
+import java.time.OffsetDateTime
+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.Data
@@ -28,8 +32,6 @@ import org.onap.cps.spi.model.DataNodeBuilder
import org.springframework.util.StringUtils
import spock.lang.Specification
-import java.time.format.DateTimeFormatter
-
class CpsDataUpdateEventFactorySpec extends Specification {
def mockCpsDataService = Mock(CpsDataService)
@@ -42,7 +44,7 @@ class CpsDataUpdateEventFactorySpec extends Specification {
def mySchemasetName = 'my-schemaset-name'
def dateTimeFormat = 'yyyy-MM-dd\'T\'HH:mm:ss.SSSZ'
- def 'Create a CPS data updated event successfully.'() {
+ def 'Create a CPS data updated event successfully: #scenario'() {
given: 'cps admin service is able to return anchor details'
mockCpsAdminService.getAnchor(myDataspaceName, myAnchorName) >>
@@ -51,12 +53,14 @@ class CpsDataUpdateEventFactorySpec extends Specification {
def xpath = '/'
def dataNode = new DataNodeBuilder().withXpath(xpath).withLeaves(['leafName': 'leafValue']).build()
mockCpsDataService.getDataNode(
- myDataspaceName, myAnchorName, xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
+ myDataspaceName, myAnchorName, xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
when: 'CPS data updated event is created'
- def cpsDataUpdatedEvent = objectUnderTest.createCpsDataUpdatedEvent(myDataspaceName, myAnchorName)
+ def cpsDataUpdatedEvent = objectUnderTest.createCpsDataUpdatedEvent(myDataspaceName,
+ myAnchorName, DateTimeUtility.toOffsetDateTime(inputObservedTimestamp))
+
+ then: 'CPS data updated event is created with correct envelope'
- then: 'CPS data updated event is created with expected values'
with(cpsDataUpdatedEvent) {
type == 'org.onap.cps.data-updated-event'
source == new URI('urn:cps:org.onap.cps')
@@ -64,13 +68,24 @@ class CpsDataUpdateEventFactorySpec extends Specification {
StringUtils.hasText(id)
content != null
}
+ and: 'correct content'
with(cpsDataUpdatedEvent.content) {
assert isExpectedDateTimeFormat(observedTimestamp): "$observedTimestamp is not in $dateTimeFormat format"
- anchorName == myAnchorName
- dataspaceName == myDataspaceName
- schemaSetName == mySchemasetName
- data == new Data().withAdditionalProperty('leafName', 'leafValue')
+ if (inputObservedTimestamp != null)
+ assert observedTimestamp == inputObservedTimestamp
+ else
+ assert OffsetDateTime.now().minusSeconds(20).isBefore(
+ DateTimeUtility.toOffsetDateTime(observedTimestamp))
+ assert anchorName == myAnchorName
+ assert dataspaceName == myDataspaceName
+ assert schemaSetName == mySchemasetName
+ assert data == new Data().withAdditionalProperty('leafName', 'leafValue')
}
+ where:
+ scenario | inputObservedTimestamp
+ 'with observed timestamp -0400' | '2021-01-01T23:00:00.345-0400'
+ 'with observed timestamp +0400' | '2021-01-01T23:00:00.345+0400'
+ 'missing observed timestamp' | null
}
def isExpectedDateTimeFormat(String observedTimestamp) {
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 ab727671e1..875113d225 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
@@ -20,6 +20,7 @@
package org.onap.cps.notification
+import java.time.OffsetDateTime
import org.onap.cps.config.AsyncConfig
import org.onap.cps.event.model.CpsDataUpdatedEvent
import org.spockframework.spring.SpringBean
@@ -55,12 +56,13 @@ class NotificationServiceSpec extends Specification {
@Shared
def myDataspacePublishedName = 'my-dataspace-published'
def myAnchorName = 'my-anchorname'
+ def myObservedTimestamp = OffsetDateTime.now()
def 'Skip sending notification when disabled.'() {
given: 'notification is disabled'
spyNotificationProperties.isEnabled() >> false
when: 'dataUpdatedEvent is received'
- objectUnderTest.processDataUpdatedEvent(myDataspacePublishedName, myAnchorName)
+ objectUnderTest.processDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp)
then: 'the notification is not sent'
0 * mockNotificationPublisher.sendNotification(_)
}
@@ -70,10 +72,11 @@ class NotificationServiceSpec extends Specification {
spyNotificationProperties.isEnabled() >> true
and: 'event factory can create event successfully'
def cpsDataUpdatedEvent = new CpsDataUpdatedEvent()
- mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(dataspaceName, myAnchorName) >> cpsDataUpdatedEvent
+ mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(dataspaceName, myAnchorName, myObservedTimestamp) >>
+ cpsDataUpdatedEvent
when: 'dataUpdatedEvent is received'
- def future = objectUnderTest.processDataUpdatedEvent(dataspaceName, myAnchorName)
- and: 'wait for async processing is completed'
+ def future = objectUnderTest.processDataUpdatedEvent(dataspaceName, myAnchorName, myObservedTimestamp)
+ and: 'wait for async processing to complete'
future.get(10, TimeUnit.SECONDS)
then: 'async process completed successfully'
future.isDone()
@@ -89,11 +92,11 @@ class NotificationServiceSpec extends Specification {
given: 'notification is enabled'
spyNotificationProperties.isEnabled() >> true
and: 'event factory can not create event successfully'
- mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(myDataspacePublishedName, myAnchorName) >>
+ mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp) >>
{ throw new Exception("Could not create event") }
when: 'event is sent for processing'
- def future = objectUnderTest.processDataUpdatedEvent(myDataspacePublishedName, myAnchorName)
- and: 'wait for async processing is completed'
+ def future = objectUnderTest.processDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp)
+ and: 'wait for async processing to complete'
future.get(10, TimeUnit.SECONDS)
then: 'async process completed successfully'
future.isDone()