CPS Delta API 2: Delta between anchor and payload
[cps.git] / cps-service / src / test / groovy / org / onap / cps / api / impl / E2ENetworkSliceSpec.groovy
1 /*\r
2  * ============LICENSE_START=======================================================\r
3  * Copyright (C) 2021-2024 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-2024 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
11  *\r
12  *       http://www.apache.org/licenses/LICENSE-2.0\r
13  *\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
19  *\r
20  * SPDX-License-Identifier: Apache-2.0\r
21  * ============LICENSE_END=========================================================\r
22  */\r
23 \r
24 package org.onap.cps.api.impl\r
25 \r
26 import com.fasterxml.jackson.databind.ObjectMapper\r
27 import org.onap.cps.TestUtils\r
28 import org.onap.cps.api.CpsAnchorService\r
29 import org.onap.cps.api.CpsDeltaService\r
30 import org.onap.cps.events.CpsDataUpdateEventsService\r
31 import org.onap.cps.spi.CpsDataPersistenceService\r
32 import org.onap.cps.spi.CpsModulePersistenceService\r
33 import org.onap.cps.spi.model.Anchor\r
34 import org.onap.cps.spi.utils.CpsValidator\r
35 import org.onap.cps.utils.JsonObjectMapper\r
36 import org.onap.cps.utils.PrefixResolver\r
37 import org.onap.cps.utils.ContentType\r
38 import org.onap.cps.utils.YangParser\r
39 import org.onap.cps.utils.YangParserHelper\r
40 import org.onap.cps.yang.TimedYangTextSchemaSourceSetBuilder\r
41 import org.onap.cps.yang.YangTextSchemaSourceSetBuilder\r
42 import spock.lang.Specification\r
43 \r
44 class E2ENetworkSliceSpec extends Specification {\r
45     def mockModuleStoreService = Mock(CpsModulePersistenceService)\r
46     def mockDataStoreService = Mock(CpsDataPersistenceService)\r
47     def mockCpsAnchorService = Mock(CpsAnchorService)\r
48     def mockYangTextSchemaSourceSetCache = Mock(YangTextSchemaSourceSetCache)\r
49     def mockCpsValidator = Mock(CpsValidator)\r
50     def timedYangTextSchemaSourceSetBuilder = new TimedYangTextSchemaSourceSetBuilder()\r
51     def yangParser = new YangParser(new YangParserHelper(), mockYangTextSchemaSourceSetCache, timedYangTextSchemaSourceSetBuilder)\r
52     def mockCpsDeltaService = Mock(CpsDeltaService)\r
53     def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())\r
54     def mockPrefixResolver = Mock(PrefixResolver)\r
55 \r
56     def cpsModuleServiceImpl = new CpsModuleServiceImpl(mockModuleStoreService,\r
57             mockYangTextSchemaSourceSetCache, mockCpsAnchorService, mockCpsValidator,timedYangTextSchemaSourceSetBuilder)\r
58 \r
59     def mockDataUpdateEventsService = Mock(CpsDataUpdateEventsService)\r
60     def cpsDataServiceImpl = new CpsDataServiceImpl(mockDataStoreService, mockDataUpdateEventsService, mockCpsAnchorService, mockCpsValidator,\r
61             yangParser, mockCpsDeltaService, jsonObjectMapper, mockPrefixResolver)\r
62     def dataspaceName = 'someDataspace'\r
63     def anchorName = 'someAnchor'\r
64     def schemaSetName = 'someSchemaSet'\r
65     def noTimestamp = null\r
66 \r
67     def 'E2E model can be parsed by CPS.'() {\r
68         given: 'Valid yang resource as name-to-content map'\r
69             def yangResourcesNameToContentMap = TestUtils.getYangResourcesAsMap(\r
70                     'ietf/ietf-inet-types@2013-07-15.yang',\r
71                     'ietf/ietf-yang-types@2013-07-15.yang',\r
72                     'e2e/basic/ran-network2020-08-06.yang'\r
73             )\r
74         when: 'Create schema set method is invoked'\r
75             cpsModuleServiceImpl.createSchemaSet(dataspaceName, schemaSetName, yangResourcesNameToContentMap)\r
76         then: 'Parameters are validated and processing is delegated to persistence service'\r
77             1 * mockModuleStoreService.storeSchemaSet(dataspaceName, schemaSetName, yangResourcesNameToContentMap)\r
78     }\r
79 \r
80     def 'E2E Coverage Area-Tracking Area & TA-Cell mapping model can be parsed by CPS.'() {\r
81         given: 'Valid yang resource as name-to-content map'\r
82             def yangResourcesNameToContentMap = TestUtils.getYangResourcesAsMap(\r
83                     'e2e/basic/cps-cavsta-onap-internal2021-01-28.yang')\r
84         when: 'Create schema set method is invoked'\r
85             cpsModuleServiceImpl.createSchemaSet(dataspaceName, schemaSetName, yangResourcesNameToContentMap)\r
86         then: 'Parameters are validated and processing is delegated to persistence service'\r
87             1 * mockModuleStoreService.storeSchemaSet(dataspaceName, schemaSetName, yangResourcesNameToContentMap)\r
88     }\r
89 \r
90     def 'E2E Coverage Area-Tracking Area & TA-Cell mapping data can be parsed by CPS.'() {\r
91         given: 'Valid yang resource as name-to-content map'\r
92             def yangResourcesNameToContentMap = TestUtils.getYangResourcesAsMap(\r
93                     'e2e/basic/cps-cavsta-onap-internal2021-01-28.yang')\r
94             def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap).getSchemaContext()\r
95             def dataNodeStored\r
96         and : 'a valid json is provided for the model'\r
97             def jsonData = TestUtils.getResourceFileContent('e2e/basic/cps-Cavsta-Data.txt')\r
98         and : 'all the further dependencies are mocked '\r
99             mockCpsAnchorService.getAnchor(dataspaceName, anchorName) >>\r
100                     new Anchor().builder().name(anchorName).schemaSetName(schemaSetName).dataspaceName(dataspaceName).build()\r
101             mockYangTextSchemaSourceSetCache.get(dataspaceName, schemaSetName) >>\r
102                     YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap)\r
103             mockModuleStoreService.getYangSchemaResources(dataspaceName, schemaSetName) >> schemaContext\r
104         when: 'saveData method is invoked'\r
105             cpsDataServiceImpl.saveData(dataspaceName, anchorName, jsonData, noTimestamp)\r
106         then: 'Parameters are validated and processing is delegated to persistence service'\r
107             1 * mockDataStoreService.storeDataNodes('someDataspace', 'someAnchor', _) >>\r
108                     { args -> dataNodeStored = args[2]}\r
109             def child = dataNodeStored[0].childDataNodes[0]\r
110             assert child.childDataNodes.size() == 1\r
111         and: 'list of Tracking Area for a Coverage Area are stored with correct xpath and child nodes '\r
112             def listOfTAForCoverageArea = child.childDataNodes[0]\r
113             listOfTAForCoverageArea.xpath == '/ran-coverage-area/pLMNIdList[@mcc=\'310\' and @mnc=\'410\']/' +\r
114                     'coverage-area[@coverageArea=\'Washington\']'\r
115             listOfTAForCoverageArea.childDataNodes[0].leaves.get('nRTAC') == 234\r
116         and: 'list of cells in a tracking area are stored with correct xpath and child nodes '\r
117             def listOfCellsInTrackingArea = listOfTAForCoverageArea.childDataNodes[0]\r
118             listOfCellsInTrackingArea.xpath == '/ran-coverage-area/pLMNIdList[@mcc=\'310\' and @mnc=\'410\']/' +\r
119                     'coverage-area[@coverageArea=\'Washington\']/coverageAreaTAList[@nRTAC=\'234\']'\r
120             listOfCellsInTrackingArea.childDataNodes[0].leaves.get('cellLocalId') == 15709\r
121     }\r
122 \r
123     def 'E2E Coverage Area-Tracking Area & TA-Cell mapping data can be parsed for RAN inventory.'() {\r
124         def dataNodeStored\r
125         given: 'valid yang resource as name-to-content map'\r
126             def yangResourcesNameToContentMap = TestUtils.getYangResourcesAsMap(\r
127                     'e2e/basic/cps-ran-inventory@2021-01-28.yang')\r
128             def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap).getSchemaContext()\r
129         and : 'a valid json is provided for the model'\r
130             def jsonData = TestUtils.getResourceFileContent('e2e/basic/cps-ran-inventory-data.json')\r
131         and : 'all the further dependencies are mocked '\r
132             mockCpsAnchorService.getAnchor('someDataspace', 'someAnchor') >>\r
133                     new Anchor().builder().name('someAnchor').schemaSetName('someSchemaSet').dataspaceName(dataspaceName).build()\r
134             mockYangTextSchemaSourceSetCache.get('someDataspace', 'someSchemaSet') >> YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap)\r
135             mockModuleStoreService.getYangSchemaResources('someDataspace', 'someSchemaSet') >> schemaContext\r
136         when: 'saveData method is invoked'\r
137             cpsDataServiceImpl.saveData('someDataspace', 'someAnchor', jsonData, noTimestamp)\r
138         then: 'parameters are validated and processing is delegated to persistence service'\r
139             1 * mockDataStoreService.storeDataNodes('someDataspace', 'someAnchor', _) >>\r
140                     { args -> dataNodeStored = args[2]}\r
141         and: 'the size of the tree is correct'\r
142             def cpsRanInventory = TestUtils.getFlattenMapByXpath(dataNodeStored[0])\r
143             assert  cpsRanInventory.size() == 4\r
144         and: 'ran-inventory contains the correct child node'\r
145             def ranInventory = cpsRanInventory.get('/ran-inventory')\r
146             def ranSlices = cpsRanInventory.get('/ran-inventory/ran-slices[@rannfnssiid=\'14559ead-f4fe-4c1c-a94c-8015fad3ea35\']')\r
147             def sliceProfilesList = cpsRanInventory.get('/ran-inventory/ran-slices[@rannfnssiid=\'14559ead-f4fe-4c1c-a94c-8015fad3ea35\']/sliceProfilesList[@sliceProfileId=\'f33a9dd8-ae51-4acf-8073-c9390c25f6f1\']')\r
148             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
149             ranInventory.getChildDataNodes().size() == 1\r
150             ranInventory.getChildDataNodes().find( {it.xpath == ranSlices.xpath})\r
151         and: 'ranSlices contains the correct child node'\r
152             ranSlices.getChildDataNodes().size() == 1\r
153             ranSlices.getChildDataNodes().find( {it.xpath == sliceProfilesList.xpath})\r
154         and: 'sliceProfilesList contains the correct child node'\r
155             sliceProfilesList.getChildDataNodes().size() == 1\r
156             sliceProfilesList.getChildDataNodes().find( {it.xpath == pLMNIdList.xpath})\r
157         and: 'pLMNIdList contains no children'\r
158             pLMNIdList.getChildDataNodes().size() == 0\r
159 \r
160     }\r
161 \r
162     def 'E2E RAN Schema Model.'(){\r
163         given: 'yang resources'\r
164             def yangResourcesNameToContentMap = TestUtils.getYangResourcesAsMap(\r
165                     'ietf/ietf-inet-types@2013-07-15.yang',\r
166                     'ietf/ietf-yang-types@2013-07-15.yang',\r
167                     'e2e/basic/cps-ran-schema-model@2021-05-19.yang'\r
168             )\r
169         and : 'json data'\r
170             def jsonData = TestUtils.getResourceFileContent('e2e/basic/cps-ran-schema-model-data-v4.json')\r
171         expect: 'schema context is built with no exception indicating the schema set being valid '\r
172             def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap).getSchemaContext()\r
173         and: 'data is parsed with no exception indicating the model match'\r
174             new YangParserHelper().parseData(ContentType.JSON, jsonData, schemaContext, '') != null\r
175     }\r
176 }\r