diff options
Diffstat (limited to 'cps-service/src/test')
7 files changed, 115 insertions, 488 deletions
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy index 41fcb29edd..2979c09866 100755 --- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy @@ -24,30 +24,24 @@ package org.onap.cps.api.impl import org.onap.cps.api.CpsDataService import org.onap.cps.spi.CpsAdminPersistenceService -import org.onap.cps.spi.exceptions.DataValidationException import org.onap.cps.spi.model.Anchor +import org.onap.cps.spi.utils.CpsValidator import spock.lang.Specification import java.time.OffsetDateTime class CpsAdminServiceImplSpec extends Specification { def mockCpsAdminPersistenceService = Mock(CpsAdminPersistenceService) def mockCpsDataService = Mock(CpsDataService) - def objectUnderTest = new CpsAdminServiceImpl(mockCpsAdminPersistenceService, mockCpsDataService) + def mockCpsValidator = Mock(CpsValidator) + def objectUnderTest = new CpsAdminServiceImpl(mockCpsAdminPersistenceService, mockCpsDataService,mockCpsValidator) def 'Create dataspace method invokes persistence service.'() { when: 'create dataspace method is invoked' objectUnderTest.createDataspace('someDataspace') then: 'the persistence service method is invoked with same parameters' 1 * mockCpsAdminPersistenceService.createDataspace('someDataspace') - } - - def 'Create a dataspace with an invalid dataspace name.'() { - when: 'create dataspace method is invoked with incorrectly named dataspace' - objectUnderTest.createDataspace('Dataspace Name with spaces') - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'the persistence service method is not invoked' - 0 * mockCpsAdminPersistenceService.createDataspace(_) + and: 'the CpsValidator is called on the dataspaceName' + 1 * mockCpsValidator.validateNameCharacters('someDataspace') } def 'Create anchor method invokes persistence service.'() { @@ -55,76 +49,44 @@ class CpsAdminServiceImplSpec extends Specification { objectUnderTest.createAnchor('someDataspace', 'someSchemaSet', 'someAnchorName') then: 'the persistence service method is invoked with same parameters' 1 * mockCpsAdminPersistenceService.createAnchor('someDataspace', 'someSchemaSet', 'someAnchorName') - } - - def 'Create an anchor with an invalid anchor name.'() { - when: 'create anchor method is invoked with incorrectly named dataspace' - objectUnderTest.createAnchor('someDataspace', 'someSchemaSet', 'Anchor Name With Spaces') - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'the persistence service method is not invoked' - 0 * mockCpsAdminPersistenceService.createAnchor(_, _, _) + and: 'the CpsValidator is called on the dataspaceName, schemaSetName and anchorName' + 1 * mockCpsValidator.validateNameCharacters('someDataspace', 'someSchemaSet', 'someAnchorName') } def 'Retrieve all anchors for dataspace.'() { - given: 'that anchor is associated with the dataspace' + given: 'that an anchor is associated with the dataspace' def anchors = [new Anchor()] mockCpsAdminPersistenceService.getAnchors('someDataspace') >> anchors - expect: 'the collection provided by persistence service is returned as result' - objectUnderTest.getAnchors('someDataspace') == anchors - } - - def 'Retrieve all anchors with an invalid dataspace name.'() { - when: 'get anchors is invoked with an invalid dataspace name' - objectUnderTest.getAnchors('Dataspace name with spaces') - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'cps admin persistence get anchors is not invoked' - 0 * mockCpsAdminPersistenceService.getAnchors(_) + when: 'get Anchors is called for a dataspace name' + def result = objectUnderTest.getAnchors('someDataspace') + then: 'the collection provided by persistence service is returned as result' + result == anchors + and: 'the CpsValidator is called on the dataspaceName' + 1 * mockCpsValidator.validateNameCharacters('someDataspace') } def 'Retrieve all anchors for schema-set.'() { given: 'that anchor is associated with the dataspace and schemaset' def anchors = [new Anchor()] mockCpsAdminPersistenceService.getAnchors('someDataspace', 'someSchemaSet') >> anchors - expect: 'the collection provided by persistence service is returned as result' - objectUnderTest.getAnchors('someDataspace', 'someSchemaSet') == anchors + when: 'get anchors is called for a dataspace name and schema set name' + def result = objectUnderTest.getAnchors('someDataspace', 'someSchemaSet') + then: 'the collection provided by persistence service is returned as result' + result == anchors + and: 'the CpsValidator is called on the dataspaceName, schemaSetName' + 1 * mockCpsValidator.validateNameCharacters('someDataspace', 'someSchemaSet') } - def 'Retrieve all anchors for schema-set with invalid #scenario.'() { - when: 'the collection provided by persistence service is returned as result' - objectUnderTest.getAnchors(dataspaceName, schemaSetName) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'cps admin persistence get anchors is not invoked' - 0 * mockCpsAdminPersistenceService.getAnchors(_, _) - where: 'the following parameters are used' - scenario | dataspaceName | schemaSetName - 'dataspace name' | 'dataspace names with spaces' | 'schemaSetName' - 'schema set name' | 'dataspaceName' | 'schema set name with spaces' - 'dataspace and schema set name' | 'dataspace name with spaces' | 'schema set name with spaces' - } - def 'Retrieve anchor for dataspace and provided anchor name.'() { given: 'that anchor name is associated with the dataspace' Anchor anchor = new Anchor() mockCpsAdminPersistenceService.getAnchor('someDataspace','someAnchor') >> anchor - expect: 'the anchor provided by persistence service is returned as result' - assert objectUnderTest.getAnchor('someDataspace','someAnchor') == anchor - } - - def 'Retrieve anchor with invalid #scenario.'() { - when: 'get anchors is invoked with an invalid dataspace name' - objectUnderTest.getAnchor(dataspaceName, anchorName) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'cps admin persistence get anchor is not invoked' - 0 * mockCpsAdminPersistenceService.getAnchor(_, _) - where: 'the following parameters are used' - scenario | dataspaceName | anchorName - 'dataspace name' | 'dataspace names with spaces' | 'anchorName' - 'anchor name' | 'dataspaceName' | 'anchor name with spaces' - 'dataspace and anchor name' | 'dataspace name with spaces' | 'anchor name with spaces' + when: 'get anchor is called for a dataspace name and anchor name' + def result = objectUnderTest.getAnchor('someDataspace','someAnchor') + then: 'the anchor provided by persistence service is returned as result' + result == anchor + and: 'the CpsValidator is called on the dataspaceName, anchorName' + 1 * mockCpsValidator.validateNameCharacters('someDataspace', 'someAnchor') } def 'Delete anchor.'() { @@ -134,39 +96,19 @@ class CpsAdminServiceImplSpec extends Specification { 1 * mockCpsDataService.deleteDataNodes('someDataspace','someAnchor', _ as OffsetDateTime ) and: 'the persistence service method is invoked with same parameters to delete anchor' 1 * mockCpsAdminPersistenceService.deleteAnchor('someDataspace','someAnchor') - } - - def 'Delete anchor with invalid #scenario.'() { - when: 'delete anchor is invoked' - objectUnderTest.deleteAnchor(dataspaceName, anchorName) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'delete data nodes is invoked on the data service with expected parameters' - 0 * mockCpsDataService.deleteDataNodes(_,_, _ as OffsetDateTime ) - and: 'the persistence service method is invoked with same parameters to delete anchor' - 0 * mockCpsAdminPersistenceService.deleteAnchor(_,_) - where: 'the following parameters are used' - scenario | dataspaceName | anchorName - 'dataspace name' | 'dataspace names with spaces' | 'anchorName' - 'anchor name' | 'dataspaceName' | 'anchor name with spaces' - 'dataspace and anchor name' | 'dataspace name with spaces' | 'anchor name with spaces' + and: 'the CpsValidator is called on the dataspaceName, anchorName' + 1 * mockCpsValidator.validateNameCharacters('someDataspace', 'someAnchor') } def 'Query all anchor identifiers for a dataspace and module names.'() { given: 'the persistence service is invoked with the expected parameters and returns a list of anchors' mockCpsAdminPersistenceService.queryAnchors('some-dataspace-name', ['some-module-name']) >> [new Anchor(name:'some-anchor-identifier')] - expect: 'get anchor identifiers returns the same anchor identifier returned by the persistence layer' - objectUnderTest.queryAnchorNames('some-dataspace-name', ['some-module-name']) == ['some-anchor-identifier'] - - } - - def 'Query all anchor identifiers for a dataspace and module names with an invalid dataspace name.'() { - when: 'delete anchor is invoked' - objectUnderTest.queryAnchorNames('some dataspace name', _ as Collection<String>) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'delete data nodes is not invoked' - 0 * mockCpsAdminPersistenceService.queryAnchors(_, _) + when: 'query anchor names is called using a dataspace name and module name' + def result = objectUnderTest.queryAnchorNames('some-dataspace-name', ['some-module-name']) + then: 'get anchor identifiers returns the same anchor identifier returned by the persistence layer' + result == ['some-anchor-identifier'] + and: 'the CpsValidator is called on the dataspaceName' + 1 * mockCpsValidator.validateNameCharacters('some-dataspace-name') } def 'Delete dataspace.'() { @@ -174,14 +116,7 @@ class CpsAdminServiceImplSpec extends Specification { objectUnderTest.deleteDataspace('someDataspace') then: 'associated persistence service method is invoked with correct parameter' 1 * mockCpsAdminPersistenceService.deleteDataspace('someDataspace') - } - - def 'Delete dataspace with invalid dataspace id.'() { - when: 'delete dataspace is invoked' - objectUnderTest.deleteDataspace('some dataspace name') - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'associated persistence service method is not invoked' - 0 * mockCpsAdminPersistenceService.deleteDataspace(_) + and: 'the CpsValidator is called on the dataspaceName' + 1 * mockCpsValidator.validateNameCharacters('someDataspace') } } 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 a53706a06b..b60e7e86e0 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 @@ -35,6 +35,7 @@ import org.onap.cps.spi.model.DataNodeBuilder import org.onap.cps.yang.YangTextSchemaSourceSet import org.onap.cps.yang.YangTextSchemaSourceSetBuilder import spock.lang.Specification +import org.onap.cps.spi.utils.CpsValidator import java.time.OffsetDateTime import java.util.stream.Collectors @@ -44,9 +45,10 @@ class CpsDataServiceImplSpec extends Specification { def mockCpsAdminService = Mock(CpsAdminService) def mockYangTextSchemaSourceSetCache = Mock(YangTextSchemaSourceSetCache) def mockNotificationService = Mock(NotificationService) + def mockCpsValidator = Mock(CpsValidator) def objectUnderTest = new CpsDataServiceImpl(mockCpsDataPersistenceService, mockCpsAdminService, - mockYangTextSchemaSourceSetCache, mockNotificationService) + mockYangTextSchemaSourceSetCache, mockNotificationService, mockCpsValidator) def setup() { mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> anchor @@ -67,26 +69,12 @@ class CpsDataServiceImplSpec extends Specification { then: 'the persistence service method is invoked with correct parameters' 1 * mockCpsDataPersistenceService.storeDataNode(dataspaceName, anchorName, { dataNode -> dataNode.xpath == '/test-tree' }) + and: 'the CpsValidator is called on the dataspaceName and AnchorName' + 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'data updated event is sent to notification service' 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, '/', Operation.CREATE, observedTimestamp) } - def 'Saving json data with invalid #scenario.'() { - when: 'save data method is invoked with invalid #scenario' - objectUnderTest.saveData(dataspaceName, anchorName, _ as String, observedTimestamp) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'the persistence service method is not invoked' - 0 * mockCpsDataPersistenceService.storeDataNode(*_) - and: 'data updated event is not sent to notification service' - 0 * mockNotificationService.processDataUpdatedEvent(*_) - where: 'the following parameters are used' - scenario | dataspaceName | anchorName - 'dataspace name' | 'dataspace names with spaces' | 'anchorName' - 'anchor name' | 'dataspaceName' | 'anchor name with spaces' - 'dataspace and anchor name' | 'dataspace name with spaces' | 'anchor name with spaces' - } - def 'Saving child data fragment under existing node.'() { given: 'schema set for given anchor and dataspace references test-tree model' setupSchemaSetMocks('test-tree.yang') @@ -96,26 +84,12 @@ class CpsDataServiceImplSpec extends Specification { 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\']' }) + and: 'the CpsValidator is called on the dataspaceName and AnchorName' + 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'data updated event is sent to notification service' 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, '/test-tree', Operation.CREATE, observedTimestamp) } - def 'Saving child data fragment under existing node with invalid #scenario.'() { - when: 'save data method is invoked with test-tree and an invalid #scenario' - objectUnderTest.saveData(dataspaceName, anchorName, '/test-tree', _ as String, observedTimestamp) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'the persistence service method is not invoked' - 0 * mockCpsDataPersistenceService.addChildDataNode(*_) - and: 'data updated event is not sent to notification service' - 0 * mockNotificationService.processDataUpdatedEvent(*_) - where: 'the following parameters are used' - scenario | dataspaceName | anchorName - 'dataspace name' | 'dataspace names with spaces' | 'anchorName' - 'anchor name' | 'dataspaceName' | 'anchor name with spaces' - 'dataspace and anchor name' | 'dataspace name with spaces' | 'anchor name with spaces' - } - def 'Saving list element data fragment under existing node.'() { given: 'schema set for given anchor and dataspace references test-tree model' setupSchemaSetMocks('test-tree.yang') @@ -132,6 +106,8 @@ class CpsDataServiceImplSpec extends Specification { } } ) + and: 'the CpsValidator is called on the dataspaceName and AnchorName' + 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'data updated event is sent to notification service' 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, '/test-tree', Operation.UPDATE, observedTimestamp) } @@ -166,20 +142,6 @@ class CpsDataServiceImplSpec extends Specification { thrown(DataValidationException) } - def 'Saving list element data fragment with invalid #scenario.'() { - when: 'save data method is invoked with an invalid #scenario' - objectUnderTest.saveListElements(dataspaceName, anchorName, '/test-tree', _ as String, observedTimestamp) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'add list elements persistence method is not invoked' - 0 * mockCpsDataPersistenceService.addListElements(*_) - where: 'the following parameters are used' - scenario | dataspaceName | anchorName - 'dataspace name' | 'dataspace names with spaces' | 'anchorName' - 'anchor name' | 'dataspaceName' | 'anchor name with spaces' - 'dataspace and anchor name' | 'dataspace name with spaces' | 'anchor name with spaces' - } - def 'Get data node with option #fetchDescendantsOption.'() { def xpath = '/xpath' def dataNode = new DataNodeBuilder().withXpath(xpath).build() @@ -191,20 +153,6 @@ class CpsDataServiceImplSpec extends Specification { fetchDescendantsOption << [FetchDescendantsOption.OMIT_DESCENDANTS, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS] } - def 'Get data node with option invalid #scenario.'() { - when: 'get data node is invoked with #scenario' - objectUnderTest.getDataNode(dataspaceName, anchorName, '/test-tree', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'get data node persistence service is not invoked' - 0 * mockCpsDataPersistenceService.getDataNode(*_) - where: 'the following parameters are used' - scenario | dataspaceName | anchorName - 'dataspace name' | 'dataspace names with spaces' | 'anchorName' - 'anchor name' | 'dataspaceName' | 'anchor name with spaces' - 'dataspace and anchor name' | 'dataspace name with spaces' | 'anchor name with spaces' - } - def 'Update data node leaves: #scenario.'() { given: 'schema set for given anchor and dataspace references test-tree model' setupSchemaSetMocks('test-tree.yang') @@ -212,6 +160,8 @@ class CpsDataServiceImplSpec extends Specification { 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: 'the CpsValidator is called on the dataspaceName and AnchorName' + 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'data updated event is sent to notification service' 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, parentNodeXpath, Operation.UPDATE, observedTimestamp) where: 'following parameters were used' @@ -220,22 +170,6 @@ class CpsDataServiceImplSpec extends Specification { 'level 2 node' | '/test-tree' | '{"branch": [{"name":"Name"}]}' || '/test-tree/branch[@name=\'Name\']' | ['name': 'Name'] } - def 'Update data node with invalid #scenario.'() { - when: 'update data method is invoked with json data #jsonData and parent node xpath #parentNodeXpath' - objectUnderTest.updateNodeLeaves(dataspaceName, anchorName, '/', '{"test-tree": {"branch": []}}', observedTimestamp) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'the persistence service method is not invoked' - 0 * mockCpsDataPersistenceService.updateDataLeaves(*_) - and: 'data updated event is not sent to notification service' - 0 * mockNotificationService.processDataUpdatedEvent(*_) - where: 'the following parameters are used' - scenario | dataspaceName | anchorName - 'dataspace name' | 'dataspace names with spaces' | 'anchorName' - 'anchor name' | 'dataspaceName' | 'anchor name with spaces' - 'dataspace and anchor name' | 'dataspace name with spaces' | 'anchor name with spaces' - } - def 'Update list-element data node with : #scenario.'() { given: 'schema set for given anchor and dataspace references bookstore model' setupSchemaSetMocks('bookstore.yang') @@ -261,28 +195,12 @@ class CpsDataServiceImplSpec extends Specification { then: 'the persistence service method is invoked with correct parameters' 1 * mockCpsDataPersistenceService.updateDataLeaves(dataspaceName, anchorName, "/bookstore/categories[@code='01']", ['name':'Romance', 'code': '01']) + and: 'the CpsValidator is called on the dataspaceName and AnchorName' + 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'the data updated event is sent to the notification service' 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, '/bookstore', Operation.UPDATE, observedTimestamp) } - def 'Update Bookstore node leaves with invalid #scenario' () { - when: 'update data method is invoked with an invalid #scenario' - objectUnderTest.updateNodeLeavesAndExistingDescendantLeaves(dataspaceName, anchorName, - '/bookstore', _ as String, observedTimestamp) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'the persistence service method is not invoked' - 0 * mockCpsDataPersistenceService.updateDataLeaves(*_) - and: 'the data updated event is not sent to the notification service' - 0 * mockNotificationService.processDataUpdatedEvent(*_) - where: 'the following parameters are used' - scenario | dataspaceName | anchorName - 'dataspace name' | 'dataspace names with spaces' | 'anchorName' - 'anchor name' | 'dataspaceName' | 'anchor name with spaces' - 'dataspace and anchor name' | 'dataspace name with spaces' | 'anchor name with spaces' - } - - def 'Replace data node using singular data node: #scenario.'() { given: 'schema set for given anchor and dataspace references test-tree model' setupSchemaSetMocks('test-tree.yang') @@ -293,6 +211,8 @@ class CpsDataServiceImplSpec extends Specification { { dataNode -> dataNode.xpath == expectedNodeXpath }) and: 'data updated event is sent to notification service' 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, parentNodeXpath, Operation.UPDATE, observedTimestamp) + and: 'the CpsValidator is called on the dataspaceName and AnchorName' + 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) where: 'following parameters were used' scenario | parentNodeXpath | jsonData || expectedNodeXpath 'top level node' | '/' | '{"test-tree": {"branch": []}}' || '/test-tree' @@ -310,44 +230,14 @@ class CpsDataServiceImplSpec extends Specification { and: 'data updated event is sent to notification service' 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, nodesJsonData.keySet()[0], Operation.UPDATE, observedTimestamp) 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, nodesJsonData.keySet()[1], Operation.UPDATE, observedTimestamp) + and: 'the CpsValidator is called on the dataspaceName and AnchorName' + 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) where: 'following parameters were used' scenario | nodesJsonData || expectedNodeXpath 'top level node' | ['/' : '{"test-tree": {"branch": []}}', '/test-tree' : '{"branch": [{"name":"Name"}]}'] || ["/test-tree", "/test-tree/branch[@name='Name']"] 'level 2 node' | ['/test-tree' : '{"branch": [{"name":"Name"}]}', '/test-tree/branch[@name=\'Name\']':'{"nest":{"name":"nestName"}}'] || ["/test-tree/branch[@name='Name']", "/test-tree/branch[@name='Name']/nest"] } - def 'Replace data node using singular data node with invalid #scenario.'() { - when: 'replace data method is invoked with invalid #scenario' - objectUnderTest.updateDataNodeAndDescendants(dataspaceName, anchorName, '/', _ as String, observedTimestamp) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'the persistence service method is not invoked' - 0 * mockCpsDataPersistenceService.updateDataNodeAndDescendants(*_) - and: 'data updated event is not sent to notification service' - 0 * mockNotificationService.processDataUpdatedEvent(*_) - where: 'the following parameters are used' - scenario | dataspaceName | anchorName - 'dataspace name' | 'dataspace names with spaces' | 'anchorName' - 'anchor name' | 'dataspaceName' | 'anchor name with spaces' - 'dataspace and anchor name' | 'dataspace name with spaces' | 'anchor name with spaces' - } - - def 'Replace data node using multiple data nodes with invalid #scenario.'() { - when: 'replace data method is invoked with invalid #scenario' - objectUnderTest.updateDataNodesAndDescendants(dataspaceName, anchorName, ['/': _ as String], observedTimestamp) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'the persistence service method is not invoked' - 0 * mockCpsDataPersistenceService.updateDataNodesAndDescendants(*_) - and: 'data updated event is not sent to notification service' - 0 * mockNotificationService.processDataUpdatedEvent(*_) - where: 'the following parameters are used' - scenario | dataspaceName | anchorName - 'dataspace name' | 'dataspace names with spaces' | 'anchorName' - 'anchor name' | 'dataspaceName' | 'anchor name with spaces' - 'dataspace and anchor name' | 'dataspace name with spaces' | 'anchor name with spaces' - } - def 'Replace list content data fragment under parent node.'() { given: 'schema set for given anchor and dataspace references test-tree model' setupSchemaSetMocks('test-tree.yang') @@ -364,6 +254,8 @@ class CpsDataServiceImplSpec extends Specification { } } ) + and: 'the CpsValidator is called on the dataspaceName and AnchorName twice' + 2 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'data updated event is sent to notification service' 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, '/test-tree', Operation.UPDATE, observedTimestamp) } @@ -378,22 +270,6 @@ class CpsDataServiceImplSpec extends Specification { thrown(DataValidationException) } - def 'Replace whole list content with an invalid #scenario.'() { - when: 'replace list data method is invoked with invalid #scenario' - objectUnderTest.replaceListContent(dataspaceName, anchorName, '/test-tree', _ as Collection<DataNode>, observedTimestamp) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'the persistence service method is not invoked' - 0 * mockCpsDataPersistenceService.replaceListContent(*_) - and: 'data updated event is not sent to notification service' - 0 * mockNotificationService.processDataUpdatedEvent(*_) - where: 'the following parameters are used' - scenario | dataspaceName | anchorName - 'dataspace name' | 'dataspace names with spaces' | 'anchorName' - 'anchor name' | 'dataspaceName' | 'anchor name with spaces' - 'dataspace and anchor name' | 'dataspace name with spaces' | 'anchor name with spaces' - } - def 'Delete list element under existing node.'() { given: 'schema set for given anchor and dataspace references test-tree model' setupSchemaSetMocks('test-tree.yang') @@ -401,27 +277,12 @@ class CpsDataServiceImplSpec extends Specification { objectUnderTest.deleteListOrListElement(dataspaceName, anchorName, '/test-tree/branch', observedTimestamp) then: 'the persistence service method is invoked with correct parameters' 1 * mockCpsDataPersistenceService.deleteListDataNode(dataspaceName, anchorName, '/test-tree/branch') + and: 'the CpsValidator is called on the dataspaceName and AnchorName' + 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'data updated event is sent to notification service' 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, '/test-tree/branch', Operation.DELETE, observedTimestamp) } - - def 'Delete list element with an invalid #scenario.'() { - when: 'delete list data method is invoked with with invalid #scenario' - objectUnderTest.deleteDataNode(dataspaceName, anchorName, '/data-node', observedTimestamp) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'the persistence service method is not invoked' - 0 * mockCpsDataPersistenceService.deleteListDataNode(*_) - and: 'data updated event is not sent to notification service' - 0 * mockNotificationService.processDataUpdatedEvent(*_) - where: 'the following parameters are used' - scenario | dataspaceName | anchorName - 'dataspace name' | 'dataspace names with spaces' | 'anchorName' - 'anchor name' | 'dataspaceName' | 'anchor name with spaces' - 'dataspace and anchor name' | 'dataspace name with spaces' | 'anchor name with spaces' - } - def 'Delete data node under anchor and dataspace.'() { given: 'schema set for given anchor and dataspace references test tree model' setupSchemaSetMocks('test-tree.yang') @@ -429,26 +290,12 @@ class CpsDataServiceImplSpec extends Specification { objectUnderTest.deleteDataNode(dataspaceName, anchorName, '/data-node', observedTimestamp) then: 'the persistence service method is invoked with the correct parameters' 1 * mockCpsDataPersistenceService.deleteDataNode(dataspaceName, anchorName, '/data-node') + and: 'the CpsValidator is called on the dataspaceName and AnchorName' + 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'data updated event is sent to notification service' 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, '/data-node', Operation.DELETE, observedTimestamp) } - def 'Delete data node with an invalid #scenario.'() { - when: 'delete data node method is invoked with invalid #scenario' - objectUnderTest.deleteDataNode(dataspaceName, anchorName, '/data-node', observedTimestamp) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'the persistence service method is not invoked' - 0 * mockCpsDataPersistenceService.deleteDataNode(*_) - and: 'data updated event is not sent to notification service' - 0 * mockNotificationService.processDataUpdatedEvent(*_) - where: 'the following parameters are used' - scenario | dataspaceName | anchorName - 'dataspace name' | 'dataspace names with spaces' | 'anchorName' - 'anchor name' | 'dataspaceName' | 'anchor name with spaces' - 'dataspace and anchor name' | 'dataspace name with spaces' | 'anchor name with spaces' - } - def 'Delete all data nodes for a given anchor and dataspace.'() { given: 'schema set for given anchor and dataspace references test tree model' setupSchemaSetMocks('test-tree.yang') @@ -456,6 +303,8 @@ class CpsDataServiceImplSpec extends Specification { objectUnderTest.deleteDataNodes(dataspaceName, anchorName, observedTimestamp) then: 'data updated event is sent to notification service before the delete' 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, '/', Operation.DELETE, observedTimestamp) + and: 'the CpsValidator is called on the dataspaceName and AnchorName' + 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) and: 'the persistence service method is invoked with the correct parameters' 1 * mockCpsDataPersistenceService.deleteDataNodes(dataspaceName, anchorName) } diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy index 429de7d51b..690578ea05 100644 --- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy @@ -1,5 +1,5 @@ /* - * ============LICENSE_START======================================================= + * ============LICENSE_START======================================================= * Copyright (C) 2020-2022 Nordix Foundation * Modifications Copyright (C) 2020-2021 Pantheon.tech * Modifications Copyright (C) 2020-2022 Bell Canada. @@ -25,9 +25,9 @@ package org.onap.cps.api.impl import org.onap.cps.TestUtils import org.onap.cps.api.CpsAdminService import org.onap.cps.spi.CpsModulePersistenceService -import org.onap.cps.spi.exceptions.DataValidationException import org.onap.cps.spi.exceptions.ModelValidationException import org.onap.cps.spi.exceptions.SchemaSetInUseException +import org.onap.cps.spi.utils.CpsValidator import org.onap.cps.spi.model.Anchor import org.onap.cps.spi.model.ModuleReference import org.onap.cps.yang.YangTextSchemaSourceSetBuilder @@ -40,8 +40,9 @@ class CpsModuleServiceImplSpec extends Specification { def mockCpsModulePersistenceService = Mock(CpsModulePersistenceService) def mockCpsAdminService = Mock(CpsAdminService) def mockYangTextSchemaSourceSetCache = Mock(YangTextSchemaSourceSetCache) + def mockCpsValidator = Mock(CpsValidator) - def objectUnderTest = new CpsModuleServiceImpl(mockCpsModulePersistenceService, mockYangTextSchemaSourceSetCache, mockCpsAdminService) + def objectUnderTest = new CpsModuleServiceImpl(mockCpsModulePersistenceService, mockYangTextSchemaSourceSetCache, mockCpsAdminService, mockCpsValidator) def 'Create schema set.'() { given: 'Valid yang resource as name-to-content map' @@ -50,20 +51,8 @@ class CpsModuleServiceImplSpec extends Specification { objectUnderTest.createSchemaSet('someDataspace', 'someSchemaSet', yangResourcesNameToContentMap) then: 'Parameters are validated and processing is delegated to persistence service' 1 * mockCpsModulePersistenceService.storeSchemaSet('someDataspace', 'someSchemaSet', yangResourcesNameToContentMap) - } - - def 'Create a schema set with an invalid #scenario.'() { - when: 'create dataspace method is invoked with incorrectly named dataspace' - objectUnderTest.createSchemaSet(dataspaceName, schemaSetName, _ as Map<String, String>) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'the persistence service method is not invoked' - 0 * mockCpsModulePersistenceService.storeSchemaSet(_, _, _) - where: 'the following parameters are used' - scenario | dataspaceName | schemaSetName - 'dataspace name' | 'dataspace names with spaces' | 'schemaSetName' - 'schema set name name' | 'dataspaceName' | 'schema set name with spaces' - 'dataspace and schema set name' | 'dataspace name with spaces' | 'schema set name with spaces' + and: 'the CpsValidator is called on the dataspaceName and schemaSetName' + 1 * mockCpsValidator.validateNameCharacters('someDataspace', 'someSchemaSet') } def 'Create schema set from new modules and existing modules.'() { @@ -74,20 +63,8 @@ class CpsModuleServiceImplSpec extends Specification { objectUnderTest.createSchemaSetFromModules("someDataspaceName", "someSchemaSetName", [newModule: "newContent"], listOfExistingModulesModuleReference) then: 'processing is delegated to persistence service' 1 * mockCpsModulePersistenceService.storeSchemaSetFromModules("someDataspaceName", "someSchemaSetName", [newModule: "newContent"], listOfExistingModulesModuleReference) - } - - def 'Create schema set from new modules and existing modules with invalid #scenario.'() { - when: 'create dataspace method is invoked with incorrectly named dataspace' - objectUnderTest.createSchemaSetFromModules(dataspaceName, schemaSetName, _ as Map<String, String>, _ as Collection<ModuleReference>) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'the persistence service method is not invoked' - 0 * mockCpsModulePersistenceService.storeSchemaSetFromModules(_, _, _) - where: 'the following parameters are used' - scenario | dataspaceName | schemaSetName - 'dataspace name' | 'dataspace names with spaces' | 'schemaSetName' - 'schema set name name' | 'dataspaceName' | 'schema set name with spaces' - 'dataspace and schema set name' | 'dataspace name with spaces' | 'schema set name with spaces' + and: 'the CpsValidator is called on the dataspaceName and schemaSetName' + 1 * mockCpsValidator.validateNameCharacters('someDataspaceName', 'someSchemaSetName') } def 'Create schema set from invalid resources'() { @@ -110,20 +87,8 @@ class CpsModuleServiceImplSpec extends Specification { result.getName().contains('someSchemaSet') result.getDataspaceName().contains('someDataspace') result.getModuleReferences().contains(new ModuleReference('stores', '2020-09-15', 'org:onap:ccsdk:sample')) - } - - def 'Get a schema set with an invalid #scenario'() { - when: 'create dataspace method is invoked with incorrectly named dataspace' - objectUnderTest.getSchemaSet(dataspaceName, schemaSetName) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'the yang resource cache is not invoked' - 0 * mockYangTextSchemaSourceSetCache.get(_, _) - where: 'the following parameters are used' - scenario | dataspaceName | schemaSetName - 'dataspace name' | 'dataspace names with spaces' | 'schemaSetName' - 'schema set name' | 'dataspaceName' | 'schema set name with spaces' - 'dataspace and schema set name' | 'dataspace name with spaces' | 'schema set name with spaces' + and: 'the CpsValidator is called on the dataspaceName and schemaSetName' + 1 * mockCpsValidator.validateNameCharacters('someDataspace', 'someSchemaSet') } def 'Delete schema-set when cascade is allowed.'() { @@ -140,6 +105,8 @@ class CpsModuleServiceImplSpec extends Specification { 1 * mockYangTextSchemaSourceSetCache.removeFromCache('my-dataspace', 'my-schemaset') and: 'orphan yang resources are deleted' 1 * mockCpsModulePersistenceService.deleteUnusedYangResourceModules() + and: 'the CpsValidator is called on the dataspaceName and schemaSetName' + 1 * mockCpsValidator.validateNameCharacters('my-dataspace', _) where: 'following parameters are used' numberOfAnchors << [0, 3] } @@ -157,6 +124,8 @@ class CpsModuleServiceImplSpec extends Specification { 1 * mockYangTextSchemaSourceSetCache.removeFromCache('my-dataspace', 'my-schemaset') and: 'orphan yang resources are deleted' 1 * mockCpsModulePersistenceService.deleteUnusedYangResourceModules() + and: 'the CpsValidator is called on the dataspaceName and schemaSetName' + 1 * mockCpsValidator.validateNameCharacters('my-dataspace', 'my-schemaset') } def 'Delete schema-set when cascade is prohibited and schema-set has anchors.'() { @@ -168,26 +137,6 @@ class CpsModuleServiceImplSpec extends Specification { thrown(SchemaSetInUseException) } - def 'Delete a schema set with an invalid #scenario.'() { - when: 'create dataspace method is invoked with incorrectly named dataspace' - objectUnderTest.deleteSchemaSet(dataspaceName, schemaSetName, CASCADE_DELETE_ALLOWED) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'anchor deletion is called 0 times' - 0 * mockCpsAdminService.deleteAnchor(_, _) - and: 'the delete schema set persistence service method is not invoked' - 0 * mockCpsModulePersistenceService.deleteSchemaSet(_, _, _) - and: 'schema set will be removed from the cache is not invoked' - 0 * mockYangTextSchemaSourceSetCache.removeFromCache(_, _) - and: 'orphan yang resources are deleted is not invoked' - 0 * mockCpsModulePersistenceService.deleteUnusedYangResourceModules() - where: 'the following parameters are used' - scenario | dataspaceName | schemaSetName - 'dataspace name' | 'dataspace names with spaces' | 'schemaSetName' - 'schema set name name' | 'dataspaceName' | 'schema set name with spaces' - 'dataspace and schema set name' | 'dataspace name with spaces' | 'schema set name with spaces' - } - def createAnchors(int anchorCount) { def anchors = [] (0..<anchorCount).each { anchors.add(new Anchor("my-anchor-$it", 'my-dataspace', 'my-schemaset')) } @@ -198,40 +147,24 @@ class CpsModuleServiceImplSpec extends Specification { given: 'an already present module reference' def moduleReferences = [new ModuleReference('some module name','some revision name')] mockCpsModulePersistenceService.getYangResourceModuleReferences('someDataspaceName') >> moduleReferences - expect: 'the list provided by persistence service is returned as result' - objectUnderTest.getYangResourceModuleReferences('someDataspaceName') == moduleReferences - } - - def 'Get all yang resources module references given an invalid dataspace name.'() { - when: 'the get yang resources module references method is invoked with an invalid dataspace name' - objectUnderTest.getYangResourceModuleReferences('dataspace name with spaces') - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'the persistence service method is not invoked' - 0 * mockCpsModulePersistenceService.getYangResourceModuleReferences(_) + when: 'get yang resource module references is called' + def result = objectUnderTest.getYangResourceModuleReferences('someDataspaceName') + then: 'the list provided by persistence service is returned as result' + result == moduleReferences + and: 'the CpsValidator is called on the dataspaceName and schemaSetName' + 1 * mockCpsValidator.validateNameCharacters('someDataspaceName') } - def 'Get all yang resources module references for the given dataspace name and anchor name.'() { given: 'the module store service service returns a list module references' def moduleReferences = [new ModuleReference()] mockCpsModulePersistenceService.getYangResourceModuleReferences('someDataspaceName', 'someAnchorName') >> moduleReferences - expect: 'the list provided by persistence service is returned as result' - objectUnderTest.getYangResourcesModuleReferences('someDataspaceName', 'someAnchorName') == moduleReferences - } - - def 'Get all yang resources module references given an invalid #scenario.'() { - when: 'the get yang resources module references method is invoked with invalid #scenario' - objectUnderTest.getYangResourcesModuleReferences(dataspaceName, anchorName) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'the persistence service method is not invoked' - 0 * mockCpsModulePersistenceService.getYangResourceModuleReferences(_, _) - where: 'the following parameters are used' - scenario | dataspaceName | anchorName - 'dataspace name' | 'dataspace names with spaces' | 'anchorName' - 'anchor name' | 'dataspaceName' | 'anchor name with spaces' - 'dataspace and anchor name' | 'dataspace name with spaces' | 'anchor name with spaces' + when: 'get yang resource module references is called for dataspace name and anchor name' + def result = objectUnderTest.getYangResourcesModuleReferences('someDataspaceName', 'someAnchorName') + then: 'the list provided by persistence service is returned as result' + result == moduleReferences + and: 'the CpsValidator is called on the dataspaceName and schemaSetName' + 1 * mockCpsValidator.validateNameCharacters('someDataspaceName', 'someAnchorName') } def 'Identifying new module references'(){ @@ -248,5 +181,7 @@ class CpsModuleServiceImplSpec extends Specification { objectUnderTest.getModuleDefinitionsByAnchorName('some-dataspace-name', 'some-anchor-name') then: 'CPS module persistence service is invoked the correct number of times' 1 * mockCpsModulePersistenceService.getYangResourceDefinitions('some-dataspace-name', 'some-anchor-name') + and: 'the CpsValidator is called on the dataspaceName and schemaSetName' + 1 * mockCpsValidator.validateNameCharacters('some-dataspace-name', 'some-anchor-name') } } diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy index b7fec85119..8b232b420d 100644 --- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy @@ -1,5 +1,5 @@ /* - * ============LICENSE_START======================================================= + * ============LICENSE_START======================================================= * Copyright (C) 2021-2022 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,17 +22,14 @@ package org.onap.cps.api.impl import org.onap.cps.spi.CpsDataPersistenceService import org.onap.cps.spi.FetchDescendantsOption -import org.onap.cps.spi.exceptions.DataValidationException +import org.onap.cps.spi.utils.CpsValidator import spock.lang.Specification class CpsQueryServiceImplSpec extends Specification { def mockCpsDataPersistenceService = Mock(CpsDataPersistenceService) + def mockCpsValidator = Mock(CpsValidator) - def objectUnderTest = new CpsQueryServiceImpl() - - def setup() { - objectUnderTest.cpsDataPersistenceService = mockCpsDataPersistenceService - } + def objectUnderTest = new CpsQueryServiceImpl(mockCpsDataPersistenceService, mockCpsValidator) def 'Query data nodes by cps path with #fetchDescendantsOption.'() { given: 'a dataspace name, an anchor name and a cps path' @@ -43,22 +40,10 @@ class CpsQueryServiceImplSpec extends Specification { objectUnderTest.queryDataNodes(dataspaceName, anchorName, cpsPath, fetchDescendantsOption) then: 'the persistence service is called once with the correct parameters' 1 * mockCpsDataPersistenceService.queryDataNodes(dataspaceName, anchorName, cpsPath, fetchDescendantsOption) + and: 'the CpsValidator is called on the dataspaceName, schemaSetName and anchorName' + 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) where: 'all fetch descendants options are supported' fetchDescendantsOption << [FetchDescendantsOption.OMIT_DESCENDANTS, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS] } - def 'Query data nodes by cps path with invalid #scenario.'() { - when: 'queryDataNodes is invoked' - objectUnderTest.queryDataNodes(dataspaceName, anchorName, '/cps-path', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) - then: 'a data validation exception is thrown' - thrown(DataValidationException) - and: 'the persistence service is not invoked' - 0 * mockCpsDataPersistenceService.queryDataNodes(_, _, _, _) - where: 'the following parameters are used' - scenario | dataspaceName | anchorName - 'dataspace name' | 'dataspace names with spaces' | 'anchorName' - 'anchor name' | 'dataspaceName' | 'anchor name with spaces' - 'dataspace and anchor name' | 'dataspace name with spaces' | 'anchor name with spaces' - } - } 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 52389522f8..2fc85aa5a4 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 @@ -1,6 +1,6 @@ /*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation.
+ * Copyright (C) 2021-2022 Nordix Foundation.
* Modifications Copyright (C) 2021-2022 Bell Canada.
* Modifications Copyright (C) 2021 Pantheon.tech
* ================================================================================
@@ -8,7 +8,7 @@ * 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
+ * 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,
@@ -28,6 +28,7 @@ import org.onap.cps.notification.NotificationService import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.spi.CpsModulePersistenceService
import org.onap.cps.spi.model.Anchor
+import org.onap.cps.spi.utils.CpsValidator
import org.onap.cps.utils.YangUtils
import org.onap.cps.yang.YangTextSchemaSourceSetBuilder
import spock.lang.Specification
@@ -38,10 +39,11 @@ class E2ENetworkSliceSpec extends Specification { def mockCpsAdminService = Mock(CpsAdminService)
def mockNotificationService = Mock(NotificationService)
def mockYangTextSchemaSourceSetCache = Mock(YangTextSchemaSourceSetCache)
+ def mockCpsValidator = Mock(CpsValidator)
def cpsModuleServiceImpl = new CpsModuleServiceImpl(mockModuleStoreService,
- mockYangTextSchemaSourceSetCache,mockCpsAdminService )
+ mockYangTextSchemaSourceSetCache, mockCpsAdminService, mockCpsValidator)
def cpsDataServiceImpl = new CpsDataServiceImpl(mockDataStoreService, mockCpsAdminService,
- mockYangTextSchemaSourceSetCache, mockNotificationService)
+ mockYangTextSchemaSourceSetCache, mockNotificationService, mockCpsValidator)
def dataspaceName = 'someDataspace'
def anchorName = 'someAnchor'
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/YangTextSchemaSourceSetCacheSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/YangTextSchemaSourceSetCacheSpec.groovy index 06c675a255..a9f50ee5b0 100644 --- a/cps-service/src/test/groovy/org/onap/cps/api/impl/YangTextSchemaSourceSetCacheSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/YangTextSchemaSourceSetCacheSpec.groovy @@ -1,5 +1,5 @@ /* - * ============LICENSE_START======================================================= + * ============LICENSE_START======================================================= * Copyright (C) 2022 Bell Canada * Modifications Copyright (C) 2022 Nordix Foundation * ================================================================================ @@ -23,7 +23,6 @@ package org.onap.cps.api.impl import org.onap.cps.TestUtils import org.onap.cps.spi.CpsModulePersistenceService -import org.onap.cps.spi.exceptions.DataValidationException import org.onap.cps.yang.YangTextSchemaSourceSet import org.onap.cps.yang.YangTextSchemaSourceSetBuilder import org.spockframework.spring.SpringBean @@ -35,6 +34,8 @@ import org.springframework.cache.annotation.EnableCaching import org.springframework.cache.caffeine.CaffeineCacheManager import org.springframework.test.context.ContextConfiguration import spock.lang.Specification +import org.onap.cps.spi.utils.CpsValidator + @SpringBootTest @EnableCaching @@ -44,6 +45,9 @@ class YangTextSchemaSourceSetCacheSpec extends Specification { @SpringBean CpsModulePersistenceService mockModuleStoreService = Mock() + @SpringBean + CpsValidator mockCpsValidator = Mock(CpsValidator) + @Autowired YangTextSchemaSourceSetCache objectUnderTest @@ -74,6 +78,8 @@ class YangTextSchemaSourceSetCacheSpec extends Specification { assert cachedValue.getModuleReferences() == expectedYangTextSchemaSourceSet.getModuleReferences() and: 'the response is as expected' assert result.getModuleReferences() == expectedYangTextSchemaSourceSet.getModuleReferences() + and: 'the CpsValidator is called on the dataspaceName and schemaSetName' + 1 * mockCpsValidator.validateNameCharacters('my-dataspace', 'my-schemaset') } def 'Cache Hit: Respond from cache'() { @@ -90,20 +96,6 @@ class YangTextSchemaSourceSetCacheSpec extends Specification { 0 * mockModuleStoreService.getYangSchemaResources(_, _) } - def 'Cache Hit: with invalid #scenario'() { - when: 'schema-set information is asked' - objectUnderTest.get(dataspaceName, schemaSetName) - then: 'an data validation exception is thrown' - thrown(DataValidationException) - and: 'module persistence is not invoked' - 0 * mockModuleStoreService.getYangSchemaResources(_, _) - where: 'the following parameters are used' - scenario | dataspaceName | schemaSetName - 'dataspace name' | 'dataspace names with spaces' | 'schemaSetName' - 'schema set name' | 'dataspaceName' | 'schema set name with spaces' - 'dataspace and schema set name' | 'dataspace name with spaces' | 'schema set name with spaces' - } - def 'Cache Update: when no data exist in the cache'() { given: 'a schema set exists' def yangResourcesNameToContentMap = TestUtils.getYangResourcesAsMap('bookstore.yang') @@ -113,23 +105,8 @@ class YangTextSchemaSourceSetCacheSpec extends Specification { then: 'cached value is same as expected' def cachedValue = getCachedValue('my-dataspace', 'my-schemaset') cachedValue.getModuleReferences() == yangTextSchemaSourceSet.getModuleReferences() - } - - def 'Cache Update: with invalid #scenario'() { - given: 'a schema set exists' - def yangResourcesNameToContentMap = TestUtils.getYangResourcesAsMap('bookstore.yang') - def yangTextSchemaSourceSet = YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap) - when: 'schema-set information is asked' - objectUnderTest.updateCache(dataspaceName, schemaSetName, yangTextSchemaSourceSet) - then: 'an data validation exception is thrown' - thrown(DataValidationException) - and: 'module persistence is not invoked' - 0 * mockModuleStoreService.getYangSchemaResources(_, _) - where: 'the following parameters are used' - scenario | dataspaceName | schemaSetName - 'dataspace name' | 'dataspace names with spaces' | 'schemaSetName' - 'schema set name' | 'dataspaceName' | 'schema set name with spaces' - 'dataspace and schema set name' | 'dataspace name with spaces' | 'schema set name with spaces' + and: 'the CpsValidator is called on the dataspaceName and schemaSetName' + 1 * mockCpsValidator.validateNameCharacters('my-dataspace', 'my-schemaset') } def 'Cache Evict:with invalid #scenario'() { @@ -143,18 +120,8 @@ class YangTextSchemaSourceSetCacheSpec extends Specification { objectUnderTest.removeFromCache('my-dataspace', 'my-schemaset') then: 'cached does not have value' assert getCachedValue('my-dataspace', 'my-schemaset') == null - } - - def 'Cache Evict: remove when exist'() { - when: 'cache is evicted for schemaset' - objectUnderTest.removeFromCache(dataspaceName, schemaSetName) - then: 'an data validation exception is thrown' - thrown(DataValidationException) - where: 'the following parameters are used' - scenario | dataspaceName | schemaSetName - 'dataspace name' | 'dataspace names with spaces' | 'schemaSetName' - 'schema set name' | 'dataspaceName' | 'schema set name with spaces' - 'dataspace and schema set name' | 'dataspace name with spaces' | 'schema set name with spaces' + and: 'the CpsValidator is called on the dataspaceName and schemaSetName' + 1 * mockCpsValidator.validateNameCharacters('my-dataspace', 'my-schemaset') } def 'Cache Evict: remove when does not exist'() { @@ -164,6 +131,8 @@ class YangTextSchemaSourceSetCacheSpec extends Specification { objectUnderTest.removeFromCache('my-dataspace', 'my-schemaset') then: 'cached does not have value' assert getCachedValue('my-dataspace', 'my-schemaset') == null + and: 'the CpsValidator is called on the dataspaceName and schemaSetName' + 1 * mockCpsValidator.validateNameCharacters('my-dataspace', 'my-schemaset') } def getCachedValue(dataSpace, schemaSet) { diff --git a/cps-service/src/test/groovy/org/onap/cps/utils/CpsValidatorSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/utils/CpsValidatorSpec.groovy deleted file mode 100644 index ea7a5d6d1d..0000000000 --- a/cps-service/src/test/groovy/org/onap/cps/utils/CpsValidatorSpec.groovy +++ /dev/null @@ -1,48 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022 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.utils - -import org.onap.cps.spi.exceptions.DataValidationException -import spock.lang.Specification - -class CpsValidatorSpec extends Specification { - - def 'Validating a valid string.'() { - when: 'the string is validated using a valid name' - CpsValidator.validateNameCharacters('name-with-no-spaces') - then: 'no exception is thrown' - noExceptionThrown() - } - - def 'Validating an invalid string.'() { - when: 'the string is validated using an invalid name' - CpsValidator.validateNameCharacters(name) - then: 'a data validation exception is thrown' - def exceptionThrown = thrown(DataValidationException) - and: 'the error was encountered at the following index in #scenario' - assert exceptionThrown.getDetails().contains(expectedErrorMessage) - where: 'the following names are used' - scenario | name || expectedErrorMessage - 'position 5' | 'name with spaces' || 'name with spaces invalid token encountered at position 5' - 'position 9' | 'nameWith Space' || 'nameWith Space invalid token encountered at position 9' - } - -} |