2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2021 Nordix Foundation
4 * Modifications Copyright (C) 2021 Pantheon.tech
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.cps.api.impl
23 import org.onap.cps.TestUtils
24 import org.onap.cps.api.CpsAdminService
25 import org.onap.cps.api.CpsModuleService
26 import org.onap.cps.spi.CpsDataPersistenceService
27 import org.onap.cps.spi.FetchDescendantsOption
28 import org.onap.cps.spi.model.Anchor
29 import org.onap.cps.spi.model.DataNodeBuilder
30 import org.onap.cps.yang.YangTextSchemaSourceSet
31 import org.onap.cps.yang.YangTextSchemaSourceSetBuilder
32 import spock.lang.Specification
34 class CpsDataServiceImplSpec extends Specification {
35 def mockCpsDataPersistenceService = Mock(CpsDataPersistenceService)
36 def mockCpsAdminService = Mock(CpsAdminService)
37 def mockCpsModuleService = Mock(CpsModuleService)
38 def mockYangTextSchemaSourceSetCache = Mock(YangTextSchemaSourceSetCache)
40 def objectUnderTest = new CpsDataServiceImpl()
43 objectUnderTest.cpsDataPersistenceService = mockCpsDataPersistenceService
44 objectUnderTest.cpsAdminService = mockCpsAdminService
45 objectUnderTest.cpsModuleService = mockCpsModuleService
46 objectUnderTest.yangTextSchemaSourceSetCache = mockYangTextSchemaSourceSetCache
49 def dataspaceName = 'some dataspace'
50 def anchorName = 'some anchor'
51 def schemaSetName = 'some schema set'
53 def 'Saving json data.'() {
54 given: 'that the admin service will return an anchor'
55 def anchor = Anchor.builder().name(anchorName).schemaSetName(schemaSetName).build()
56 mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> anchor
57 and: 'the schema source set cache returns a schema source set'
58 def mockYangTextSchemaSourceSet = Mock(YangTextSchemaSourceSet)
59 mockYangTextSchemaSourceSetCache.get(dataspaceName, schemaSetName) >> mockYangTextSchemaSourceSet
60 and: 'the schema source sets returns the test-tree schema context'
61 def yangResourceNameToContent = TestUtils.getYangResourcesAsMap('test-tree.yang')
62 def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent).getSchemaContext()
63 mockYangTextSchemaSourceSet.getSchemaContext() >> schemaContext
64 when: 'save data method is invoked with test-tree json data'
65 def jsonData = TestUtils.getResourceFileContent('test-tree.json')
66 objectUnderTest.saveData(dataspaceName, anchorName, jsonData)
67 then: 'the persistence service method is invoked with correct parameters'
68 1 * mockCpsDataPersistenceService.storeDataNode(dataspaceName, anchorName,
69 { dataNode -> dataNode.xpath == '/test-tree' })
72 def 'Saving child data fragment under existing node.'() {
73 given: 'that the admin service will return an anchor'
74 def anchor = Anchor.builder().name(anchorName).schemaSetName(schemaSetName).build()
75 mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> anchor
76 and: 'the schema source set cache returns a schema source set'
77 def mockYangTextSchemaSourceSet = Mock(YangTextSchemaSourceSet)
78 mockYangTextSchemaSourceSetCache.get(dataspaceName, schemaSetName) >> mockYangTextSchemaSourceSet
79 and: 'the schema source sets returns the test-tree schema context'
80 def yangResourceNameToContent = TestUtils.getYangResourcesAsMap('test-tree.yang')
81 def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent).getSchemaContext()
82 mockYangTextSchemaSourceSet.getSchemaContext() >> schemaContext
83 when: 'save data method is invoked with test-tree json data'
84 def jsonData = '{"branch": [{"name": "New"}]}'
85 objectUnderTest.saveData(dataspaceName, anchorName, '/test-tree',jsonData)
86 then: 'the persistence service method is invoked with correct parameters'
87 1 * mockCpsDataPersistenceService.addChildDataNode(dataspaceName, anchorName,'/test-tree',
88 { dataNode -> dataNode.xpath == '/test-tree/branch[@name=\'New\']' })
91 def 'Get data node with option #fetchDescendantsOption.'() {
93 def dataNode = new DataNodeBuilder().withXpath(xpath).build()
94 given: 'persistence service returns data for get data request'
95 mockCpsDataPersistenceService.getDataNode(dataspaceName, anchorName, xpath, fetchDescendantsOption) >> dataNode
96 expect: 'service returns same data if uses same parameters'
97 objectUnderTest.getDataNode(dataspaceName, anchorName, xpath, fetchDescendantsOption) == dataNode
98 where: 'all fetch options are supported'
99 fetchDescendantsOption << FetchDescendantsOption.values()
102 def 'Update data node leaves: #scenario.'() {
103 given: 'that the admin service will return an anchor'
104 def anchor = Anchor.builder().name(anchorName).schemaSetName(schemaSetName).build()
105 mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> anchor
106 and: 'the schema source set cache returns a schema source set'
107 def mockYangTextSchemaSourceSet = Mock(YangTextSchemaSourceSet)
108 mockYangTextSchemaSourceSetCache.get(dataspaceName, schemaSetName) >> mockYangTextSchemaSourceSet
109 and: 'the schema source sets returns the test-tree schema context'
110 def yangResourceNameToContent = TestUtils.getYangResourcesAsMap('test-tree.yang')
111 def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent).getSchemaContext()
112 mockYangTextSchemaSourceSet.getSchemaContext() >> schemaContext
113 when: 'update data method is invoked with json data #jsonData and parent node xpath #parentNodeXpath'
114 objectUnderTest.updateNodeLeaves(dataspaceName, anchorName, parentNodeXpath, jsonData)
115 then: 'the persistence service method is invoked with correct parameters'
116 1 * mockCpsDataPersistenceService.updateDataLeaves(dataspaceName, anchorName, nodeXpath, leaves)
117 where: 'following parameters were used'
118 scenario | parentNodeXpath | jsonData | nodeXpath | leaves
119 'top level node' | '/' | '{ "test-tree": {"branch": []}}' | '/test-tree' | Collections.emptyMap()
120 'level 2 node' | '/test-tree' | '{"branch": [{"name":"Name"}]}' | '/test-tree/branch[@name=\'Name\']' | ['name': 'Name']
123 def 'Replace data node: #scenario.'() {
124 given: 'that the admin service will return an anchor'
125 def anchor = Anchor.builder().name(anchorName).schemaSetName(schemaSetName).build()
126 mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> anchor
127 and: 'the schema source set cache returns a schema source set'
128 def mockYangTextSchemaSourceSet = Mock(YangTextSchemaSourceSet)
129 mockYangTextSchemaSourceSetCache.get(dataspaceName, schemaSetName) >> mockYangTextSchemaSourceSet
130 and: 'the schema source sets returns the test-tree schema context'
131 def yangResourceNameToContent = TestUtils.getYangResourcesAsMap('test-tree.yang')
132 def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent).getSchemaContext()
133 mockYangTextSchemaSourceSet.getSchemaContext() >> schemaContext
134 when: 'replace data method is invoked with json data #jsonData and parent node xpath #parentNodeXpath'
135 objectUnderTest.replaceNodeTree(dataspaceName, anchorName, parentNodeXpath, jsonData)
136 then: 'the persistence service method is invoked with correct parameters'
137 1 * mockCpsDataPersistenceService.replaceDataNodeTree(dataspaceName, anchorName,
138 { dataNode -> dataNode.xpath == nodeXpath })
139 where: 'following parameters were used'
140 scenario | parentNodeXpath | jsonData | nodeXpath
141 'top level node' | '/' | '{ "test-tree": {"branch": []}}' | '/test-tree'
142 'level 2 node' | '/test-tree' | '{"branch": [{"name":"Name"}]}' | '/test-tree/branch[@name=\'Name\']'