Remove Augmentation{Identifier,Node}
[yangtools.git] / codec / yang-data-codec-gson / src / test / java / org / opendaylight / yangtools / yang / data / codec / gson / JsonStreamToNormalizedNodeTest.java
1 /*
2  * Copyright (c) 2016 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.codec.gson;
9
10 import static org.hamcrest.CoreMatchers.containsString;
11 import static org.hamcrest.MatcherAssert.assertThat;
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertNotNull;
14 import static org.junit.Assert.assertThrows;
15 import static org.opendaylight.yangtools.yang.data.codec.gson.TestUtils.loadTextFile;
16 import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.choiceBuilder;
17 import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.containerBuilder;
18 import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.leafNode;
19
20 import com.google.gson.stream.JsonReader;
21 import java.io.IOException;
22 import java.io.StringReader;
23 import java.net.URISyntaxException;
24 import org.junit.Test;
25 import org.opendaylight.yangtools.yang.common.QName;
26 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
27 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
28 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
29 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizationResultHolder;
30 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
31
32 /**
33  * Each test tests whether json input is correctly transformed to normalized node structure.
34  */
35 public class JsonStreamToNormalizedNodeTest extends AbstractComplexJsonTest {
36     @Test
37     public void leafNodeInContainer() throws IOException, URISyntaxException {
38         final String inputJson = loadTextFile("/complexjson/leaf-node-in-container.json");
39         verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.leafNodeInContainer());
40     }
41
42     @Test
43     public void leafNodeViaAugmentationInContainer() throws IOException, URISyntaxException {
44         final String inputJson = loadTextFile("/complexjson/leaf-node-via-augmentation-in-container.json");
45         verifyTransformationToNormalizedNode(inputJson,
46                 TestingNormalizedNodeStructuresCreator.leafNodeViaAugmentationInContainer());
47     }
48
49     @Test
50     public void leafListNodeInContainer() throws IOException, URISyntaxException {
51         final String inputJson = loadTextFile("/complexjson/leaflist-node-in-container.json");
52         verifyTransformationToNormalizedNode(inputJson,
53                 TestingNormalizedNodeStructuresCreator.leafListNodeInContainer());
54     }
55
56     @Test
57     public void keyedListNodeInContainer() throws IOException, URISyntaxException {
58         final String inputJson = loadTextFile("/complexjson/keyed-list-node-in-container.json");
59         verifyTransformationToNormalizedNode(inputJson,
60                 TestingNormalizedNodeStructuresCreator.keyedListNodeInContainer());
61     }
62
63     @Test
64     public void choiceNodeInContainer() throws IOException, URISyntaxException {
65         final String inputJson = loadTextFile("/complexjson/choice-node-in-container.json");
66         verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.choiceNodeInContainer());
67     }
68
69     /**
70      * Test of translating internal augmentations to normalized nodes structure.
71      *
72      * <p>
73      * 2 nodes are added via internal augmentation A, 1 node via internal augmentation B and one node is originally
74      * member of case.
75      */
76     @Test
77     public void caseNodeAugmentationInChoiceInContainer() throws IOException, URISyntaxException {
78         final String inputJson = loadTextFile("/complexjson/case-node-augmentation-in-choice-in-container.json");
79         verifyTransformationToNormalizedNode(inputJson,
80                 TestingNormalizedNodeStructuresCreator.caseNodeAugmentationInChoiceInContainer());
81     }
82
83     /**
84      * also test using of namesakes (equal local names with different.
85      */
86     @Test
87     public void caseNodeExternalAugmentationInChoiceInContainer() throws IOException, URISyntaxException {
88         final String inputJson =
89                 loadTextFile("/complexjson/case-node-external-augmentation-in-choice-in-container.json");
90         verifyTransformationToNormalizedNode(inputJson,
91                 TestingNormalizedNodeStructuresCreator.caseNodeExternalAugmentationInChoiceInContainer());
92     }
93
94     /**
95      * augmentation of choice - adding new case.
96      */
97     @Test
98     public void choiceNodeAugmentationInContainer() throws IOException, URISyntaxException {
99         final String inputJson = loadTextFile("/complexjson/choice-node-augmentation-in-container.json");
100         verifyTransformationToNormalizedNode(inputJson,
101                 TestingNormalizedNodeStructuresCreator.choiceNodeAugmentationInContainer());
102     }
103
104     @Test
105     public void unkeyedNodeInContainer() throws IOException, URISyntaxException {
106         final String inputJson = loadTextFile("/complexjson/unkeyed-node-in-container.json");
107         verifyTransformationToNormalizedNode(inputJson,
108             TestingNormalizedNodeStructuresCreator.unkeyedNodeInContainer());
109     }
110
111     /**
112      * Top level JSON element contains no information about module name.
113      *
114      * <p>
115      * It should be possible to find out potential module name from available schema context.
116      */
117     @Test
118     public void missingModuleInfoInTopLevelElement() throws IOException, URISyntaxException {
119         final String inputJson = loadTextFile("/complexjson/missing-module-in-top-level.json");
120         verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.topLevelContainer());
121     }
122
123     /**
124      * Exception expected.
125      *
126      * <p>
127      * It tests case when several elements with the same name and various namespaces exists and are in JSON specified
128      * without module name prefix.
129      */
130     @Test
131     public void leafNamesakes() throws IOException, URISyntaxException {
132         final String inputJson = loadTextFile("/complexjson/namesakes.json");
133         final IllegalStateException ex = assertThrows(IllegalStateException.class,
134             // second parameter isn't necessary because error will be raised before it is used.
135             () -> verifyTransformationToNormalizedNode(inputJson, null));
136
137         final String errorMessage = ex.getMessage();
138         assertThat(errorMessage, containsString("Choose suitable module name for element lf11-namesake:"));
139         assertThat(errorMessage, containsString("complexjson-augmentation"));
140         assertThat(errorMessage, containsString("complexjson-augmentation-namesake"));
141     }
142
143     @Test
144     public void emptyTypeTest() throws IOException, URISyntaxException {
145         final String inputJson = loadTextFile("/complexjson/type-empty.json");
146         verifyTransformationToNormalizedNode(inputJson, CONT1_WITH_EMPTYLEAF);
147     }
148
149     /**
150      * Exception expected.
151      *
152      * <p>
153      * Json input contains element which doesn't exist in YANG schema
154      */
155     @Test
156     public void parsingNotExistingElement() throws IOException, URISyntaxException {
157         final String inputJson = loadTextFile("/complexjson/not-existing-element.json");
158         final IllegalStateException ex = assertThrows(IllegalStateException.class,
159             //second parameter isn't necessary because error will be raised before it is used.
160             () -> verifyTransformationToNormalizedNode(inputJson, null));
161
162         assertThat(ex.getMessage(), containsString("Schema node with name dummy-element was not found"));
163     }
164
165     /**
166      * Should not fail as we set the parser to be lenient.
167      *
168      * <p>
169      * Json input contains element which doesn't exist in YANG schema
170      */
171     @Test
172     public void parsingSkipNotExistingElement() throws IOException, URISyntaxException {
173         final String inputJson = loadTextFile("/complexjson/not-existing-element.json");
174         final var result = new NormalizationResultHolder();
175         final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
176         final var jsonParser = JsonParserStream.createLenient(streamWriter,
177             JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02.getShared(schemaContext));
178         jsonParser.parse(new JsonReader(new StringReader(inputJson)));
179         final var transformedInput = result.getResult().data();
180         assertNotNull(transformedInput);
181     }
182
183     @Test
184     public void listItemWithoutArray() throws IOException, URISyntaxException {
185         final String inputJson = loadTextFile("/complexjson/keyed-list-restconf-behaviour.json");
186         final var result = new NormalizationResultHolder();
187         final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
188         final var jsonParser = JsonParserStream.create(streamWriter, lhotkaCodecFactory,
189             Inference.ofDataTreePath(schemaContext, CONT_1));
190         jsonParser.parse(new JsonReader(new StringReader(inputJson)));
191         final var transformedInput = result.getResult().data();
192         assertNotNull(transformedInput);
193     }
194
195     @Test
196     public void listItemWithArray() throws IOException, URISyntaxException {
197         final String inputJson = loadTextFile("/complexjson/keyed-list-yang-json-behaviour.json");
198         final var result = new NormalizationResultHolder();
199         final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
200         final var jsonParser = JsonParserStream.create(streamWriter, lhotkaCodecFactory,
201             Inference.ofDataTreePath(schemaContext, CONT_1));
202         jsonParser.parse(new JsonReader(new StringReader(inputJson)));
203         final var transformedInput = result.getResult().data();
204         assertNotNull(transformedInput);
205     }
206
207     @Test
208     public void multipleChoiceAugmentation() throws IOException, URISyntaxException {
209         final String inputJson = loadTextFile("/complexjson/multiple-choice-augmentation-in-container.json");
210
211         final var result = new NormalizationResultHolder();
212         final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
213
214         final QName augmentChoice1QName = QName.create(CONT_1, "augment-choice1");
215         final QName augmentChoice2QName = QName.create(augmentChoice1QName, "augment-choice2");
216         final QName containerQName = QName.create(augmentChoice1QName, "case11-choice-case-container");
217         final QName leafQName = QName.create(augmentChoice1QName, "case11-choice-case-leaf");
218
219         final var cont1Normalized = containerBuilder()
220             .withNodeIdentifier(new NodeIdentifier(CONT_1))
221             .withChild(choiceBuilder()
222                 .withNodeIdentifier(new NodeIdentifier(augmentChoice1QName))
223                 .withChild(choiceBuilder()
224                     .withNodeIdentifier(new NodeIdentifier(augmentChoice2QName))
225                     .withChild(containerBuilder()
226                         .withNodeIdentifier(new NodeIdentifier(containerQName))
227                         .withChild(leafNode(leafQName, "leaf-value"))
228                         .build())
229                     .build())
230                 .build())
231             .build();
232
233         final var jsonParser = JsonParserStream.create(streamWriter, lhotkaCodecFactory);
234         jsonParser.parse(new JsonReader(new StringReader(inputJson)));
235         final var transformedInput = result.getResult().data();
236         assertNotNull(transformedInput);
237         assertEquals(cont1Normalized, transformedInput);
238     }
239
240     private static void verifyTransformationToNormalizedNode(final String inputJson,
241             final NormalizedNode awaitedStructure) {
242         final var result = new NormalizationResultHolder();
243         final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
244         final var jsonParser = JsonParserStream.create(streamWriter, lhotkaCodecFactory);
245         jsonParser.parse(new JsonReader(new StringReader(inputJson)));
246         final var transformedInput = result.getResult().data();
247         assertEquals("Transformation of json input to normalized node wasn't successful.", awaitedStructure,
248                 transformedInput);
249     }
250 }