Update NodeIdentifierWithPredicates construction
[netconf.git] / restconf / restconf-nb-rfc8040 / src / test / java / org / opendaylight / restconf / nb / rfc8040 / utils / parser / YangInstanceIdentifierDeserializerTest.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 import static org.junit.Assert.fail;
13
14 import com.google.common.collect.Iterables;
15 import com.google.common.collect.Sets;
16 import java.io.FileNotFoundException;
17 import java.util.Iterator;
18 import java.util.LinkedHashMap;
19 import java.util.Map;
20 import java.util.Map.Entry;
21 import org.junit.Before;
22 import org.junit.Rule;
23 import org.junit.Test;
24 import org.junit.rules.ExpectedException;
25 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
26 import org.opendaylight.restconf.common.errors.RestconfError;
27 import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils;
28 import org.opendaylight.yangtools.yang.common.QName;
29 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
30 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
31 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
32 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
33 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
34 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
35 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
36 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
37
38 /**
39  * Unit tests for {@link YangInstanceIdentifierDeserializer}.
40  */
41 public class YangInstanceIdentifierDeserializerTest {
42
43     @Rule
44     public ExpectedException thrown = ExpectedException.none();
45
46     // schema context
47     private SchemaContext schemaContext;
48
49     @Before
50     public void init() throws FileNotFoundException {
51         this.schemaContext =
52                 YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/restconf/parser/deserializer"));
53     }
54
55     /**
56      * Test of deserialization <code>String</code> URI with container to
57      * {@code Iterable<YangInstanceIdentifier.PathArgument>}.
58      */
59     @Test
60     public void deserializeContainerTest() {
61         final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer
62                 .create(this.schemaContext, "deserializer-test:contA");
63
64         assertEquals("Result does not contains expected number of path arguments", 1, Iterables.size(result));
65         assertEquals("Not expected path argument",
66                 NodeIdentifier.create(QName.create("deserializer:test", "2016-06-06", "contA")),
67                 result.iterator().next());
68     }
69
70     /**
71      * Test of deserialization <code>String</code> URI with container containing leaf to
72      * {@code Iterable<YangInstanceIdentifier.PathArgument>}.
73      */
74     @Test
75     public void deserializeContainerWithLeafTest() {
76         final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer
77                 .create(this.schemaContext, "deserializer-test:contA/leaf-A");
78
79         assertEquals("Result does not contains expected number of path arguments", 2, Iterables.size(result));
80
81         final Iterator<PathArgument> iterator = result.iterator();
82         assertEquals("Not expected path argument",
83                 NodeIdentifier.create(QName.create("deserializer:test", "2016-06-06", "contA")),
84                 iterator.next());
85         assertEquals("Not expected path argument",
86                 NodeIdentifier.create(QName.create("deserializer:test", "2016-06-06", "leaf-A")),
87                 iterator.next());
88     }
89
90     /**
91      * Test of deserialization <code>String</code> URI with container containing list with leaf list to
92      * {@code Iterable<YangInstanceIdentifier.PathArgument>}.
93      */
94     @Test
95     public void deserializeContainerWithListWithLeafListTest() {
96         final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer
97                 .create(this.schemaContext, "deserializer-test:contA/list-A=100/leaf-list-AA=instance");
98
99         assertEquals("Result does not contains expected number of path arguments", 5, Iterables.size(result));
100
101         final Iterator<PathArgument> iterator = result.iterator();
102
103         // container
104         assertEquals("Not expected path argument",
105                 NodeIdentifier.create(QName.create("deserializer:test", "2016-06-06", "contA")),
106                 iterator.next());
107
108         // list
109         final QName list = QName.create("deserializer:test", "2016-06-06", "list-A");
110         assertEquals("Not expected path argument", NodeIdentifier.create(list), iterator.next());
111         assertEquals("Not expected path argument", NodeIdentifierWithPredicates.of(
112             list, QName.create(list, "list-key"), 100).toString(), iterator.next().toString());
113
114         // leaf list
115         final QName leafList = QName.create("deserializer:test", "2016-06-06", "leaf-list-AA");
116         assertEquals("Not expected path argument", NodeIdentifier.create(leafList), iterator.next());
117         assertEquals("Not expected path argument", new NodeWithValue<>(leafList, "instance"), iterator.next());
118     }
119
120     /**
121      * Test of deserialization <code>String</code> URI with container containing list with Action to
122      * {@code Iterable<YangInstanceIdentifier.PathArgument>}.
123      */
124     @Test
125     public void deserializeContainerWithListWithActionTest() {
126         final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer.create(this.schemaContext,
127             "example-actions:interfaces/interface=eth0/reset");
128         assertEquals("Result does not contains expected number of path arguments", 4, Iterables.size(result));
129
130         final Iterator<PathArgument> iterator = result.iterator();
131
132         // container
133         assertEquals("Not expected path argument",
134             NodeIdentifier.create(QName.create("https://example.com/ns/example-actions", "2016-07-07", "interfaces")),
135             iterator.next());
136
137         // list
138         final QName list = QName.create("https://example.com/ns/example-actions", "2016-07-07", "interface");
139         assertEquals("Not expected path argument", NodeIdentifier.create(list), iterator.next());
140         assertEquals("Not expected path argument",
141             NodeIdentifierWithPredicates.of(list, QName.create(list, "name"), "eth0"), iterator.next());
142
143         // action QName
144         final QName action = QName.create("https://example.com/ns/example-actions", "2016-07-07", "reset");
145         assertEquals("Not expected path argument", NodeIdentifier.create(action),
146             iterator.next());
147     }
148
149     /**
150      * Test of deserialization <code>String</code> URI containing list with no keys to
151      * {@code Iterable<YangInstanceIdentifier.PathArgument>}.
152      */
153     @Test
154     public void deserializeListWithNoKeysTest() {
155         final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer.create(this.schemaContext,
156             "deserializer-test:list-no-key");
157
158         assertEquals("Result does not contains expected number of path arguments", 2, Iterables.size(result));
159
160         final Iterator<PathArgument> iterator = result.iterator();
161         final QName list = QName.create("deserializer:test", "2016-06-06", "list-no-key");
162
163         assertEquals("Not expected path argument", NodeIdentifier.create(list), iterator.next());
164         assertEquals("Not expected path argument", NodeIdentifier.create(list), iterator.next());
165     }
166
167     /**
168      * Test of deserialization <code>String</code> URI containing list with one key to
169      * {@code Iterable<YangInstanceIdentifier.PathArgument>}.
170      */
171     @Test
172     public void deserializeListWithOneKeyTest() {
173         final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer.create(this.schemaContext,
174             "deserializer-test:list-one-key=value");
175
176         assertEquals("Result does not contains expected number of path arguments", 2, Iterables.size(result));
177
178         final Iterator<PathArgument> iterator = result.iterator();
179         final QName list = QName.create("deserializer:test", "2016-06-06", "list-one-key");
180
181         assertEquals("Not expected path argument", NodeIdentifier.create(list), iterator.next());
182         assertEquals("Not expected path argument",
183             NodeIdentifierWithPredicates.of(list, QName.create(list, "name"), "value"), iterator.next());
184     }
185
186     /**
187      * Test of deserialization <code>String</code> URI containing list with multiple keys to
188      * {@code Iterable<YangInstanceIdentifier.PathArgument>}.
189      */
190     @Test
191     public void deserializeListWithMultipleKeysTest() {
192         final QName list = QName.create("deserializer:test", "2016-06-06", "list-multiple-keys");
193         final Map<QName, Object> values = new LinkedHashMap<>();
194         values.put(QName.create(list, "name"), "value");
195         values.put(QName.create(list, "number"), 100);
196         values.put(QName.create(list, "enabled"), false);
197
198         final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer.create(this.schemaContext,
199             "deserializer-test:list-multiple-keys=value,100,false");
200
201         assertEquals("Result does not contains expected number of path arguments", 2, Iterables.size(result));
202
203         final Iterator<PathArgument> iterator = result.iterator();
204
205         assertEquals("Not expected path argument", NodeIdentifier.create(list), iterator.next());
206         assertEquals("Not expected path argument", NodeIdentifierWithPredicates.of(list, values).toString(),
207                 iterator.next().toString());
208     }
209
210     /**
211      * Test of deserialization <code>String</code> URI containing leaf list to
212      * {@code Iterable<YangInstanceIdentifier.PathArgument>}.
213      */
214     @Test
215     public void deserializeLeafListTest() {
216         final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer.create(this.schemaContext,
217             "deserializer-test:leaf-list-0=true");
218
219         assertEquals("Result does not contains expected number of path arguments", 2, Iterables.size(result));
220
221         final Iterator<PathArgument> iterator = result.iterator();
222         final QName leafList = QName.create("deserializer:test", "2016-06-06", "leaf-list-0");
223
224         assertEquals("Not expected path argument", new NodeIdentifier(leafList), iterator.next());
225         assertEquals("Not expected path argument",
226                 new NodeWithValue<>(leafList, true).toString(), iterator.next().toString());
227     }
228
229     /**
230      * Test when empty <code>String</code> is supplied as an input. Test is expected to return empty result.
231      */
232     @Test
233     public void deserializeEmptyDataTest() {
234         final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer.create(this.schemaContext, "");
235         assertTrue("Empty result expected", Iterables.isEmpty(result));
236     }
237
238     /**
239      * Test of deserialization <code>String</code> URI with identifiers separated by multiple slashes to
240      * {@code Iterable<YangInstanceIdentifier.PathArgument>}.
241      */
242     @Test
243     public void deserializeMultipleSlashesTest() {
244         final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer
245                 .create(this.schemaContext, "deserializer-test:contA////list-A=40//list-key");
246
247         assertEquals("Result does not contains expected number of path arguments", 4, Iterables.size(result));
248
249         final Iterator<PathArgument> iterator = result.iterator();
250
251         // container
252         assertEquals("Not expected path argument",
253                 NodeIdentifier.create(QName.create("deserializer:test", "2016-06-06", "contA")),
254                 iterator.next());
255
256         // list
257         final QName list = QName.create("deserializer:test", "2016-06-06", "list-A");
258         assertEquals("Not expected path argument", NodeIdentifier.create(list), iterator.next());
259         assertEquals("Not expected path argument",
260                 NodeIdentifierWithPredicates.of(list, QName.create(list, "list-key"), 40).toString(),
261                 iterator.next().toString());
262
263         // leaf
264         assertEquals("Not expected path argument",
265                 new NodeIdentifier(QName.create("deserializer:test", "2016-06-06", "list-key")), iterator.next());
266     }
267
268     /**
269      * Negative test when supplied <code>SchemaContext</code> is null. Test is expected to fail with
270      * <code>NullPointerException</code>.
271      */
272     @Test
273     public void deserializeNullSchemaContextNegativeTest() {
274         this.thrown.expect(NullPointerException.class);
275         YangInstanceIdentifierDeserializer.create(null, "deserializer-test:contA");
276     }
277
278     /**
279      * Negative test when supplied <code>String</code> data to deserialize is null. Test is expected to fail with
280      * <code>NullPointerException</code>.
281      */
282     @Test
283     public void nullDataNegativeNegativeTest() {
284         this.thrown.expect(NullPointerException.class);
285         YangInstanceIdentifierDeserializer.create(this.schemaContext, null);
286     }
287
288     /**
289      * Negative test when identifier is not followed by slash or equals. Test is expected to fail with
290      * <code>RestconfDocumentedException</code>.
291      */
292     @Test
293     public void deserializeBadCharMissingSlashOrEqualNegativeTest() {
294         this.thrown.expect(RestconfDocumentedException.class);
295         YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:cont*leaf-A");
296     }
297
298     /**
299      * Negative test of validating identifier when there is a slash after container without next identifier. Test
300      * is expected to fail with <code>RestconfDocumentedException</code>.
301      */
302     @Test
303     public void validArgIdentifierContainerEndsWithSlashNegativeTest() {
304         this.thrown.expect(RestconfDocumentedException.class);
305         YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:contA/");
306     }
307
308     /**
309      * Negative test of validating identifier when there are multiple slashes after container without next identifier.
310      * Test is expected to fail with <code>RestconfDocumentedException</code>.
311      */
312     @Test
313     public void validArgIdentifierContainerEndsWithMultipleSlashesNegativeTest() {
314         this.thrown.expect(RestconfDocumentedException.class);
315         YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:contA///");
316     }
317
318     /**
319      * Negative test of validating identifier when there is a slash after list key values without next identifier. Test
320      * is expected to fail with <code>RestconfDocumentedException</code>.
321      */
322     @Test
323     public void validArgIdentifierListEndsWithSlashLNegativeTest() {
324         this.thrown.expect(RestconfDocumentedException.class);
325         YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:list-one-key=value/");
326     }
327
328     /**
329      * Negative test of validating identifier when there are multiple slashes after list key values without next
330      * identifier. Test is expected to fail with <code>RestconfDocumentedException</code>.
331      */
332     @Test
333     public void validArgIdentifierListEndsWithSlashesNegativeTest() {
334         this.thrown.expect(RestconfDocumentedException.class);
335         YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:list-one-key=value//");
336     }
337
338     /**
339      * Negative test of creating <code>QName</code> when identifier is empty (example: '/'). Test is expected to fail
340      * with <code>RestconfDocumentedException</code>.
341      */
342     @Test
343     public void prepareQnameEmptyIdentifierNegativeTest() {
344         this.thrown.expect(RestconfDocumentedException.class);
345         YangInstanceIdentifierDeserializer.create(this.schemaContext, "/");
346     }
347
348     /**
349      * Negative test of creating <code>QName</code> when in identifier there is another sign than colon or equals.
350      * Test is expected to fail with <code>RestconfDocumentedException</code>.
351      */
352     @Test
353     public void prepareQnameBuildPathNegativeTest() {
354         this.thrown.expect(RestconfDocumentedException.class);
355         YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test*contA");
356     }
357
358     /**
359      * Negative test of creating <code>QName</code> when it is not possible to find module for specified prefix. Test is
360      * expected to fail with <code>RestconfDocumentedException</code>.
361      */
362     @Test
363     public void prepareQnameNotExistingPrefixNegativeTest() {
364         this.thrown.expect(RestconfDocumentedException.class);
365         YangInstanceIdentifierDeserializer.create(this.schemaContext, "not-existing:contA");
366     }
367
368     /**
369      * Negative test of creating <code>QName</code> when after prefix and colon there is not parsable identifier as
370      * local name. Test is expected to fail with <code>RestconfDocumentedException</code>.
371      */
372     @Test
373     public void prepareQnameNotValidPrefixAndLocalNameNegativeTest() {
374         this.thrown.expect(RestconfDocumentedException.class);
375         YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:*not-parsable-identifier");
376     }
377
378     /**
379      * Negative test of creating <code>QName</code> when data ends after prefix and colon. Test is expected to fail
380      * with <code>StringIndexOutOfBoundsException</code>.
381      */
382     @Test
383     public void prepareQnameErrorParsingNegativeTest() {
384         this.thrown.expect(StringIndexOutOfBoundsException.class);
385         YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:");
386     }
387
388     /**
389      * Negative test of creating <code>QName</code> when after identifier and colon there is node name of unknown
390      * node in current container. Test is expected to fail with <code>RestconfDocumentedException</code> and error
391      * type, error tag and error status code are compared to expected values.
392      */
393     @Test
394     public void prepareQnameNotValidContainerNameNegativeTest() {
395         try {
396             YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:contA/leafB");
397             fail("Test should fail due to unknown child node in container");
398         } catch (final RestconfDocumentedException e) {
399             assertEquals("Not expected error type",
400                     RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
401             assertEquals("Not expected error tag",
402                     RestconfError.ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
403             assertEquals("Not expected error status code",
404                     404, e.getErrors().get(0).getErrorTag().getStatusCode());
405         }
406     }
407
408     /**
409      * Negative test of creating <code>QName</code> when after identifier and equals there is node name of unknown
410      * node in current list. Test is expected to fail with <code>RestconfDocumentedException</code> and error
411      * type, error tag and error status code are compared to expected values.
412      */
413     @Test
414     public void prepareQnameNotValidListNameNegativeTest() {
415         try {
416             YangInstanceIdentifierDeserializer
417                     .create(this.schemaContext, "deserializer-test:list-no-key/disabled=false");
418             fail("Test should fail due to unknown child node in list");
419         } catch (final RestconfDocumentedException e) {
420             assertEquals("Not expected error type",
421                     RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
422             assertEquals("Not expected error tag",
423                     RestconfError.ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
424             assertEquals("Not expected error status code",
425                     404, e.getErrors().get(0).getErrorTag().getStatusCode());
426         }
427     }
428
429     /**
430      * Negative test of getting next identifier when current node is keyed entry. Test is expected to
431      * fail with <code>RestconfDocumentedException</code>.
432      */
433     @Test
434     public void prepareIdentifierNotKeyedEntryNegativeTest() {
435         this.thrown.expect(RestconfDocumentedException.class);
436         YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:list-one-key");
437     }
438
439     /**
440      * Negative test when there is a comma also after the last key. Test is expected to fail with
441      * <code>RestconfDocumentedException</code>.
442      */
443     @Test
444     public void deserializeKeysEndsWithComaNegativeTest() {
445         this.thrown.expect(RestconfDocumentedException.class);
446         YangInstanceIdentifierDeserializer.create(this.schemaContext,
447                 "deserializer-test:list-multiple-keys=value,100,false,");
448     }
449
450     /**
451      * Positive when not all keys of list are encoded. The missing keys should be considered to has empty
452      * <code>String</code> values. Also value of next leaf must not be considered to be missing key value.
453      */
454     @Test
455     public void notAllListKeysEncodedPositiveTest() {
456         final QName list = QName.create("deserializer:test", "2016-06-06", "list-multiple-keys");
457         final Map<QName, Object> values = new LinkedHashMap<>();
458         values.put(QName.create(list, "name"), ":foo");
459         values.put(QName.create(list, "number"), "");
460         values.put(QName.create(list, "enabled"), "");
461
462         final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer.create(
463                 this.schemaContext, "deserializer-test:list-multiple-keys=%3Afoo,,/string-value");
464
465         assertEquals("Result does not contains expected number of path arguments", 3, Iterables.size(result));
466
467         final Iterator<PathArgument> iterator = result.iterator();
468
469         // list
470         assertEquals("Not expected path argument", NodeIdentifier.create(list), iterator.next());
471         assertEquals("Not expected path argument", NodeIdentifierWithPredicates.of(list, values).toString(),
472                 iterator.next().toString());
473
474         // leaf
475         assertEquals("Not expected path argument",
476                 new NodeIdentifier(QName.create("deserializer:test", "2016-06-06", "string-value")), iterator.next());
477     }
478
479     /**
480      * Negative test when not all keys of list are encoded and it is not possible to consider missing keys to be empty.
481      * Test is expected to fail with <code>RestconfDocumentedException</code> and error type, error tag and error
482      * status code are compared to expected values.
483      */
484     @Test
485     public void notAllListKeysEncodedNegativeTest() {
486         try {
487             YangInstanceIdentifierDeserializer.create(
488                     this.schemaContext, "deserializer-test:list-multiple-keys=%3Afoo/string-value");
489             fail("Test should fail due to missing list key values");
490         } catch (final RestconfDocumentedException e) {
491             assertEquals("Not expected error type",
492                     RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
493             assertEquals("Not expected error tag",
494                     RestconfError.ErrorTag.MISSING_ATTRIBUTE, e.getErrors().get(0).getErrorTag());
495             assertEquals("Not expected error status code",
496                     400, e.getErrors().get(0).getErrorTag().getStatusCode());
497         }
498     }
499
500     /**
501      * Test URI with list where key value starts with, ends with or contains percent encoded characters.The encoded
502      * value should be complete also with not percent-encoded parts.
503      */
504     @Test
505     public void percentEncodedKeyEndsWithNoPercentEncodedChars() {
506         final String URI = "deserializer-test:list-multiple-keys=%3Afoo,1,true";
507         final YangInstanceIdentifier result = YangInstanceIdentifier.create(
508                 YangInstanceIdentifierDeserializer.create(this.schemaContext, URI));
509
510         final Iterator<Entry<QName, Object>> resultListKeys =
511                 ((NodeIdentifierWithPredicates)result.getLastPathArgument()).entrySet().iterator();
512
513         assertEquals(":foo", resultListKeys.next().getValue());
514         assertEquals(new Short("1"), resultListKeys.next().getValue());
515         assertEquals(true, resultListKeys.next().getValue());
516     }
517
518     /**
519      * Positive test when all keys of list can be considered to be empty <code>String</code>.
520      */
521     @Test
522     public void deserializeAllKeysEmptyTest() {
523         final QName list = QName.create("deserializer:test", "2016-06-06", "list-multiple-keys");
524         final Map<QName, Object> values = new LinkedHashMap<>();
525         values.put(QName.create(list, "name"), "");
526         values.put(QName.create(list, "number"), "");
527         values.put(QName.create(list, "enabled"), "");
528
529         final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer
530                 .create(this.schemaContext, "deserializer-test:list-multiple-keys=,,");
531
532         assertEquals("Result does not contains expected number of path arguments", 2, Iterables.size(result));
533
534         final Iterator<PathArgument> iterator = result.iterator();
535
536         assertEquals("Not expected path argument", NodeIdentifier.create(list), iterator.next());
537         assertEquals("Not expected path argument", NodeIdentifierWithPredicates.of(list, values).toString(),
538                 iterator.next().toString());
539     }
540
541     /**
542      * Negative test of deserialization when for leaf list there is no specified instance value.
543      * <code>RestconfDocumentedException</code> is expected and error type, error tag and error status code are
544      * compared to expected values.
545      */
546     @Test
547     public void leafListMissingKeyNegativeTest() {
548         try {
549             YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:leaf-list-0=");
550             fail("Test should fail due to missing instance value");
551         } catch (final RestconfDocumentedException e) {
552             assertEquals("Not expected error type",
553                     RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
554             assertEquals("Not expected error tag",
555                     RestconfError.ErrorTag.MISSING_ATTRIBUTE, e.getErrors().get(0).getErrorTag());
556             assertEquals("Not expected error status code",
557                     400, e.getErrors().get(0).getErrorTag().getStatusCode());
558         }
559     }
560
561     /**
562      * Positive test of deserialization when parts of input URI <code>String</code> are defined in another module.
563      */
564     @Test
565     public void deserializePartInOtherModuleTest() {
566         final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer.create(this.schemaContext,
567             "deserializer-test-included:augmented-list=100/augmented-leaf");
568
569         assertEquals("Result does not contains expected number of path arguments", 4, Iterables.size(result));
570
571         final Iterator<PathArgument> iterator = result.iterator();
572         final QName list = QName.create("deserializer:test:included", "2016-06-06", "augmented-list");
573         final QName child = QName.create("deserializer:test", "2016-06-06", "augmented-leaf");
574
575         // list
576         assertEquals("Not expected path argument",
577                 NodeIdentifier.create(list),
578                 iterator.next());
579
580         assertEquals("Not expected path argument",
581                 NodeIdentifierWithPredicates.of(list, QName.create(list, "list-key"), 100).toString(),
582                 iterator.next().toString());
583
584         // augmented leaf
585         assertEquals("Not expected path argument", new AugmentationIdentifier(Sets.newHashSet(child)), iterator.next());
586         assertEquals("Not expected path argument", NodeIdentifier.create(child), iterator.next());
587     }
588 }