2 * ============LICENSE_START=======================================================
\r
3 * Copyright (C) 2021-2023 Nordix Foundation.
\r
4 * Modifications Copyright (C) 2021-2022 Bell Canada.
\r
5 * Modifications Copyright (C) 2021 Pantheon.tech
\r
6 * Modifications Copyright (C) 2022-2023 TechMahindra Ltd.
\r
7 * ================================================================================
\r
8 * Licensed under the Apache License, Version 2.0 (the "License");
\r
9 * you may not use this file except in compliance with the License.
\r
10 * You may obtain a copy of the License at
\r
12 * http://www.apache.org/licenses/LICENSE-2.0
\r
14 * Unless required by applicable law or agreed to in writing, software
\r
15 * distributed under the License is distributed on an "AS IS" BASIS,
\r
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
17 * See the License for the specific language governing permissions and
\r
18 * limitations under the License.
\r
20 * SPDX-License-Identifier: Apache-2.0
\r
21 * ============LICENSE_END=========================================================
\r
24 package org.onap.cps.api.impl
\r
26 import org.onap.cps.TestUtils
\r
27 import org.onap.cps.api.CpsAdminService
\r
28 import org.onap.cps.api.CpsDeltaService
\r
29 import org.onap.cps.notification.NotificationService
\r
30 import org.onap.cps.spi.CpsDataPersistenceService
\r
31 import org.onap.cps.spi.CpsModulePersistenceService
\r
32 import org.onap.cps.spi.model.Anchor
\r
33 import org.onap.cps.spi.utils.CpsValidator
\r
34 import org.onap.cps.utils.TimedYangParser
\r
35 import org.onap.cps.utils.YangUtils
\r
36 import org.onap.cps.yang.TimedYangTextSchemaSourceSetBuilder
\r
37 import org.onap.cps.yang.YangTextSchemaSourceSetBuilder
\r
38 import spock.lang.Specification
\r
40 class E2ENetworkSliceSpec extends Specification {
\r
41 def mockModuleStoreService = Mock(CpsModulePersistenceService)
\r
42 def mockDataStoreService = Mock(CpsDataPersistenceService)
\r
43 def mockCpsAdminService = Mock(CpsAdminService)
\r
44 def mockNotificationService = Mock(NotificationService)
\r
45 def mockYangTextSchemaSourceSetCache = Mock(YangTextSchemaSourceSetCache)
\r
46 def mockCpsValidator = Mock(CpsValidator)
\r
47 def timedYangTextSchemaSourceSetBuilder = new TimedYangTextSchemaSourceSetBuilder()
\r
48 def timedYangParser = new TimedYangParser()
\r
49 def mockCpsDeltaService = Mock(CpsDeltaService)
\r
51 def cpsModuleServiceImpl = new CpsModuleServiceImpl(mockModuleStoreService,
\r
52 mockYangTextSchemaSourceSetCache, mockCpsAdminService, mockCpsValidator,timedYangTextSchemaSourceSetBuilder)
\r
54 def cpsDataServiceImpl = new CpsDataServiceImpl(mockDataStoreService, mockCpsAdminService,
\r
55 mockYangTextSchemaSourceSetCache, mockNotificationService, mockCpsValidator, timedYangParser, mockCpsDeltaService)
\r
57 def dataspaceName = 'someDataspace'
\r
58 def anchorName = 'someAnchor'
\r
59 def schemaSetName = 'someSchemaSet'
\r
60 def noTimestamp = null
\r
62 def 'E2E model can be parsed by CPS.'() {
\r
63 given: 'Valid yang resource as name-to-content map'
\r
64 def yangResourcesNameToContentMap = TestUtils.getYangResourcesAsMap(
\r
65 'ietf/ietf-inet-types@2013-07-15.yang',
\r
66 'ietf/ietf-yang-types@2013-07-15.yang',
\r
67 'e2e/basic/ran-network2020-08-06.yang'
\r
69 when: 'Create schema set method is invoked'
\r
70 cpsModuleServiceImpl.createSchemaSet(dataspaceName, schemaSetName, yangResourcesNameToContentMap)
\r
71 then: 'Parameters are validated and processing is delegated to persistence service'
\r
72 1 * mockModuleStoreService.storeSchemaSet(dataspaceName, schemaSetName, yangResourcesNameToContentMap)
\r
75 def 'E2E Coverage Area-Tracking Area & TA-Cell mapping model can be parsed by CPS.'() {
\r
76 given: 'Valid yang resource as name-to-content map'
\r
77 def yangResourcesNameToContentMap = TestUtils.getYangResourcesAsMap(
\r
78 'e2e/basic/cps-cavsta-onap-internal2021-01-28.yang')
\r
79 when: 'Create schema set method is invoked'
\r
80 cpsModuleServiceImpl.createSchemaSet(dataspaceName, schemaSetName, yangResourcesNameToContentMap)
\r
81 then: 'Parameters are validated and processing is delegated to persistence service'
\r
82 1 * mockModuleStoreService.storeSchemaSet(dataspaceName, schemaSetName, yangResourcesNameToContentMap)
\r
85 def 'E2E Coverage Area-Tracking Area & TA-Cell mapping data can be parsed by CPS.'() {
\r
86 given: 'Valid yang resource as name-to-content map'
\r
87 def yangResourcesNameToContentMap = TestUtils.getYangResourcesAsMap(
\r
88 'e2e/basic/cps-cavsta-onap-internal2021-01-28.yang')
\r
89 def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap).getSchemaContext()
\r
91 and : 'a valid json is provided for the model'
\r
92 def jsonData = TestUtils.getResourceFileContent('e2e/basic/cps-Cavsta-Data.txt')
\r
93 and : 'all the further dependencies are mocked '
\r
94 mockCpsAdminService.getAnchor(dataspaceName, anchorName) >>
\r
95 new Anchor().builder().name(anchorName).schemaSetName(schemaSetName).dataspaceName(dataspaceName).build()
\r
96 mockYangTextSchemaSourceSetCache.get(dataspaceName, schemaSetName) >>
\r
97 YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap)
\r
98 mockModuleStoreService.getYangSchemaResources(dataspaceName, schemaSetName) >> schemaContext
\r
99 when: 'saveData method is invoked'
\r
100 cpsDataServiceImpl.saveData(dataspaceName, anchorName, jsonData, noTimestamp)
\r
101 then: 'Parameters are validated and processing is delegated to persistence service'
\r
102 1 * mockDataStoreService.storeDataNodes('someDataspace', 'someAnchor', _) >>
\r
103 { args -> dataNodeStored = args[2]}
\r
104 def child = dataNodeStored[0].childDataNodes[0]
\r
105 assert child.childDataNodes.size() == 1
\r
106 and: 'list of Tracking Area for a Coverage Area are stored with correct xpath and child nodes '
\r
107 def listOfTAForCoverageArea = child.childDataNodes[0]
\r
108 listOfTAForCoverageArea.xpath == '/ran-coverage-area/pLMNIdList[@mcc=\'310\' and @mnc=\'410\']/' +
\r
109 'coverage-area[@coverageArea=\'Washington\']'
\r
110 listOfTAForCoverageArea.childDataNodes[0].leaves.get('nRTAC') == 234
\r
111 and: 'list of cells in a tracking area are stored with correct xpath and child nodes '
\r
112 def listOfCellsInTrackingArea = listOfTAForCoverageArea.childDataNodes[0]
\r
113 listOfCellsInTrackingArea.xpath == '/ran-coverage-area/pLMNIdList[@mcc=\'310\' and @mnc=\'410\']/' +
\r
114 'coverage-area[@coverageArea=\'Washington\']/coverageAreaTAList[@nRTAC=\'234\']'
\r
115 listOfCellsInTrackingArea.childDataNodes[0].leaves.get('cellLocalId') == 15709
\r
118 def 'E2E Coverage Area-Tracking Area & TA-Cell mapping data can be parsed for RAN inventory.'() {
\r
120 given: 'valid yang resource as name-to-content map'
\r
121 def yangResourcesNameToContentMap = TestUtils.getYangResourcesAsMap(
\r
122 'e2e/basic/cps-ran-inventory@2021-01-28.yang')
\r
123 def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap).getSchemaContext()
\r
124 and : 'a valid json is provided for the model'
\r
125 def jsonData = TestUtils.getResourceFileContent('e2e/basic/cps-ran-inventory-data.json')
\r
126 and : 'all the further dependencies are mocked '
\r
127 mockCpsAdminService.getAnchor('someDataspace', 'someAnchor') >>
\r
128 new Anchor().builder().name('someAnchor').schemaSetName('someSchemaSet').dataspaceName(dataspaceName).build()
\r
129 mockYangTextSchemaSourceSetCache.get('someDataspace', 'someSchemaSet') >> YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap)
\r
130 mockModuleStoreService.getYangSchemaResources('someDataspace', 'someSchemaSet') >> schemaContext
\r
131 when: 'saveData method is invoked'
\r
132 cpsDataServiceImpl.saveData('someDataspace', 'someAnchor', jsonData, noTimestamp)
\r
133 then: 'parameters are validated and processing is delegated to persistence service'
\r
134 1 * mockDataStoreService.storeDataNodes('someDataspace', 'someAnchor', _) >>
\r
135 { args -> dataNodeStored = args[2]}
\r
136 and: 'the size of the tree is correct'
\r
137 def cpsRanInventory = TestUtils.getFlattenMapByXpath(dataNodeStored[0])
\r
138 assert cpsRanInventory.size() == 4
\r
139 and: 'ran-inventory contains the correct child node'
\r
140 def ranInventory = cpsRanInventory.get('/ran-inventory')
\r
141 def ranSlices = cpsRanInventory.get('/ran-inventory/ran-slices[@rannfnssiid=\'14559ead-f4fe-4c1c-a94c-8015fad3ea35\']')
\r
142 def sliceProfilesList = cpsRanInventory.get('/ran-inventory/ran-slices[@rannfnssiid=\'14559ead-f4fe-4c1c-a94c-8015fad3ea35\']/sliceProfilesList[@sliceProfileId=\'f33a9dd8-ae51-4acf-8073-c9390c25f6f1\']')
\r
143 def pLMNIdList = cpsRanInventory.get('/ran-inventory/ran-slices[@rannfnssiid=\'14559ead-f4fe-4c1c-a94c-8015fad3ea35\']/sliceProfilesList[@sliceProfileId=\'f33a9dd8-ae51-4acf-8073-c9390c25f6f1\']/pLMNIdList[@mcc=\'310\' and @mnc=\'410\']')
\r
144 ranInventory.getChildDataNodes().size() == 1
\r
145 ranInventory.getChildDataNodes().find( {it.xpath == ranSlices.xpath})
\r
146 and: 'ranSlices contains the correct child node'
\r
147 ranSlices.getChildDataNodes().size() == 1
\r
148 ranSlices.getChildDataNodes().find( {it.xpath == sliceProfilesList.xpath})
\r
149 and: 'sliceProfilesList contains the correct child node'
\r
150 sliceProfilesList.getChildDataNodes().size() == 1
\r
151 sliceProfilesList.getChildDataNodes().find( {it.xpath == pLMNIdList.xpath})
\r
152 and: 'pLMNIdList contains no children'
\r
153 pLMNIdList.getChildDataNodes().size() == 0
\r
157 def 'E2E RAN Schema Model.'(){
\r
158 given: 'yang resources'
\r
159 def yangResourcesNameToContentMap = TestUtils.getYangResourcesAsMap(
\r
160 'ietf/ietf-inet-types@2013-07-15.yang',
\r
161 'ietf/ietf-yang-types@2013-07-15.yang',
\r
162 'e2e/basic/cps-ran-schema-model@2021-05-19.yang'
\r
165 def jsonData = TestUtils.getResourceFileContent('e2e/basic/cps-ran-schema-model-data-v4.json')
\r
166 expect: 'schema context is built with no exception indicating the schema set being valid '
\r
167 def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap).getSchemaContext()
\r
168 and: 'data is parsed with no exception indicating the model match'
\r
169 YangUtils.parseJsonData(jsonData, schemaContext) != null
\r