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