BUG-8123: simplify file name support
[yangtools.git] / yang / yang-data-jaxen / src / test / java / org / opendaylight / yangtools / yang / data / jaxen / YangXPathFunctionsTest.java
1 /*
2  * Copyright (c) 2017 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.yangtools.yang.data.jaxen;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertFalse;
13 import static org.junit.Assert.assertNotNull;
14 import static org.junit.Assert.assertSame;
15 import static org.junit.Assert.assertTrue;
16 import static org.mockito.Mockito.mock;
17
18 import com.google.common.collect.BiMap;
19 import com.google.common.collect.HashBiMap;
20 import com.google.common.collect.ImmutableList;
21 import com.google.common.collect.ImmutableMap;
22 import com.google.common.collect.ImmutableSet;
23 import com.google.common.collect.Maps;
24 import java.net.URI;
25 import java.util.Map;
26 import java.util.Set;
27 import org.jaxen.Context;
28 import org.jaxen.Function;
29 import org.junit.BeforeClass;
30 import org.junit.Test;
31 import org.opendaylight.yangtools.yang.common.QName;
32 import org.opendaylight.yangtools.yang.common.QNameModule;
33 import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
34 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
35 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
36 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
37 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
38 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
39 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
40 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
41 import org.opendaylight.yangtools.yang.data.api.schema.xpath.XPathDocument;
42 import org.opendaylight.yangtools.yang.data.api.schema.xpath.XPathSchemaContext;
43 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
44 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
45 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
46
47 public class YangXPathFunctionsTest {
48
49     private static JaxenSchemaContextFactory jaxenSchemaContextFactory;
50
51     @BeforeClass
52     public static void setup() {
53         jaxenSchemaContextFactory = new JaxenSchemaContextFactory();
54     }
55
56     @Test
57     public void testRematchFunction() throws Exception {
58         // re-match() uses regex processing from yang-parser-impl which has been thoroughly tested within
59         // the Bug5410Test unit test class, so here is just a basic test
60         final YangFunctionContext yangFunctionContext = YangFunctionContext.getInstance();
61         final Function rematchFunction = yangFunctionContext.getFunction(null, null, "re-match");
62
63         final Context mockedContext = mock(Context.class);
64
65         boolean rematchResult = (boolean) rematchFunction.call(mockedContext, ImmutableList.of("abbc", "[abc]{1,4}"));
66         assertTrue(rematchResult);
67         rematchResult = (boolean) rematchFunction.call(mockedContext, ImmutableList.of("abbcc", "[abc]{1,4}"));
68         assertFalse(rematchResult);
69     }
70
71     @Test
72     public void testDerefFunctionForInstanceIdentifier() throws Exception {
73         final QNameModule fooModule = QNameModule.create(URI.create("foo-ns"),
74                 SimpleDateFormatUtil.getRevisionFormat().parse("2017-04-03"));
75         final QName myContainer = QName.create(fooModule, "my-container");
76         final QName myList = QName.create(fooModule, "my-list");
77         final QName keyLeafA = QName.create(fooModule, "key-leaf-a");
78         final QName keyLeafB = QName.create(fooModule, "key-leaf-b");
79         final QName iidLeaf = QName.create(fooModule, "iid-leaf");
80         final QName referencedLeaf = QName.create(fooModule, "referenced-leaf");
81
82         final Map<QName, Object> keyValues = ImmutableMap.of(keyLeafA, "key-value-a", keyLeafB, "key-value-b");
83         final YangInstanceIdentifier iidPath = YangInstanceIdentifier.of(myContainer).node(myList)
84                 .node(new NodeIdentifierWithPredicates(myList, keyValues)).node(referencedLeaf);
85
86         final LeafNode<?> iidLeafNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(iidLeaf))
87                 .withValue(iidPath).build();
88         final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(referencedLeaf))
89                 .withValue("referenced-leaf-node-value").build();
90
91         final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(myList))
92                 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
93                         new NodeIdentifierWithPredicates(myList, keyValues))
94                         .withChild(iidLeafNode)
95                         .withChild(referencedLeafNode).build())
96                 .build();
97
98         final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
99                 new NodeIdentifier(myContainer)).withChild(myListNode).build();
100
101         final SchemaContext schemaContext = YangParserTestUtils.parseYangSource(
102                 "/yang-xpath-functions-test/deref-function-iid/foo.yang");
103         assertNotNull(schemaContext);
104
105         final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
106         final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(myContainerNode);
107
108         final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
109         converterBiMap.put("foo-prefix", fooModule);
110
111         final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
112                 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
113
114         final YangInstanceIdentifier path = YangInstanceIdentifier.of(myList)
115                 .node(new NodeIdentifierWithPredicates(myList, keyValues)).node(iidLeaf);
116         final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(path);
117
118         final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
119                 .getFunction(null, null, "deref");
120         final Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
121         assertNotNull(derefResult);
122         assertTrue(derefResult instanceof NormalizedNode<?, ?>);
123         assertSame(referencedLeafNode, derefResult);
124     }
125
126     @Test
127     public void testDerefFunctionForLeafref() throws Exception {
128         final QNameModule fooModule = QNameModule.create(URI.create("foo-ns"),
129                 SimpleDateFormatUtil.getRevisionFormat().parse("2017-04-03"));
130         final QName myContainer = QName.create(fooModule, "my-container");
131         final QName myInnerContainer = QName.create(fooModule, "my-inner-container");
132         final QName myList = QName.create(fooModule, "my-list");
133         final QName keyLeafA = QName.create(fooModule, "key-leaf-a");
134         final QName keyLeafB = QName.create(fooModule, "key-leaf-b");
135         final QName absLeafrefLeaf = QName.create(fooModule, "abs-leafref-leaf");
136         final QName relLeafrefLeaf = QName.create(fooModule, "rel-leafref-leaf");
137         final QName ordinaryLeafA = QName.create(fooModule, "ordinary-leaf-a");
138         final QName ordinaryLeafB = QName.create(fooModule, "ordinary-leaf-b");
139         final QName referencedLeaf = QName.create(fooModule, "referenced-leaf");
140
141         final Map<QName, Object> keyValues = ImmutableMap.of(keyLeafA, "value-a", keyLeafB, "value-b");
142
143         final LeafNode<?> absLeafrefNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(absLeafrefLeaf))
144                 .withValue("referenced-leaf-node-value").build();
145         final LeafNode<?> relLeafrefNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(relLeafrefLeaf))
146                 .withValue("referenced-leaf-node-value").build();
147         final LeafNode<?> ordinaryLeafANode = Builders.leafBuilder().withNodeIdentifier(
148                 new NodeIdentifier(ordinaryLeafA)).withValue("value-a").build();
149         final LeafNode<?> ordinaryLeafBNode = Builders.leafBuilder().withNodeIdentifier(
150                 new NodeIdentifier(ordinaryLeafB)).withValue("value-b").build();
151
152         final LeafNode<?> referencedLeafNode = Builders.leafBuilder().withNodeIdentifier(
153                 new NodeIdentifier(referencedLeaf)).withValue("referenced-leaf-node-value").build();
154
155         final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(myList))
156                 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
157                         new NodeIdentifierWithPredicates(myList, keyValues))
158                         .withChild(referencedLeafNode).build())
159                 .build();
160
161         final ContainerNode myInnerContainerNode = Builders.containerBuilder().withNodeIdentifier(
162                 new NodeIdentifier(myInnerContainer))
163                 .withChild(absLeafrefNode)
164                 .withChild(relLeafrefNode)
165                 .withChild(ordinaryLeafANode)
166                 .withChild(ordinaryLeafBNode).build();
167
168         final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
169                 new NodeIdentifier(myContainer))
170                 .withChild(myListNode)
171                 .withChild(myInnerContainerNode).build();
172
173         final SchemaContext schemaContext = YangParserTestUtils.parseYangSource(
174                 "/yang-xpath-functions-test/deref-function-leafref/foo.yang");
175         assertNotNull(schemaContext);
176
177         final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
178         final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(myContainerNode);
179
180         final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
181         converterBiMap.put("foo-prefix", fooModule);
182
183         final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
184                 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
185
186         final YangInstanceIdentifier absLeafrefPath = YangInstanceIdentifier.of(myInnerContainer).node(absLeafrefLeaf);
187         NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(absLeafrefPath);
188
189         final Function derefFunction = normalizedNodeContextSupport.getFunctionContext()
190                 .getFunction(null, null, "deref");
191         Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
192         assertNotNull(derefResult);
193         assertTrue(derefResult instanceof NormalizedNode<?, ?>);
194         assertSame(referencedLeafNode, derefResult);
195
196         final YangInstanceIdentifier relLeafrefPath = YangInstanceIdentifier.of(myInnerContainer).node(relLeafrefLeaf);
197         normalizedNodeContext = normalizedNodeContextSupport.createContext(relLeafrefPath);
198
199         derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
200         assertNotNull(derefResult);
201         assertTrue(derefResult instanceof NormalizedNode<?, ?>);
202         assertSame(referencedLeafNode, derefResult);
203     }
204
205     @Test
206     public void testDerivedFromFunction() throws Exception {
207         // also includes test for derived-from-or-self function
208         final QNameModule barModule = QNameModule.create(URI.create("bar-ns"),
209                 SimpleDateFormatUtil.getRevisionFormat().parse("2017-04-03"));
210         final QName myContainer = QName.create(barModule, "my-container");
211         final QName myList = QName.create(barModule, "my-list");
212         final QName keyLeaf = QName.create(barModule, "key-leaf");
213         final QName idrefLeaf = QName.create(barModule, "idref-leaf");
214         final QName idC2Identity = QName.create(barModule, "id-c2");
215
216         final LeafNode<?> idrefLeafNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(idrefLeaf))
217                 .withValue(idC2Identity).build();
218
219         final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(myList))
220                 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
221                         new NodeIdentifierWithPredicates(myList, keyLeaf, "key-value"))
222                         .withChild(idrefLeafNode).build()).build();
223
224         final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
225                 new NodeIdentifier(myContainer)).withChild(myListNode).build();
226
227         final SchemaContext schemaContext = YangParserTestUtils.parseYangSources(
228                 "/yang-xpath-functions-test/derived-from-function");
229         assertNotNull(schemaContext);
230
231         final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
232         final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(myContainerNode);
233
234         final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
235         converterBiMap.put("bar-prefix", barModule);
236
237         final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
238                 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
239
240         final ImmutableMap.Builder<QName, Object> builder = ImmutableMap.builder();
241         final ImmutableMap<QName, Object> keys = builder.put(keyLeaf, "key-value").build();
242
243         final YangInstanceIdentifier path = YangInstanceIdentifier.of(myList)
244                 .node(new NodeIdentifierWithPredicates(myList, keys)).node(idrefLeaf);
245         final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(path);
246
247         final Function derivedFromFunction = normalizedNodeContextSupport.getFunctionContext()
248                 .getFunction(null, null, "derived-from");
249
250         assertTrue(getDerivedFromResult(derivedFromFunction, normalizedNodeContext, "foo-prefix:id-a3"));
251         assertTrue(getDerivedFromResult(derivedFromFunction, normalizedNodeContext, "foo-prefix:id-a4"));
252         assertTrue(getDerivedFromResult(derivedFromFunction, normalizedNodeContext, "foo-prefix:id-b2"));
253         assertTrue(getDerivedFromResult(derivedFromFunction, normalizedNodeContext, "bar-prefix:id-b3"));
254         assertTrue(getDerivedFromResult(derivedFromFunction, normalizedNodeContext, "id-b4"));
255
256         assertFalse(getDerivedFromResult(derivedFromFunction, normalizedNodeContext, "foo-prefix:id-a1"));
257         assertFalse(getDerivedFromResult(derivedFromFunction, normalizedNodeContext, "foo-prefix:id-a2"));
258         assertFalse(getDerivedFromResult(derivedFromFunction, normalizedNodeContext, "foo-prefix:id-b1"));
259         assertFalse(getDerivedFromResult(derivedFromFunction, normalizedNodeContext, "foo-prefix:id-c1"));
260         assertFalse(getDerivedFromResult(derivedFromFunction, normalizedNodeContext, "bar-prefix:id-c2"));
261
262         final Function derivedFromOrSelfFunction = normalizedNodeContextSupport.getFunctionContext()
263                 .getFunction(null, null, "derived-from-or-self");
264         assertTrue(getDerivedFromResult(derivedFromOrSelfFunction, normalizedNodeContext, "bar-prefix:id-c2"));
265     }
266
267
268
269     @Test
270     public void testEnumValueFunction() throws Exception {
271         final QNameModule fooModule = QNameModule.create(URI.create("foo-ns"),
272                 SimpleDateFormatUtil.getRevisionFormat().parse("2017-04-03"));
273         final QName myContainer = QName.create(fooModule, "my-container");
274         final QName alarm = QName.create(fooModule, "alarm");
275         final QName severity = QName.create(fooModule, "severity");
276         final QName ordinaryLeaf = QName.create(fooModule, "ordinary-leaf");
277
278         final LeafNode<?> ordinaryLeafNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(ordinaryLeaf))
279                 .withValue("test-value").build();
280
281         final MapNode alarmListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(alarm))
282                 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
283                         new NodeIdentifierWithPredicates(alarm, severity, "major"))
284                         .withChild(ordinaryLeafNode).build()).build();
285
286         final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
287                 new NodeIdentifier(myContainer)).withChild(alarmListNode).build();
288
289         final SchemaContext schemaContext = YangParserTestUtils.parseYangSource(
290                 "/yang-xpath-functions-test/enum-value-function/foo.yang");
291         assertNotNull(schemaContext);
292
293         final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
294         final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(myContainerNode);
295
296         final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
297         converterBiMap.put("foo-prefix", fooModule);
298
299         final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
300                 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
301
302         final ImmutableMap.Builder<QName, Object> builder = ImmutableMap.builder();
303         final ImmutableMap<QName, Object> keys = builder.put(severity, "major").build();
304
305         final YangInstanceIdentifier path = YangInstanceIdentifier.of(alarm)
306                 .node(new NodeIdentifierWithPredicates(alarm, keys)).node(severity);
307         final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(path);
308
309         final Function enumValueFunction = normalizedNodeContextSupport.getFunctionContext()
310                 .getFunction(null, null, "enum-value");
311         final int enumValueResult = (int) enumValueFunction.call(normalizedNodeContext, ImmutableList.of());
312         assertEquals(5, enumValueResult);
313     }
314
315     @Test
316     public void testBitIsSetFunction() throws Exception {
317         final QNameModule fooModule = QNameModule.create(URI.create("foo-ns"),
318                 SimpleDateFormatUtil.getRevisionFormat().parse("2017-04-03"));
319         final QName myContainer = QName.create(fooModule, "my-container");
320         final QName myList = QName.create(fooModule, "my-list");
321         final QName flags = QName.create(fooModule, "flags");
322         final QName ordinaryLeaf = QName.create(fooModule, "ordinary-leaf");
323
324         final LeafNode<?> ordinaryLeafNode = Builders.leafBuilder().withNodeIdentifier(new NodeIdentifier(ordinaryLeaf))
325                 .withValue("test-value").build();
326
327         final Set<String> setOfBits = ImmutableSet.of("UP", "PROMISCUOUS");
328
329         final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(myList))
330                 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
331                         new NodeIdentifierWithPredicates(myList, flags, setOfBits))
332                         .withChild(ordinaryLeafNode).build()).build();
333
334         final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
335                 new NodeIdentifier(myContainer)).withChild(myListNode).build();
336
337         final SchemaContext schemaContext = YangParserTestUtils.parseYangSource(
338                 "/yang-xpath-functions-test/bit-is-set-function/foo.yang");
339         assertNotNull(schemaContext);
340
341         final XPathSchemaContext jaxenSchemaContext = jaxenSchemaContextFactory.createContext(schemaContext);
342         final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(myContainerNode);
343
344         final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
345         converterBiMap.put("foo-prefix", fooModule);
346
347         final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
348                 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
349
350         final ImmutableMap.Builder<QName, Object> builder = ImmutableMap.builder();
351         final ImmutableMap<QName, Object> keys = builder.put(flags, setOfBits).build();
352
353         final YangInstanceIdentifier path = YangInstanceIdentifier.of(myList)
354                 .node(new NodeIdentifierWithPredicates(myList, keys)).node(flags);
355         final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(path);
356
357         final Function bitIsSetFunction = normalizedNodeContextSupport.getFunctionContext()
358                 .getFunction(null, null, "bit-is-set");
359         boolean bitIsSetResult = (boolean) bitIsSetFunction.call(normalizedNodeContext, ImmutableList.of("UP"));
360         assertTrue(bitIsSetResult);
361         bitIsSetResult = (boolean) bitIsSetFunction.call(normalizedNodeContext, ImmutableList.of("PROMISCUOUS"));
362         assertTrue(bitIsSetResult);
363         bitIsSetResult = (boolean) bitIsSetFunction.call(normalizedNodeContext, ImmutableList.of("DISABLED"));
364         assertFalse(bitIsSetResult);
365     }
366
367     private static boolean getDerivedFromResult(final Function derivedFromFunction, final NormalizedNodeContext nnCtx,
368             final String identityArg) throws Exception {
369         return (boolean) derivedFromFunction.call(nnCtx, ImmutableList.of(identityArg));
370     }
371 }