Migrate users of YangInstanceIdentifier.empty()
[netconf.git] / restconf / restconf-nb / src / test / java / org / opendaylight / restconf / nb / rfc8040 / utils / parser / YangInstanceIdentifierSerializerTest.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.restconf.nb.rfc8040.utils.parser;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertThrows;
12 import static org.junit.Assert.assertTrue;
13
14 import java.util.LinkedHashMap;
15 import java.util.Map;
16 import org.junit.AfterClass;
17 import org.junit.BeforeClass;
18 import org.junit.Test;
19 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
20 import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils;
21 import org.opendaylight.yangtools.yang.common.QName;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
23 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
24 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
25 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
26 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
27
28 /**
29  * Unit tests for {@link YangInstanceIdentifierSerializer}.
30  */
31 public class YangInstanceIdentifierSerializerTest {
32     // schema context with test modules
33     private static EffectiveModelContext SCHEMA_CONTEXT;
34
35     @BeforeClass
36     public static void beforeClass() throws Exception {
37         SCHEMA_CONTEXT = YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/restconf/parser/serializer"));
38     }
39
40     @AfterClass
41     public static void afterClass() {
42         SCHEMA_CONTEXT = null;
43     }
44
45     /**
46      * Positive test of serialization of <code>YangInstanceIdentifier</code> containing container node to
47      * <code>String</code>. Returned <code>String</code> is compared to have expected value.
48      */
49     @Test
50     public void serializeContainerTest() {
51         final YangInstanceIdentifier data = YangInstanceIdentifier.builder()
52                 .node(QName.create("serializer:test", "2016-06-06", "contA"))
53                 .build();
54
55         final String result = YangInstanceIdentifierSerializer.create(SCHEMA_CONTEXT, data);
56         assertEquals("Serialization not successful",
57                 "serializer-test:contA", result);
58     }
59
60     /**
61      * Positive test of serialization of <code>YangInstanceIdentifier</code> containing container with leaf node to
62      * <code>String</code>. Returned <code>String</code> is compared to have expected value.
63      */
64     @Test
65     public void serializeContainerWithLeafTest() {
66         final YangInstanceIdentifier data = YangInstanceIdentifier.builder()
67                 .node(QName.create("serializer:test", "2016-06-06", "contA"))
68                 .node(QName.create("serializer:test", "2016-06-06", "leaf-A"))
69                 .build();
70
71         final String result = YangInstanceIdentifierSerializer.create(SCHEMA_CONTEXT, data);
72         assertEquals("Serialization not successful", "serializer-test:contA/leaf-A", result);
73     }
74
75     /**
76      * Positive test of serialization of <code>YangInstanceIdentifier</code> containing container with list with leaf
77      * list node to <code>String</code>. Returned <code>String</code> is compared to have expected value.
78      */
79     @Test
80     public void serializeContainerWithListWithLeafListTest() {
81         final QName list = QName.create("serializer:test", "2016-06-06", "list-A");
82         final QName leafList = QName.create("serializer:test", "2016-06-06", "leaf-list-AA");
83
84         final YangInstanceIdentifier data = YangInstanceIdentifier.builder()
85                 .node(QName.create("serializer:test", "2016-06-06", "contA"))
86                 .node(list)
87                 .node(NodeIdentifierWithPredicates.of(list, QName.create(list, "list-key"), 100))
88                 .node(leafList)
89                 .node(new NodeWithValue<>(leafList, "instance"))
90                 .build();
91
92         final String result = YangInstanceIdentifierSerializer.create(SCHEMA_CONTEXT, data);
93         assertEquals("Serialization not successful",
94                 "serializer-test:contA/list-A=100/leaf-list-AA=instance",
95                 result);
96     }
97
98     /**
99      * Positive test of serialization of <code>YangInstanceIdentifier</code> to <code>String</code> when serialized
100      * <code>YangInstanceIdentifier</code> contains list with no keys. Returned <code>String</code> is compared to have
101      * expected value.
102      */
103     @Test
104     public void serializeListWithNoKeysTest() {
105         final YangInstanceIdentifier data = YangInstanceIdentifier.builder()
106                 .node(QName.create("serializer:test", "2016-06-06", "list-no-key"))
107                 .node(QName.create("serializer:test", "2016-06-06", "list-no-key"))
108                 .build();
109
110         final String result = YangInstanceIdentifierSerializer.create(SCHEMA_CONTEXT, data);
111         assertEquals("Serialization not successful", "serializer-test:list-no-key", result);
112     }
113
114     /**
115      * Positive test of serialization of <code>YangInstanceIdentifier</code> to <code>String</code> when serialized
116      * <code>YangInstanceIdentifier</code> contains a keyed list, but the path argument does not specify them. Returned
117      * <code>String</code> is compared to have expected value.
118      */
119     @Test
120     public void serializeMapWithNoKeysTest() {
121         final YangInstanceIdentifier data = YangInstanceIdentifier.builder()
122                 .node(QName.create("serializer:test", "2016-06-06", "list-one-key"))
123                 .nodeWithKey(QName.create("serializer:test", "2016-06-06", "list-one-key"), Map.of())
124                 .build();
125
126         final String result = YangInstanceIdentifierSerializer.create(SCHEMA_CONTEXT, data);
127         assertEquals("Serialization not successful", "serializer-test:list-one-key", result);
128     }
129
130     /**
131      * Positive test of serialization of <code>YangInstanceIdentifier</code> to <code>String</code> when serialized
132      * <code>YangInstanceIdentifier</code> contains list with one key. Returned <code>String</code> is compared to have
133      * expected value.
134      */
135     @Test
136     public void serializeMapWithOneKeyTest() {
137         final YangInstanceIdentifier data = YangInstanceIdentifier.builder()
138                 .node(QName.create("serializer:test", "2016-06-06", "list-one-key"))
139                 .nodeWithKey(QName.create("serializer:test", "2016-06-06", "list-one-key"),
140                         QName.create("serializer:test", "2016-06-06", "list-one-key"), "value")
141                 .build();
142
143         final String result = YangInstanceIdentifierSerializer.create(SCHEMA_CONTEXT, data);
144         assertEquals("Serialization not successful", "serializer-test:list-one-key=value", result);
145     }
146
147     /**
148      * Positive test of serialization of <code>YangInstanceIdentifier</code> to <code>String</code> when serialized
149      * <code>YangInstanceIdentifier</code> contains list with multiple keys. Returned <code>String</code> is compared
150      * to have expected value.
151      */
152     @Test
153     public void serializeMapWithMultipleKeysTest() {
154         final QName list = QName.create("serializer:test", "2016-06-06", "list-multiple-keys");
155         final Map<QName, Object> values = new LinkedHashMap<>();
156         values.put(QName.create(list, "name"), "value-1");
157         values.put(QName.create(list, "number"), "2");
158         values.put(QName.create(list, "enabled"), "true");
159
160         final YangInstanceIdentifier data = YangInstanceIdentifier.builder()
161                 .node(list).nodeWithKey(list, values).build();
162
163         final String result = YangInstanceIdentifierSerializer.create(SCHEMA_CONTEXT, data);
164         assertEquals("Serialization not successful", "serializer-test:list-multiple-keys=value-1,2,true", result);
165     }
166
167     /**
168      * Positive test of serialization of <code>YangInstanceIdentifier</code> to <code>String</code> when serialized
169      * <code>YangInstanceIdentifier</code> contains leaf node. Returned <code>String</code> is compared to have
170      * expected value.
171      */
172     @Test
173     public void serializeLeafTest() {
174         final YangInstanceIdentifier data = YangInstanceIdentifier.builder()
175                 .node(QName.create("serializer:test", "2016-06-06", "leaf-0"))
176                 .build();
177
178         final String result = YangInstanceIdentifierSerializer.create(SCHEMA_CONTEXT, data);
179         assertEquals("Serialization not successful", "serializer-test:leaf-0", result);
180     }
181
182     /**
183      * Positive test of serialization of <code>YangInstanceIdentifier</code> to <code>String</code> when serialized
184      * <code>YangInstanceIdentifier</code> contains leaf list node. Returned <code>String</code> is compared to have
185      * expected value.
186      */
187     @Test
188     public void serializeLeafListTest() {
189         final YangInstanceIdentifier data = YangInstanceIdentifier.builder()
190                 .node(QName.create("serializer:test", "2016-06-06", "leaf-list-0"))
191                 .node(new NodeWithValue<>(QName.create("serializer:test", "2016-06-06", "leaf-list-0"), "instance"))
192                 .build();
193
194         final String result = YangInstanceIdentifierSerializer.create(SCHEMA_CONTEXT, data);
195         assertEquals("Serialization not successful", "serializer-test:leaf-list-0=instance", result);
196     }
197
198     /**
199      * Negative test of serialization <code>YangInstanceIdentifier</code> to <code>String</code> when
200      * <code>SchemaContext</code> is <code>null</code>. Test is expected to fail with
201      * <code>NullPointerException</code>.
202      */
203     @Test
204     public void serializeNullSchemaContextNegativeTest() {
205         assertThrows(NullPointerException.class,
206             () -> YangInstanceIdentifierSerializer.create(null, YangInstanceIdentifier.of()));
207     }
208
209     /**
210      * Negative test of serialization <code>YangInstanceIdentifier</code> to <code>String</code> when supplied
211      * <code>YangInstanceIdentifier</code> is <code>null</code>. Test is expected to fail with
212      * <code>NullPointerException</code>.
213      */
214     @Test
215     public void serializeNullDataNegativeTest() {
216         assertThrows(NullPointerException.class,
217             () -> YangInstanceIdentifierSerializer.create(SCHEMA_CONTEXT, null));
218     }
219
220     /**
221      * Test of serialization <code>YangInstanceIdentifier</code> to <code>String</code> when supplied
222      * <code>YangInstanceIdentifier</code> is <code>YangInstanceIdentifier.EMPTY</code>.
223      * Empty <code>String</code> is expected as a return value.
224      */
225     @Test
226     public void serializeEmptyDataTest() {
227         final String result = YangInstanceIdentifierSerializer.create(SCHEMA_CONTEXT, YangInstanceIdentifier.of());
228         assertTrue("Empty identifier is expected", result.isEmpty());
229     }
230
231     /**
232      * Negative test when it is not possible to find child node of current node. Test is expected to fail with
233      * <code>RestconfDocumentedException</code> and error message is compared to expected error message.
234      */
235     @Test
236     public void serializeChildNodeNotFoundNegativeTest() {
237         final YangInstanceIdentifier data = YangInstanceIdentifier.builder()
238                 .node(QName.create("serializer:test", "2016-06-06", "contA"))
239                 .node(QName.create("serializer:test", "2016-06-06", "not-existing-leaf"))
240                 .build();
241
242         assertThrows(RestconfDocumentedException.class,
243             () -> YangInstanceIdentifierSerializer.create(SCHEMA_CONTEXT, data));
244     }
245
246     /**
247      * Test to verify if all reserved characters according to rfc3986 are considered by serializer implementation to
248      * be percent encoded.
249      */
250     @Test
251     public void verifyReservedCharactersTest() {
252         final char[] genDelims = { ':', '/', '?', '#', '[', ']', '@' };
253         final char[] subDelims = { '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=' };
254
255         for (final char c : genDelims) {
256             assertTrue("Current character is reserved and should be percent encoded",
257                     YangInstanceIdentifierSerializer.PERCENT_ENCODE_CHARS.matches(c));
258         }
259
260         for (final char c : subDelims) {
261             assertTrue("Current character is reserved and should be percent encoded",
262                     YangInstanceIdentifierSerializer.PERCENT_ENCODE_CHARS.matches(c));
263         }
264     }
265
266     /**
267      * Test if URIs with percent encoded characters are all correctly serialized.
268      */
269     @Test
270     public void serializePercentEncodingTest() {
271         final String value = "foo:foo bar/foo,bar/'bar'";
272         final String encoded = "foo%3Afoo%20bar%2Ffoo%2Cbar%2F%27bar%27";
273
274         final YangInstanceIdentifier data = YangInstanceIdentifier.builder()
275                 .node(QName.create("serializer:test", "2016-06-06", "list-one-key"))
276                 .nodeWithKey(QName.create("serializer:test", "2016-06-06", "list-one-key"),
277                         QName.create("serializer:test", "2016-06-06", "list-one-key"), value)
278                 .build();
279
280         final String result = YangInstanceIdentifierSerializer.create(SCHEMA_CONTEXT, data);
281         assertEquals("Serialization not successful", "serializer-test:list-one-key=" + encoded, result);
282     }
283
284     /**
285      * Test if URIs with no percent encoded characters are correctly serialized. Input should be untouched.
286      */
287     @Test
288     public void serializeNoPercentEncodingTest() {
289         final String value = "foo\"b\"bar";
290
291         final YangInstanceIdentifier data = YangInstanceIdentifier.builder()
292                 .node(QName.create("serializer:test", "2016-06-06", "list-one-key"))
293                 .nodeWithKey(QName.create("serializer:test", "2016-06-06", "list-one-key"),
294                         QName.create("serializer:test", "2016-06-06", "list-one-key"), value)
295                 .build();
296
297         final String result = YangInstanceIdentifierSerializer.create(SCHEMA_CONTEXT, data);
298         assertEquals("Serialization not successful", "serializer-test:list-one-key=" + value, result);
299     }
300
301     /**
302      * Test of serialization when nodes in input <code>YangInstanceIdentifier</code> are defined in two different
303      * modules by using augmentation.
304      */
305     @Test
306     public void serializeIncludedNodesTest() {
307         final QName list = QName.create("serializer:test:included", "2016-06-06", "augmented-list");
308         final QName child = QName.create("serializer:test", "2016-06-06", "augmented-leaf");
309
310         final YangInstanceIdentifier data = YangInstanceIdentifier.builder()
311                 .node(list)
312                 .node(NodeIdentifierWithPredicates.of(list, QName.create(list, "list-key"), 100))
313                 .node(child)
314                 .build();
315
316         final String result = YangInstanceIdentifierSerializer.create(SCHEMA_CONTEXT, data);
317
318         assertEquals("Serialization not successful",
319                 "serializer-test-included:augmented-list=100/serializer-test:augmented-leaf", result);
320     }
321
322     /**
323      * Test of serialization when nodes in input <code>YangInstanceIdentifier</code> are defined in two different
324      * modules by using augmentation. Augmented node in data supplied for serialization has wrong namespace.
325      * <code>RestconfDocumentedException</code> is expected because augmented node is defined in other module than its
326      * parent and will not be found.
327      */
328     @Test
329     public void serializeIncludedNodesSerializationTest() {
330         final QName list = QName.create("serializer:test:included", "2016-06-06", "augmented-list");
331         // child should has different namespace
332         final QName child = QName.create("serializer:test:included", "2016-06-06", "augmented-leaf");
333
334         final YangInstanceIdentifier data = YangInstanceIdentifier.builder()
335                 .node(list)
336                 .node(NodeIdentifierWithPredicates.of(list, QName.create(list, "list-key"), 100))
337                 .node(child)
338                 .build();
339
340         assertThrows(RestconfDocumentedException.class,
341             () -> YangInstanceIdentifierSerializer.create(SCHEMA_CONTEXT, data));
342     }
343 }