2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2021-2023 Nordix Foundation
4 * Modifications Copyright (C) 2021 Pantheon.tech
5 * Modifications Copyright (C) 2021-2022 Bell Canada.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 * SPDX-License-Identifier: Apache-2.0
20 * ============LICENSE_END=========================================================
23 package org.onap.cps.utils
25 import com.hazelcast.map.IMap
26 import org.onap.cps.TestUtils
27 import org.onap.cps.api.CpsAdminService
28 import org.onap.cps.api.impl.YangTextSchemaSourceSetCache
29 import org.onap.cps.cache.AnchorDataCacheEntry
30 import org.onap.cps.spi.model.Anchor
31 import org.onap.cps.yang.YangTextSchemaSourceSet
32 import org.onap.cps.yang.YangTextSchemaSourceSetBuilder
33 import spock.lang.Specification
35 class PrefixResolverSpec extends Specification {
37 def mockCpsAdminService = Mock(CpsAdminService)
39 def mockYangTextSchemaSourceSetCache = Mock(YangTextSchemaSourceSetCache)
41 def mockAnchorDataCache = Mock(IMap<String, AnchorDataCacheEntry>)
43 def objectUnderTest = new PrefixResolver(mockCpsAdminService, mockYangTextSchemaSourceSetCache, mockAnchorDataCache)
45 def mockYangTextSchemaSourceSet = Mock(YangTextSchemaSourceSet)
47 def yangResourceNameToContent = TestUtils.getYangResourcesAsMap('test-tree.yang')
49 def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent).getSchemaContext()
52 given: 'an anchor for the test-tree model'
53 def anchor = new Anchor(dataspaceName: 'testDataspace', name: 'testAnchor')
54 and: 'the system can get this anchor'
55 mockCpsAdminService.getAnchor('testDataspace', 'testAnchor') >> anchor
56 and: 'the schema source cache contains the schema context for the test-tree module'
57 mockYangTextSchemaSourceSet.getSchemaContext() >> schemaContext
60 def 'get xpath prefix using node schema context'() {
61 when: 'the prefix of the yang module is retrieved'
62 def result = objectUnderTest.getPrefix('testDataspace', 'testAnchor', xpath)
63 then: 'the expected prefix is returned'
64 result == expectedPrefix
65 and: 'the cache is updated for the given anchor with a map of prefixes per top level container (just one one this case)'
66 1 * mockAnchorDataCache.put('testAnchor',_ , _ ,_) >> { args -> {
67 def prefixPerContainerName = args[1].getProperty("prefixPerContainerName")
68 assert prefixPerContainerName.size() == 1
69 assert prefixPerContainerName.get('test-tree') == 'tree'
72 and: 'schema source cache is used (i.e. need to build schema context)'
73 1 * mockYangTextSchemaSourceSetCache.get(*_) >> mockYangTextSchemaSourceSet
74 where: 'the following scenarios are applied'
75 xpath || expectedPrefix
76 '/test-tree' || 'tree'
77 '/test-tree/with/descendants' || 'tree'
78 '/test-tree[@id=1]' || 'tree'
79 '/test-tree[@id=1]/child' || 'tree'
80 '/test-tree[@id="[1]"]/child' || 'tree'
85 def 'get prefix with populated anchor data cache with #scenario cache entry'() {
86 given: 'anchor data cache is populated for the anchor with a prefix for top level container named #cachedTopLevelContainerName'
87 def anchorDataCacheEntry = new AnchorDataCacheEntry()
88 def prefixPerContainerName = [(cachedTopLevelContainerName): 'cachedPrefix']
89 anchorDataCacheEntry.setProperty('prefixPerContainerName',prefixPerContainerName)
90 mockAnchorDataCache.containsKey('testAnchor') >> true
91 mockAnchorDataCache.get('testAnchor') >> anchorDataCacheEntry
92 when: 'the prefix of the yang module is retrieved'
93 def result = objectUnderTest.getPrefix('testDataspace', 'testAnchor', '/test-tree')
94 then: 'the expected prefix is returned'
95 result == expectedPrefix
96 and: 'schema source cache is not used (i.e. no need to build schema context)'
97 0 * mockYangTextSchemaSourceSetCache.get(*_)
98 where: 'the following scenarios are applied'
99 scenario | cachedTopLevelContainerName || expectedPrefix
100 'matching' | 'test-tree' || 'cachedPrefix'
101 'non-matching' | 'other' || ''
104 def 'get prefix with other (non relevant) data in anchor data cache'() {
105 given: 'anchor data cache is populated with non relevant other property'
106 def anchorDataCacheEntry = new AnchorDataCacheEntry()
107 anchorDataCacheEntry.setProperty('something else', 'does not matter')
108 mockAnchorDataCache.containsKey('testAnchor') >> true
109 mockAnchorDataCache.get('testAnchor') >> anchorDataCacheEntry
110 when: 'the prefix of the yang module is retrieved'
111 def result = objectUnderTest.getPrefix('testDataspace', 'testAnchor', '/test-tree')
112 then: 'the expected prefix is returned'
114 and: 'schema source cache is used (i.e. need to build schema context)'
115 1 * mockYangTextSchemaSourceSetCache.get(*_) >> mockYangTextSchemaSourceSet