Merge branch 'master' of ../controller
[yangtools.git] / yang / yang-data-jaxen / src / test / java / org / opendaylight / yangtools / yang / data / jaxen / BitIsSetXPathFunctionTest.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 package org.opendaylight.yangtools.yang.data.jaxen;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertTrue;
14 import static org.junit.Assert.fail;
15 import static org.mockito.Mockito.mock;
16
17 import com.google.common.collect.BiMap;
18 import com.google.common.collect.HashBiMap;
19 import com.google.common.collect.ImmutableList;
20 import com.google.common.collect.ImmutableMap;
21 import com.google.common.collect.ImmutableSet;
22 import com.google.common.collect.Maps;
23 import java.net.URI;
24 import java.util.Set;
25 import org.jaxen.Context;
26 import org.jaxen.Function;
27 import org.jaxen.FunctionCallException;
28 import org.junit.Test;
29 import org.opendaylight.yangtools.yang.common.QName;
30 import org.opendaylight.yangtools.yang.common.QNameModule;
31 import org.opendaylight.yangtools.yang.common.Revision;
32 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
33 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
34 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
35 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
36 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
37 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
38 import org.opendaylight.yangtools.yang.data.api.schema.xpath.XPathDocument;
39 import org.opendaylight.yangtools.yang.data.api.schema.xpath.XPathSchemaContext;
40 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
41 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
42 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
43
44 public class BitIsSetXPathFunctionTest {
45
46     private static final JaxenSchemaContextFactory SCHEMA_CONTEXT_FACTORY = new JaxenSchemaContextFactory();
47     private static final QNameModule FOO_MODULE = QNameModule.create(URI.create("foo-ns"), Revision.of("2017-04-03"));
48     private static final QName MY_CONTAINER = QName.create(FOO_MODULE, "my-container");
49     private static final QName MY_LIST = QName.create(FOO_MODULE, "my-list");
50     private static final QName FLAGS = QName.create(FOO_MODULE, "flags");
51     private static final QName ORDINARY_LEAF = QName.create(FOO_MODULE, "ordinary-leaf");
52
53     @Test
54     public void testBitIsSetFunction() throws Exception {
55         final Set<String> setOfBits = ImmutableSet.of("UP", "PROMISCUOUS");
56
57         final SchemaContext schemaContext = YangParserTestUtils.parseYangResources(BitIsSetXPathFunctionTest.class,
58                 "/yang-xpath-functions-test/bit-is-set-function/foo.yang");
59         assertNotNull(schemaContext);
60
61         final XPathSchemaContext jaxenSchemaContext = SCHEMA_CONTEXT_FACTORY.createContext(schemaContext);
62         final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNode(setOfBits));
63
64         final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
65         converterBiMap.put("foo-prefix", FOO_MODULE);
66
67         final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
68                 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
69
70         final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(
71                 buildPathToFlagsLeafNode(setOfBits));
72
73         final Function bitIsSetFunction = normalizedNodeContextSupport.getFunctionContext()
74                 .getFunction(null, null, "bit-is-set");
75         boolean bitIsSetResult = (boolean) bitIsSetFunction.call(normalizedNodeContext, ImmutableList.of("UP"));
76         assertTrue(bitIsSetResult);
77         bitIsSetResult = (boolean) bitIsSetFunction.call(normalizedNodeContext, ImmutableList.of("PROMISCUOUS"));
78         assertTrue(bitIsSetResult);
79         bitIsSetResult = (boolean) bitIsSetFunction.call(normalizedNodeContext, ImmutableList.of("DISABLED"));
80         assertFalse(bitIsSetResult);
81     }
82
83     @Test
84     public void testInvalidTypeOfCorrespondingSchemaNode() throws Exception {
85         final Set<String> setOfBits = ImmutableSet.of("UP", "PROMISCUOUS");
86
87         final SchemaContext schemaContext = YangParserTestUtils.parseYangResources(BitIsSetXPathFunctionTest.class,
88                 "/yang-xpath-functions-test/bit-is-set-function/foo-invalid.yang");
89         assertNotNull(schemaContext);
90
91         final XPathSchemaContext jaxenSchemaContext = SCHEMA_CONTEXT_FACTORY.createContext(schemaContext);
92         final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNode(setOfBits));
93
94         final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
95         converterBiMap.put("foo-prefix", FOO_MODULE);
96
97         final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
98                 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
99
100         final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(
101                 buildPathToFlagsLeafNode(setOfBits));
102
103         final Function bitIsSetFunction = normalizedNodeContextSupport.getFunctionContext()
104                 .getFunction(null, null, "bit-is-set");
105         boolean bitIsSetResult = (boolean) bitIsSetFunction.call(normalizedNodeContext, ImmutableList.of("UP"));
106         assertFalse(bitIsSetResult);
107     }
108
109     @Test
110     public void testInvalidNormalizedNodeValueType() throws Exception {
111         final String invalidNodeValueType = "value of invalid type";
112
113         final SchemaContext schemaContext = YangParserTestUtils.parseYangResources(BitIsSetXPathFunctionTest.class,
114                 "/yang-xpath-functions-test/bit-is-set-function/foo.yang");
115         assertNotNull(schemaContext);
116
117         final XPathSchemaContext jaxenSchemaContext = SCHEMA_CONTEXT_FACTORY.createContext(schemaContext);
118         final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNode(
119                     invalidNodeValueType));
120
121         final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
122         converterBiMap.put("foo-prefix", FOO_MODULE);
123
124         final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
125                 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
126
127         final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(
128                 buildPathToFlagsLeafNode(invalidNodeValueType));
129
130         final Function bitIsSetFunction = normalizedNodeContextSupport.getFunctionContext()
131                 .getFunction(null, null, "bit-is-set");
132         boolean bitIsSetResult = (boolean) bitIsSetFunction.call(normalizedNodeContext, ImmutableList.of("UP"));
133         assertFalse(bitIsSetResult);
134     }
135
136     @Test
137     public void shouldFailOnUnknownBitArgument() throws Exception {
138         final Set<String> setOfBits = ImmutableSet.of("UP", "PROMISCUOUS");
139
140         final SchemaContext schemaContext = YangParserTestUtils.parseYangResources(BitIsSetXPathFunctionTest.class,
141                 "/yang-xpath-functions-test/bit-is-set-function/foo.yang");
142         assertNotNull(schemaContext);
143
144         final XPathSchemaContext jaxenSchemaContext = SCHEMA_CONTEXT_FACTORY.createContext(schemaContext);
145         final XPathDocument jaxenDocument = jaxenSchemaContext.createDocument(buildMyContainerNode(setOfBits));
146
147         final BiMap<String, QNameModule> converterBiMap = HashBiMap.create();
148         converterBiMap.put("foo-prefix", FOO_MODULE);
149
150         final NormalizedNodeContextSupport normalizedNodeContextSupport = NormalizedNodeContextSupport.create(
151                 (JaxenDocument) jaxenDocument, Maps.asConverter(converterBiMap));
152
153         final NormalizedNodeContext normalizedNodeContext = normalizedNodeContextSupport.createContext(
154                 buildPathToFlagsLeafNode(setOfBits));
155
156         final Function bitIsSetFunction = normalizedNodeContextSupport.getFunctionContext()
157                 .getFunction(null, null, "bit-is-set");
158         try {
159             bitIsSetFunction.call(normalizedNodeContext, ImmutableList.of("UNKNOWN"));
160             fail("Function call should have failed on unknown bit-name argument");
161         } catch (final IllegalStateException ex) {
162             assertTrue(ex.getMessage().startsWith("Bit UNKNOWN does not belong to bits"));
163         }
164     }
165
166     @Test
167     public void shouldFailOnInvalidNumberOfArguments() throws Exception {
168         final YangFunctionContext yangFunctionContext = YangFunctionContext.getInstance();
169         final Function bitIsSetFunction = yangFunctionContext.getFunction(null, null, "bit-is-set");
170
171         final Context mockedContext = mock(Context.class);
172
173         try {
174             bitIsSetFunction.call(mockedContext, ImmutableList.of("bit-a", "bit-b"));
175             fail("Function call should have failed on invalid number of arguments.");
176         } catch (final FunctionCallException ex) {
177             assertEquals("bit-is-set() takes two arguments: node-set nodes, string bit-name", ex.getMessage());
178         }
179     }
180
181     @Test
182     public void shouldFailOnInvalidTypeOfArgument() throws Exception {
183         final YangFunctionContext yangFunctionContext = YangFunctionContext.getInstance();
184         final Function bitIsSetFunction = yangFunctionContext.getFunction(null, null, "bit-is-set");
185
186         final Context mockedContext = mock(Context.class);
187
188         try {
189             bitIsSetFunction.call(mockedContext, ImmutableList.of(100));
190             fail("Function call should have failed on invalid type of the bit-name argument.");
191         } catch (final FunctionCallException ex) {
192             assertEquals("Argument bit-name of bit-is-set() function should be a String", ex.getMessage());
193         }
194     }
195
196     private static ContainerNode buildMyContainerNode(final Object keyLeafValue) {
197         final LeafNode<?> ordinaryLeafNode = Builders.leafBuilder()
198                 .withNodeIdentifier(new NodeIdentifier(ORDINARY_LEAF)).withValue("test-value").build();
199
200         final MapNode myListNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(MY_LIST))
201                 .withChild(Builders.mapEntryBuilder().withNodeIdentifier(
202                         NodeIdentifierWithPredicates.of(MY_LIST, FLAGS, keyLeafValue))
203                         .withChild(ordinaryLeafNode).build()).build();
204
205         final ContainerNode myContainerNode = Builders.containerBuilder().withNodeIdentifier(
206                 new NodeIdentifier(MY_CONTAINER)).withChild(myListNode).build();
207
208         return myContainerNode;
209     }
210
211     private static YangInstanceIdentifier buildPathToFlagsLeafNode(final Object keyLeafValue) {
212         final ImmutableMap.Builder<QName, Object> builder = ImmutableMap.builder();
213         final ImmutableMap<QName, Object> keys = builder.put(FLAGS, keyLeafValue).build();
214
215         final YangInstanceIdentifier path = YangInstanceIdentifier.of(MY_LIST)
216                 .node(NodeIdentifierWithPredicates.of(MY_LIST, keys)).node(FLAGS);
217         return path;
218     }
219 }