Merge "Removed `which` dependency, now using proper shell builtin."
[controller.git] / opendaylight / md-sal / sal-rest-connector / src / test / java / org / opendaylight / controller / sal / restconf / impl / json / to / cnsn / test / JsonToCnSnTest.java
1 /*
2  * Copyright (c) 2014 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.controller.sal.restconf.impl.json.to.cnsn.test;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertNull;
13 import static org.junit.Assert.assertTrue;
14
15 import java.io.ByteArrayInputStream;
16 import java.io.InputStream;
17 import java.util.HashSet;
18 import java.util.List;
19 import java.util.Set;
20
21 import org.junit.Ignore;
22 import org.junit.Test;
23 import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
24 import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
25 import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
26 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
27 import org.opendaylight.yangtools.yang.common.QName;
28 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
29 import org.opendaylight.yangtools.yang.data.api.Node;
30 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
31 import org.opendaylight.yangtools.yang.model.api.Module;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 public class JsonToCnSnTest {
36
37     private static final Logger LOG = LoggerFactory.getLogger(JsonToCnSnTest.class);
38
39     @Test
40     public void simpleListTest() {
41         simpleTest("/json-to-cnsn/simple-list.json", "/json-to-cnsn/simple-list-yang/1", "lst", "simple:list:yang1",
42                 "simple-list-yang1");
43     }
44
45     @Test
46     public void simpleContainerTest() {
47         simpleTest("/json-to-cnsn/simple-container.json", "/json-to-cnsn/simple-container-yang", "cont",
48                 "simple:container:yang", "simple-container-yang");
49     }
50
51     /**
52      * test if for every leaf list item is simple node instance created
53      */
54     @Test
55     public void multipleItemsInLeafList() {
56         CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-leaflist-items.json", true,
57                 JsonToCompositeNodeProvider.INSTANCE);
58         assertNotNull(compositeNode);
59         assertEquals(3, compositeNode.getValue().size());
60
61         boolean lflst1_1 = false;
62         boolean lflst1_2 = false;
63         boolean lflst1_3 = false;
64
65         for (Node<?> node : compositeNode.getValue()) {
66             assertEquals("lflst1", node.getNodeType().getLocalName());
67             assertTrue(node instanceof SimpleNode<?>);
68             SimpleNode<?> simpleNode = (SimpleNode<?>) node;
69             if (simpleNode.getValue().equals("45")) {
70                 lflst1_1 = true;
71             } else if (simpleNode.getValue().equals("55")) {
72                 lflst1_2 = true;
73             } else if (simpleNode.getValue().equals("66")) {
74                 lflst1_3 = true;
75             }
76         }
77
78         assertTrue(lflst1_1);
79         assertTrue(lflst1_2);
80         assertTrue(lflst1_3);
81
82     }
83
84     /**
85      * List contains 4 items and in every item are other elements. It is
86      * supposed that there should be: lf11, lflst11, cont11, lst11
87      */
88     @Test
89     public void multipleItemsInListTest() {
90         CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-items-in-list.json", true,
91                 JsonToCompositeNodeProvider.INSTANCE);
92
93         assertNotNull(compositeNode);
94         assertEquals("lst", compositeNode.getNodeType().getLocalName());
95
96         verityMultipleItemsInList(compositeNode);
97     }
98
99     @Test
100     public void nullArrayToSimpleNodeWithNullValueTest() {
101         CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/array-with-null.json", true,
102                 JsonToCompositeNodeProvider.INSTANCE);
103         assertNotNull(compositeNode);
104         assertEquals("cont", compositeNode.getNodeType().getLocalName());
105
106         assertNotNull(compositeNode.getValue());
107         assertEquals(1, compositeNode.getValue().size());
108         Node<?> lfNode = compositeNode.getValue().iterator().next();
109
110         assertTrue(lfNode instanceof SimpleNode<?>);
111         assertEquals(null, ((SimpleNode<?>) lfNode).getValue());
112
113     }
114
115     @Test
116     public void incorrectTopLevelElementsTest() {
117         RestconfDocumentedException cause1 = null;
118         try {
119             TestUtils.readInputToCnSn("/json-to-cnsn/wrong-top-level1.json", true, JsonToCompositeNodeProvider.INSTANCE);
120         } catch (RestconfDocumentedException e) {
121             cause1 = e;
122         }
123
124         assertNotNull(cause1);
125         assertTrue(cause1.getErrors().get( 0 ).getErrorMessage().contains(
126             "First element in Json Object has to be \"Object\" or \"Array with one Object element\". Other scenarios are not supported yet."));
127
128         RestconfDocumentedException cause2 = null;
129         try {
130             TestUtils
131                     .readInputToCnSn("/json-to-cnsn/wrong-top-level2.json", true, JsonToCompositeNodeProvider.INSTANCE);
132         } catch (RestconfDocumentedException e) {
133             cause2 = e;
134         }
135         assertNotNull(cause2);
136         assertTrue(cause2.getErrors().get( 0 ).getErrorMessage().contains(
137                                                      "Json Object should contain one element"));
138
139         RestconfDocumentedException cause3 = null;
140         try {
141             TestUtils
142
143                     .readInputToCnSn("/json-to-cnsn/wrong-top-level3.json", true, JsonToCompositeNodeProvider.INSTANCE);
144         } catch (RestconfDocumentedException e) {
145             cause3 = e;
146         }
147         assertNotNull(cause3);
148         assertTrue(cause3.getErrors().get( 0 ).getErrorMessage().contains(
149             "First element in Json Object has to be \"Object\" or \"Array with one Object element\". Other scenarios are not supported yet."));
150
151     }
152
153     /**
154      * if leaf list with no data is in json then no corresponding data is
155      * created in composite node. if leaf with no data then exception is raised
156      */
157     @Test
158     public void emptyDataReadTest() {
159         CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/empty-data.json", true,
160                 JsonToCompositeNodeProvider.INSTANCE);
161
162         assertNotNull(compositeNode);
163
164         assertEquals("cont", compositeNode.getNodeType().getLocalName());
165         assertTrue(compositeNode instanceof CompositeNode);
166         List<Node<?>> children = compositeNode.getValue();
167         assertEquals(1, children.size());
168         assertEquals("lflst2", children.get(0).getNodeType().getLocalName());
169         assertEquals("45", children.get(0).getValue());
170
171         String reason = null;
172         try {
173             TestUtils.readInputToCnSn("/json-to-cnsn/empty-data1.json", true, JsonToCompositeNodeProvider.INSTANCE);
174         } catch (RestconfDocumentedException e) {
175             reason = e.getErrors().get( 0 ).getErrorMessage();
176         }
177
178         assertTrue(reason.contains("Expected value at line"));
179
180     }
181
182     @Test
183     public void testJsonBlankInput() throws Exception{
184         InputStream inputStream = new ByteArrayInputStream( "".getBytes() );
185         CompositeNode compositeNode =
186                 JsonToCompositeNodeProvider.INSTANCE.readFrom(null, null, null, null, null, inputStream);
187         assertNull( compositeNode );
188     }
189
190     /**
191      * Tests whether namespace <b>stay unchanged</b> if concrete values are
192      * present in composite or simple node and if the method for update is
193      * called.
194      *
195      */
196     @Test
197     public void notSupplyNamespaceIfAlreadySupplied() {
198
199         CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/simple-list.json", false,
200                 JsonToCompositeNodeProvider.INSTANCE);
201         assertNotNull(compositeNode);
202
203         // supplement namespaces according to first data schema -
204         // "simple:data:types1"
205         Set<Module> modules1 = new HashSet<>();
206         Set<Module> modules2 = new HashSet<>();
207         modules1 = TestUtils.loadModulesFrom("/json-to-cnsn/simple-list-yang/1");
208         modules2 = TestUtils.loadModulesFrom("/json-to-cnsn/simple-list-yang/2");
209         assertNotNull(modules1);
210         assertNotNull(modules2);
211
212         TestUtils.normalizeCompositeNode(compositeNode, modules1, "simple-list-yang1:lst");
213
214         assertTrue(compositeNode instanceof CompositeNodeWrapper);
215         CompositeNode compNode = ((CompositeNodeWrapper) compositeNode).unwrap();
216
217         assertEquals("lst", compNode.getNodeType().getLocalName());
218         verifyCompositeNode(compNode, "simple:list:yang1");
219
220         TestUtils.normalizeCompositeNode(compositeNode, modules2, "simple-list-yang2:lst");
221         verifyCompositeNode(compNode, "simple:list:yang1");
222     }
223
224     @Test
225     public void jsonIdentityrefToCompositeNode() {
226         CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/identityref/json/data.json", false,
227                 JsonToCompositeNodeProvider.INSTANCE);
228         assertNotNull(compositeNode);
229
230         Set<Module> modules = TestUtils.loadModulesFrom("/json-to-cnsn/identityref");
231         assertEquals(2, modules.size());
232
233         TestUtils.normalizeCompositeNode(compositeNode, modules, "identityref-module:cont");
234
235         assertEquals("cont", compositeNode.getNodeType().getLocalName());
236
237         List<Node<?>> childs = compositeNode.getValue();
238         assertEquals(1, childs.size());
239         Node<?> nd = childs.iterator().next();
240         assertTrue(nd instanceof CompositeNode);
241         assertEquals("cont1", nd.getNodeType().getLocalName());
242
243         childs = ((CompositeNode) nd).getValue();
244         assertEquals(4, childs.size());
245         SimpleNode<?> lf11 = null;
246         SimpleNode<?> lf12 = null;
247         SimpleNode<?> lf13 = null;
248         SimpleNode<?> lf14 = null;
249         for (Node<?> child : childs) {
250             assertTrue(child instanceof SimpleNode);
251             if (child.getNodeType().getLocalName().equals("lf11")) {
252                 lf11 = (SimpleNode<?>) child;
253             } else if (child.getNodeType().getLocalName().equals("lf12")) {
254                 lf12 = (SimpleNode<?>) child;
255             } else if (child.getNodeType().getLocalName().equals("lf13")) {
256                 lf13 = (SimpleNode<?>) child;
257             } else if (child.getNodeType().getLocalName().equals("lf14")) {
258                 lf14 = (SimpleNode<?>) child;
259             }
260         }
261
262         assertTrue(lf11.getValue() instanceof QName);
263         assertEquals("iden", ((QName) lf11.getValue()).getLocalName());
264         assertEquals("identity:module", ((QName) lf11.getValue()).getNamespace().toString());
265
266         assertTrue(lf12.getValue() instanceof QName);
267         assertEquals("iden_local", ((QName) lf12.getValue()).getLocalName());
268         assertEquals("identityref:module", ((QName) lf12.getValue()).getNamespace().toString());
269
270         assertTrue(lf13.getValue() instanceof QName);
271         assertEquals("iden_local", ((QName) lf13.getValue()).getLocalName());
272         assertEquals("identityref:module", ((QName) lf13.getValue()).getNamespace().toString());
273
274         assertTrue(lf14.getValue() instanceof QName);
275         assertEquals("iden_local", ((QName) lf14.getValue()).getLocalName());
276         assertEquals("identity:module", ((QName) lf14.getValue()).getNamespace().toString());
277     }
278
279     @Ignore
280     @Test
281     public void loadDataAugmentedSchemaMoreEqualNamesTest() {
282         loadAndNormalizeData("/common/augment/json/dataa.json", "/common/augment/yang", "cont", "main");
283         loadAndNormalizeData("/common/augment/json/datab.json", "/common/augment/yang", "cont", "main");
284
285     }
286
287     private void simpleTest(final String jsonPath, final String yangPath, final String topLevelElementName, final String namespace,
288             final String moduleName) {
289         CompositeNode compNode = loadAndNormalizeData(jsonPath, yangPath, topLevelElementName, moduleName);
290         verifyCompositeNode(compNode, namespace);
291     }
292
293     private CompositeNode loadAndNormalizeData(final String jsonPath, final String yangPath, final String topLevelElementName, final String moduleName) {
294         CompositeNode compositeNode = TestUtils.readInputToCnSn(jsonPath, false, JsonToCompositeNodeProvider.INSTANCE);
295         assertNotNull(compositeNode);
296
297         Set<Module> modules = null;
298         modules = TestUtils.loadModulesFrom(yangPath);
299         assertNotNull(modules);
300
301         TestUtils.normalizeCompositeNode(compositeNode, modules, moduleName + ":" + topLevelElementName);
302
303         assertTrue(compositeNode instanceof CompositeNodeWrapper);
304         CompositeNode compNode = ((CompositeNodeWrapper) compositeNode).unwrap();
305
306         assertEquals(topLevelElementName, compNode.getNodeType().getLocalName());
307         return compNode;
308     }
309
310     private void verityMultipleItemsInList(final CompositeNode compositeNode) {
311         List<Node<?>> childrenNodes = compositeNode.getValue();
312         assertEquals(4, childrenNodes.size());
313         boolean lf11Found = false;
314         boolean cont11Found = false;
315         boolean lst11Found = false;
316         for (Node<?> lst1Item : childrenNodes) {
317             assertEquals("lst1", lst1Item.getNodeType().getLocalName());
318             assertTrue(lst1Item instanceof CompositeNode);
319
320             List<Node<?>> childrenLst1 = ((CompositeNode) lst1Item).getValue();
321             assertEquals(1, childrenLst1.size());
322             String localName = childrenLst1.get(0).getNodeType().getLocalName();
323             if (localName.equals("lf11")) {
324                 assertTrue(childrenLst1.get(0) instanceof SimpleNode);
325                 lf11Found = true;
326             } else if (localName.equals("lflst11")) {
327                 assertTrue(childrenLst1.get(0) instanceof SimpleNode);
328                 assertEquals("45", ((SimpleNode<?>) childrenLst1.get(0)).getValue());
329                 lf11Found = true;
330             } else if (localName.equals("cont11")) {
331                 assertTrue(childrenLst1.get(0) instanceof CompositeNode);
332                 cont11Found = true;
333             } else if (localName.equals("lst11")) {
334                 lst11Found = true;
335                 assertTrue(childrenLst1.get(0) instanceof CompositeNode);
336                 assertEquals(0, ((CompositeNode) childrenLst1.get(0)).getValue().size());
337             }
338
339         }
340         assertTrue(lf11Found);
341         assertTrue(cont11Found);
342         assertTrue(lst11Found);
343     }
344
345     private void verifyCompositeNode(final CompositeNode compositeNode, final String namespace) {
346         boolean cont1Found = false;
347         boolean lst1Found = false;
348         boolean lflst1_1Found = false;
349         boolean lflst1_2Found = false;
350         boolean lf1Found = false;
351
352         // assertEquals(namespace,
353         // compositeNode.getNodeType().getNamespace().toString());
354
355         for (Node<?> node : compositeNode.getValue()) {
356             if (node.getNodeType().getLocalName().equals("cont1")) {
357                 if (node instanceof CompositeNode) {
358                     cont1Found = true;
359                     assertEquals(0, ((CompositeNode) node).getValue().size());
360                 }
361             } else if (node.getNodeType().getLocalName().equals("lst1")) {
362                 if (node instanceof CompositeNode) {
363                     lst1Found = true;
364                     assertEquals(0, ((CompositeNode) node).getValue().size());
365                 }
366             } else if (node.getNodeType().getLocalName().equals("lflst1")) {
367                 if (node instanceof SimpleNode) {
368                     if (((SimpleNode<?>) node).getValue().equals("lflst1_1")) {
369                         lflst1_1Found = true;
370                     } else if (((SimpleNode<?>) node).getValue().equals("lflst1_2")) {
371                         lflst1_2Found = true;
372                     }
373                 }
374
375             } else if (node.getNodeType().getLocalName().equals("lf1")) {
376                 if (node instanceof SimpleNode) {
377                     if (((SimpleNode<?>) node).getValue().equals("lf1")) {
378                         lf1Found = true;
379                     }
380                 }
381             }
382             assertEquals(namespace, node.getNodeType().getNamespace().toString());
383         }
384         assertTrue(cont1Found);
385         assertTrue(lst1Found);
386         assertTrue(lflst1_1Found);
387         assertTrue(lflst1_2Found);
388         assertTrue(lf1Found);
389     }
390
391     @Test
392     public void unsupportedDataFormatTest() {
393         String exceptionMessage = "";
394         try {
395             TestUtils.readInputToCnSn("/json-to-cnsn/unsupported-json-format.json", true,
396                     JsonToCompositeNodeProvider.INSTANCE);
397         } catch (RestconfDocumentedException e) {
398             exceptionMessage = e.getErrors().get( 0 ).getErrorMessage();
399         }
400         assertTrue(exceptionMessage.contains("Root element of Json has to be Object"));
401     }
402
403 }