Migrate YangInstanceIdentifier.EMPTY users
[netconf.git] / restconf / restconf-nb-rfc8040 / src / test / java / org / opendaylight / restconf / nb / rfc8040 / utils / parser / ParserIdentifierTest.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.assertNotNull;
12 import static org.junit.Assert.assertNull;
13 import static org.junit.Assert.assertSame;
14 import static org.junit.Assert.fail;
15 import static org.mockito.Mockito.when;
16
17 import java.util.Map.Entry;
18 import java.util.Optional;
19 import org.junit.Before;
20 import org.junit.Rule;
21 import org.junit.Test;
22 import org.junit.rules.ExpectedException;
23 import org.mockito.Mock;
24 import org.mockito.MockitoAnnotations;
25 import org.opendaylight.mdsal.dom.api.DOMMountPoint;
26 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
27 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
28 import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
29 import org.opendaylight.mdsal.dom.broker.DOMMountPointServiceImpl;
30 import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
31 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
32 import org.opendaylight.restconf.common.errors.RestconfError;
33 import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag;
34 import org.opendaylight.restconf.common.errors.RestconfError.ErrorType;
35 import org.opendaylight.restconf.common.schema.SchemaExportContext;
36 import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils;
37 import org.opendaylight.restconf.nb.rfc8040.utils.RestconfConstants;
38 import org.opendaylight.yangtools.yang.common.QName;
39 import org.opendaylight.yangtools.yang.common.Revision;
40 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
41 import org.opendaylight.yangtools.yang.model.api.Module;
42 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
43 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
44
45 /**
46  * Unit tests for {@link ParserIdentifier}.
47  */
48 public class ParserIdentifierTest {
49     // mount point identifier
50     private static final String MOUNT_POINT_IDENT =
51             "mount-point:mount-container/point-number" + "/" + RestconfConstants.MOUNT;
52
53     // invalid mount point identifier
54     private static final String INVALID_MOUNT_POINT_IDENT =
55             "mount-point:point-number" + "/" + RestconfConstants.MOUNT;
56
57     // test identifier + expected result
58     private static final String TEST_IDENT =
59             "parser-identifier:cont1/cont2/listTest/list-in-grouping=name/leaf-A.B";
60
61     private static final String TEST_IDENT_RESULT =
62             "/(parser:identifier?revision=2016-06-02)cont1/cont2/listTest/listTest/list-in-grouping/"
63             + "list-in-grouping[{(parser:identifier?revision=2016-06-02)name=name}]/leaf-A.B";
64
65     // test identifier with nodes defined in other modules using augmentation + expected result
66     private static final String TEST_IDENT_OTHERS =
67             "parser-identifier-included:list-1=name,2016-06-02/parser-identifier:augment-leaf";
68
69     private static final String TEST_IDENT_OTHERS_RESULT =
70             "/(parser:identifier:included?revision=2016-06-02)list-1/list-1"
71             + "[{(parser:identifier:included?revision=2016-06-02)name=name, "
72             + "(parser:identifier:included?revision=2016-06-02)revision=2016-06-02}]"
73             + "/AugmentationIdentifier{childNames=[(parser:identifier?revision=2016-06-02)augment-leaf]}/"
74             + "(parser:identifier?revision=2016-06-02)augment-leaf";
75
76     // invalid test identifier
77     private static final String INVALID_TEST_IDENT =
78             "parser-identifier:cont2/listTest/list-in-grouping=name/leaf-A.B";
79
80     // schema context with test modules
81     private SchemaContext schemaContext;
82     // contains the same modules but it is different object (it can be compared with equals)
83     private SchemaContext schemaContextOnMountPoint;
84
85     private static final String TEST_MODULE_NAME = "test-module";
86     private static final String TEST_MODULE_REVISION = "2016-06-02";
87     private static final String TEST_MODULE_NAMESPACE = "test:module";
88
89     private static final String INVOKE_RPC = "invoke-rpc-module:rpc-test";
90     private static final String INVOKE_ACTION = "example-actions:interfaces/interface=eth0/reset";
91
92     // mount point and mount point service
93     private DOMMountPoint mountPoint;
94     private DOMMountPointService mountPointService;
95
96     // mock mount point and mount point service
97     @Mock
98     private DOMMountPoint mockMountPoint;
99     @Mock
100     private DOMMountPointService mockMountPointService;
101     @Mock
102     private DOMSchemaService domSchemaService;
103     @Mock
104     private DOMYangTextSourceProvider sourceProvider;
105
106     @Rule
107     public final ExpectedException thrown = ExpectedException.none();
108
109     @Before
110     public void setup() throws Exception {
111         MockitoAnnotations.initMocks(this);
112         this.schemaContext = YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/parser-identifier"));
113         this.schemaContextOnMountPoint =
114                 YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/parser-identifier"));
115
116         this.mountPointService = new DOMMountPointServiceImpl();
117
118         // create and register mount point
119         final YangInstanceIdentifier mountPointId = YangInstanceIdentifier.builder()
120                 .node(QName.create("mount:point", "2016-06-02", "mount-container"))
121                 .node(QName.create("mount:point", "2016-06-02", "point-number"))
122                 .build();
123
124         mountPoint = mountPointService.createMountPoint(mountPointId)
125                 .addInitialSchemaContext(this.schemaContextOnMountPoint)
126                 .register()
127                 .getInstance();
128
129         // register mount point with null schema context
130         when(this.mockMountPoint.getSchemaContext()).thenReturn(null);
131         when(this.mockMountPointService.getMountPoint(YangInstanceIdentifier.empty()))
132                 .thenReturn(Optional.of(this.mockMountPoint));
133     }
134
135     /**
136      * {@link ParserIdentifier#toInstanceIdentifier(String, SchemaContext)} tests.
137      */
138
139     /**
140      * Positive test of creating <code>InstanceIdentifierContext</code> from identifier when all nodes are defined
141      * in one module.
142      */
143     @Test
144     public void toInstanceIdentifierTest() {
145         final InstanceIdentifierContext<?> context = ParserIdentifier.toInstanceIdentifier(
146                 TEST_IDENT, this.schemaContext, Optional.empty());
147
148         assertEquals("Returned not expected identifier",
149                 TEST_IDENT_RESULT, context .getInstanceIdentifier().toString());
150     }
151
152     /**
153      * Positive test of creating <code>InstanceIdentifierContext</code> from identifier when nodes are defined in
154      * multiple modules.
155      */
156     @Test
157     public void toInstanceIdentifierOtherModulesTest() {
158         final InstanceIdentifierContext<?> context = ParserIdentifier.toInstanceIdentifier(
159                 TEST_IDENT_OTHERS, this.schemaContext, Optional.empty());
160
161         assertEquals("Returned not expected identifier",
162                 TEST_IDENT_OTHERS_RESULT, context.getInstanceIdentifier().toString());
163     }
164
165     /**
166      * Positive test of creating <code>InstanceIdentifierContext</code> from identifier containing
167      * {@link RestconfConstants#MOUNT}.
168      */
169     @Test
170     public void toInstanceIdentifierMountPointTest() {
171         final InstanceIdentifierContext<?> context = ParserIdentifier.toInstanceIdentifier(
172                 MOUNT_POINT_IDENT + "/" + TEST_IDENT, this.schemaContext, Optional.of(this.mountPointService));
173
174         assertEquals("Returned not expected identifier",
175                 TEST_IDENT_RESULT.toString(), context.getInstanceIdentifier().toString());
176
177         assertEquals("Mount point not found",
178                 this.mountPoint, context.getMountPoint());
179
180         assertEquals("Schema context from mount point expected",
181                 this.schemaContextOnMountPoint, context.getSchemaContext());
182     }
183
184     /**
185      * Test of creating <code>InstanceIdentifierContext</code> when identifier is <code>null</code>.
186      * <code>{@link YangInstanceIdentifier#EMPTY}</code> should be returned.
187      */
188     @Test
189     public void toInstanceIdentifierNullIdentifierTest() {
190         final InstanceIdentifierContext<?> context = ParserIdentifier.toInstanceIdentifier(
191                 null, this.schemaContext, Optional.empty());
192         assertEquals("Returned not expected identifier",
193                 YangInstanceIdentifier.empty(), context.getInstanceIdentifier());
194     }
195
196     /**
197      * Negative test of creating <code>InstanceIdentifierContext</code> when <code>SchemaContext</code> is
198      * <code>null</code>. Test fails expecting <code>NullPointerException</code>.
199      */
200     @Test
201     public void toInstanceIdentifierNullSchemaContextNegativeTest() {
202         this.thrown.expect(NullPointerException.class);
203         ParserIdentifier.toInstanceIdentifier(TEST_IDENT, null, Optional.empty());
204     }
205
206     /**
207      * Api path can be empty. <code>YangInstanceIdentifier.EMPTY</code> is expected to be returned.
208      */
209     @Test
210     public void toInstanceIdentifierEmptyIdentifierTest() {
211         final InstanceIdentifierContext<?> context = ParserIdentifier.toInstanceIdentifier(
212                 "", this.schemaContext, Optional.empty());
213         assertEquals("Returned not expected identifier",
214                 YangInstanceIdentifier.empty(), context.getInstanceIdentifier());
215     }
216
217     /**
218      * Negative test with invalid test identifier. Test should fail with <code>RestconfDocumentedException</code>.
219      */
220     @Test
221     public void toInstanceIdentifierInvalidIdentifierNegativeTest() {
222         this.thrown.expect(RestconfDocumentedException.class);
223         ParserIdentifier.toInstanceIdentifier(INVALID_TEST_IDENT, this.schemaContext, Optional.empty());
224     }
225
226     /**
227      * Negative test when identifier contains {@link RestconfConstants#MOUNT} but identifier part is not valid. Test
228      * should fail with <code>RestconfDocumentedException</code>.
229      */
230     @Test
231     public void toInstanceIdentifierMountPointInvalidIdentifierNegativeTest() {
232         this.thrown.expect(RestconfDocumentedException.class);
233         ParserIdentifier.toInstanceIdentifier(
234                 INVALID_MOUNT_POINT_IDENT, this.schemaContext, Optional.of(this.mountPointService));
235     }
236
237     /**
238      * Negative test when <code>DOMMountPoint</code> cannot be found. Test is expected to fail with
239      * <code>RestconfDocumentedException</code> error type, error tag and error status code are
240      * compared to expected values.
241      */
242     @Test
243     public void toInstanceIdentifierMissingMountPointNegativeTest() {
244         try {
245             ParserIdentifier.toInstanceIdentifier(
246                     "" + "/" + RestconfConstants.MOUNT, this.schemaContext, Optional.of(this.mountPointService));
247             fail("Test should fail due to missing mount point");
248         } catch (final RestconfDocumentedException e) {
249             assertEquals("Not expected error type",
250                     RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
251             assertEquals("Not expected error tag",
252                     ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
253             assertEquals("Not expected error status code",
254                     404, e.getErrors().get(0).getErrorTag().getStatusCode());
255         }
256     }
257
258     /**
259      * Negative test when <code>{@link DOMMountPointService}</code> is absent. Test is expected to fail with
260      * <code>RestconfDocumentedException</code> error type, error tag and error status code are
261      * compared to expected values.
262      */
263     @Test
264     public void toInstanceIdentifierMissingMountPointServiceNegativeTest() {
265         try {
266             ParserIdentifier.toInstanceIdentifier(RestconfConstants.MOUNT, this.schemaContext, Optional.empty());
267             fail("Test should fail due to absent mount point service");
268         } catch (final RestconfDocumentedException e) {
269             assertEquals("Not expected error type",
270                     ErrorType.APPLICATION, e.getErrors().get(0).getErrorType());
271             assertEquals("Not expected error tag",
272                     ErrorTag.OPERATION_FAILED, e.getErrors().get(0).getErrorTag());
273             assertEquals("Not expected error status code",
274                     500, e.getErrors().get(0).getErrorTag().getStatusCode());
275         }
276     }
277
278     /**
279      * {@link ParserIdentifier#makeQNameFromIdentifier(String)} tests.
280      */
281
282     /**
283      * Positive test of making <code>QName</code> from identifier and compare values from returned <code>QName</code>
284      * to expected values.
285      */
286     @Test
287     public void makeQNameFromIdentifierTest() {
288         final Entry<String, Revision> qName = ParserIdentifier.makeQNameFromIdentifier(
289             TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION);
290
291         assertNotNull("QName should be created", qName);
292         assertEquals("Returned not expected module name", TEST_MODULE_NAME, qName.getKey());
293         assertEquals("Returned not expected module revision", Revision.of(TEST_MODULE_REVISION), qName.getValue());
294     }
295
296     /**
297      * Negative test when supplied identifier is in invalid format and then revision is not parsable.
298      * <code>RestconfDocumentedException</code> is expected and error type, error tag and error status code are
299      * compared to expected values.
300      */
301     @Test
302     public void makeQNameFromIdentifierInvalidIdentifierNegativeTest() {
303         try {
304             ParserIdentifier.makeQNameFromIdentifier(TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME);
305             fail("Test should fail due to invalid identifier format");
306         } catch (final RestconfDocumentedException e) {
307             assertEquals("Not expected error type",
308                     RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
309             assertEquals("Not expected error tag",
310                     RestconfError.ErrorTag.INVALID_VALUE, e.getErrors().get(0).getErrorTag());
311             assertEquals("Not expected error status code",
312                     400, e.getErrors().get(0).getErrorTag().getStatusCode());
313         }
314     }
315
316     /**
317      * Negative test when supplied identifier is too short (contains only module name).
318      * <code>RestconfDocumentedException</code> is expected and error type, error tag and error status code are
319      * compared to expected values.
320      */
321     @Test
322     public void makeQNameFromIdentifierTooShortIdentifierNegativeTest() {
323         try {
324             ParserIdentifier.makeQNameFromIdentifier(TEST_MODULE_NAME);
325             fail("Test should fail due to too short identifier format");
326         } catch (final RestconfDocumentedException e) {
327             assertEquals("Not expected error type",
328                     RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
329             assertEquals("Not expected error tag",
330                     RestconfError.ErrorTag.INVALID_VALUE, e.getErrors().get(0).getErrorTag());
331             assertEquals("Not expected error status code",
332                     400, e.getErrors().get(0).getErrorTag().getStatusCode());
333         }
334     }
335
336     /**
337      * Positive test of making <code>QName</code> from identifier for module behind mount point. Value from returned
338      * <code>QName</code> are compared to expected values.
339      */
340     @Test
341     public void makeQNameFromIdentifierMountTest() {
342         final Entry<String, Revision> qName = ParserIdentifier.makeQNameFromIdentifier(
343                 MOUNT_POINT_IDENT
344                 + "/"
345                 + TEST_MODULE_NAME
346                 + "/"
347                 + TEST_MODULE_REVISION);
348
349         assertNotNull("QName should be created", qName);
350         assertEquals("Returned not expected module name", TEST_MODULE_NAME, qName.getKey());
351         assertEquals("Returned not expected module revision", Revision.of(TEST_MODULE_REVISION), qName.getValue());
352     }
353
354     /**
355      * Negative test when supplied identifier for module behind mount point is in invalid format and then revision is
356      * not parsable. <code>RestconfDocumentedException</code> is expected and error type, error tag and error status
357      * code are compared to expected values.
358      */
359     @Test
360     public void makeQNameFromIdentifierMountPointInvalidIdentifierNegativeTest() {
361         try {
362             ParserIdentifier.makeQNameFromIdentifier(
363                     MOUNT_POINT_IDENT
364                     + "/"
365                     + TEST_MODULE_REVISION
366                     + "/"
367                     + TEST_MODULE_NAME);
368
369             fail("Test should fail due to invalid identifier format");
370         } catch (final RestconfDocumentedException e) {
371             assertEquals("Not expected error type",
372                     RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
373             assertEquals("Not expected error tag",
374                     RestconfError.ErrorTag.INVALID_VALUE, e.getErrors().get(0).getErrorTag());
375             assertEquals("Not expected error status code",
376                     400, e.getErrors().get(0).getErrorTag().getStatusCode());
377         }
378     }
379
380     /**
381      * Negative test when supplied identifier for module behind mount point is too short (contains only module name).
382      * <code>RestconfDocumentedException</code> is expected and error type, error tag and error status code
383      * are compared to expected values.
384      */
385     @Test
386     public void makeQNameFromIdentifierMountPointTooShortIdentifierNegativeTest() {
387         try {
388             ParserIdentifier.makeQNameFromIdentifier(
389                     MOUNT_POINT_IDENT
390                     + "/"
391                     + TEST_MODULE_NAME);
392
393             fail("Test should fail due to too short identifier format");
394         } catch (final RestconfDocumentedException e) {
395             assertEquals("Not expected error type",
396                     RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
397             assertEquals("Not expected error tag",
398                     RestconfError.ErrorTag.INVALID_VALUE, e.getErrors().get(0).getErrorTag());
399             assertEquals("Not expected error status code",
400                     400, e.getErrors().get(0).getErrorTag().getStatusCode());
401         }
402     }
403
404     /**
405      * Negative test trying to make <code>QName</code> from <code>null</code> identifier. Test is expected to fail with
406      * <code>NullPointerException</code>.
407      */
408     @Test
409     public void makeQNameFromIdentifierNullIdentifierNegativeTest() {
410         this.thrown.expect(NullPointerException.class);
411         ParserIdentifier.makeQNameFromIdentifier(null);
412     }
413
414     /**
415      * Negative test trying to make <code>QName</code> from empty identifier. Test is expected to fail with
416      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code is compared to expected
417      * values.
418      */
419     @Test
420     public void makeQNameFromIdentifierEmptyIdentifierNegativeTest() {
421         try {
422             ParserIdentifier.makeQNameFromIdentifier("");
423             fail("Test should fail due to empty identifier");
424         } catch (final RestconfDocumentedException e) {
425             assertEquals("Not expected error type",
426                     RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
427             assertEquals("Not expected error tag",
428                     RestconfError.ErrorTag.INVALID_VALUE, e.getErrors().get(0).getErrorTag());
429             assertEquals("Not expected error status code",
430                     400, e.getErrors().get(0).getErrorTag().getStatusCode());
431         }
432     }
433
434     /**
435      * Negative test with identifier containing double slash. Between // there is one empty string which will be
436      * incorrectly considered to be module revision. Test is expected to fail with
437      * <code>RestconfDocumentedException</code> and error type, error tag and error status code are compared to
438      * expected values.
439      */
440     @Test
441     public void makeQNameFromIdentifierDoubleSlashNegativeTest() {
442         try {
443             ParserIdentifier.makeQNameFromIdentifier(TEST_MODULE_NAME + "//" + TEST_MODULE_REVISION);
444             fail("Test should fail due to identifier containing double slash");
445         } catch (final RestconfDocumentedException e) {
446             assertEquals("Not expected error type",
447                     RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
448             assertEquals("Not expected error tag",
449                     RestconfError.ErrorTag.INVALID_VALUE, e.getErrors().get(0).getErrorTag());
450             assertEquals("Not expected error status code",
451                     400, e.getErrors().get(0).getErrorTag().getStatusCode());
452         }
453     }
454
455     /**
456      * {@link ParserIdentifier#toSchemaExportContextFromIdentifier(SchemaContext, String, DOMMountPointService)} tests.
457      */
458
459     /**
460      * Positive test of getting <code>SchemaExportContext</code>. Expected module name, revision and namespace are
461      * verified.
462      */
463     @Test
464     public void toSchemaExportContextFromIdentifierTest() {
465         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
466                 this.schemaContext, TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null, sourceProvider);
467
468         assertNotNull("Export context should be parsed", exportContext);
469
470         final Module module = exportContext.getModule();
471         assertNotNull("Export context should contains test module", module);
472
473         assertEquals("Returned not expected module name",
474                 TEST_MODULE_NAME, module.getName());
475         assertEquals("Returned not expected module revision",
476                 Revision.ofNullable(TEST_MODULE_REVISION), module.getRevision());
477         assertEquals("Returned not expected module namespace",
478                 TEST_MODULE_NAMESPACE, module.getNamespace().toString());
479     }
480
481     /**
482      * Test of getting <code>SchemaExportContext</code> when desired module is not found.
483      * <code>SchemaExportContext</code> should be created but module should be set to <code>null</code>.
484      */
485     @Test
486     public void toSchemaExportContextFromIdentifierNotFoundTest() {
487         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
488                 this.schemaContext,
489                 "not-existing-module" + "/" + "2016-01-01",
490                 null, sourceProvider);
491
492         assertNotNull("Export context should be parsed", exportContext);
493         assertNull("Not-existing module should be null", exportContext.getModule());
494     }
495
496     /**
497      * Negative test trying to get <code>SchemaExportContext</code> with invalid identifier. Test is expected to fail
498      * with <code>RestconfDocumentedException</code> error type, error tag and error status code are compared to
499      * expected values.
500      */
501     @Test
502     public void toSchemaExportContextFromIdentifierInvalidIdentifierNegativeTest() {
503         try {
504             ParserIdentifier.toSchemaExportContextFromIdentifier(
505                     this.schemaContext, TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME, null, sourceProvider);
506             fail("Test should fail due to invalid identifier supplied");
507         } catch (final RestconfDocumentedException e) {
508             assertEquals("Not expected error type",
509                     RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
510             assertEquals("Not expected error tag",
511                     RestconfError.ErrorTag.INVALID_VALUE, e.getErrors().get(0).getErrorTag());
512             assertEquals("Not expected error status code",
513                     400, e.getErrors().get(0).getErrorTag().getStatusCode());
514         }
515     }
516
517     /**
518      * Positive test of getting <code>SchemaExportContext</code> for module behind mount point.
519      * Expected module name, revision and namespace are verified.
520      */
521     @Test
522     public void toSchemaExportContextFromIdentifierMountPointTest() {
523         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
524                 this.schemaContext,
525                 MOUNT_POINT_IDENT + "/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION,
526                 this.mountPointService, sourceProvider);
527
528         final Module module = exportContext.getModule();
529         assertNotNull("Export context should contains test module", module);
530
531         assertEquals("Returned not expected module name",
532                 TEST_MODULE_NAME, module.getName());
533         assertEquals("Returned not expected module revision",
534                 Revision.ofNullable(TEST_MODULE_REVISION), module.getRevision());
535         assertEquals("Returned not expected module namespace",
536                 TEST_MODULE_NAMESPACE, module.getNamespace().toString());
537     }
538
539     /**
540      * Negative test of getting <code>SchemaExportContext</code> when desired module is not found behind mount point.
541      * <code>SchemaExportContext</code> should be still created but module should be set to <code>null</code>.
542      */
543     @Test
544     public void toSchemaExportContextFromIdentifierMountPointNotFoundTest() {
545         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
546                 this.schemaContext,
547                 MOUNT_POINT_IDENT + "/" + "not-existing-module" + "/" + "2016-01-01",
548                 this.mountPointService, sourceProvider);
549
550         assertNotNull("Export context should be parsed", exportContext);
551         assertNull("Not-existing module should be null", exportContext.getModule());
552     }
553
554     /**
555      * Negative test trying to get <code>SchemaExportContext</code> behind mount point with invalid identifier. Test is
556      * expected to fail with <code>RestconfDocumentedException</code> error type, error tag and error status code are
557      * compared to expected values.
558      */
559     @Test
560     public void toSchemaExportContextFromIdentifierMountPointInvalidIdentifierNegativeTest() {
561         try {
562             ParserIdentifier.toSchemaExportContextFromIdentifier(
563                     this.schemaContext,
564                     MOUNT_POINT_IDENT + "/" + TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME,
565                     this.mountPointService, sourceProvider);
566
567             fail("Test should fail due to invalid identifier supplied");
568         } catch (final RestconfDocumentedException e) {
569             assertEquals("Not expected error type",
570                     RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
571             assertEquals("Not expected error tag",
572                     RestconfError.ErrorTag.INVALID_VALUE, e.getErrors().get(0).getErrorTag());
573             assertEquals("Not expected error status code",
574                     400, e.getErrors().get(0).getErrorTag().getStatusCode());
575         }
576     }
577
578     /**
579      * Negative test of getting <code>SchemaExportContext</code> when supplied identifier is null.
580      * <code>NullPointerException</code> is expected. <code>DOMMountPointService</code> is not used.
581      */
582     @Test
583     public void toSchemaExportContextFromIdentifierNullIdentifierNegativeTest() {
584         this.thrown.expect(NullPointerException.class);
585         ParserIdentifier.toSchemaExportContextFromIdentifier(this.schemaContext, null, null, sourceProvider);
586     }
587
588     /**
589      * Negative test of of getting <code>SchemaExportContext</code> when supplied <code>SchemaContext</code> is
590      * <code>null</code>. Test is expected to fail with <code>NullPointerException</code>.
591      */
592     @Test
593     public void toSchemaExportContextFromIdentifierNullSchemaContextNegativeTest() {
594         this.thrown.expect(NullPointerException.class);
595         ParserIdentifier.toSchemaExportContextFromIdentifier(null, TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null,
596                 sourceProvider);
597     }
598
599     /**
600      * Negative test of of getting <code>SchemaExportContext</code> when supplied <code>SchemaContext</code> is
601      * <code>null</code> and identifier specifies module behind mount point. Test is expected to fail with
602      * <code>NullPointerException</code>.
603      */
604     @Test
605     public void toSchemaExportContextFromIdentifierMountPointNullSchemaContextNegativeTest() {
606         this.thrown.expect(NullPointerException.class);
607         ParserIdentifier.toSchemaExportContextFromIdentifier(
608                 null,
609                 MOUNT_POINT_IDENT
610                 + "/"
611                 + TEST_MODULE_NAME
612                 + "/"
613                 + TEST_MODULE_REVISION,
614                 this.mountPointService,
615                 sourceProvider);
616     }
617
618     /**
619      * Negative test of of getting <code>SchemaExportContext</code> when supplied <code>DOMMountPointService</code>
620      * is <code>null</code> and identifier defines module behind mount point. Test is expected to fail with
621      * <code>NullPointerException</code>.
622      */
623     @Test
624     public void toSchemaExportContextFromIdentifierNullMountPointServiceNegativeTest() {
625         this.thrown.expect(NullPointerException.class);
626         ParserIdentifier.toSchemaExportContextFromIdentifier(
627                 this.schemaContext,
628                 MOUNT_POINT_IDENT
629                 + "/"
630                 + TEST_MODULE_NAME
631                 + "/"
632                 + TEST_MODULE_REVISION,
633                 null,
634                 sourceProvider);
635     }
636
637     /**
638      * Negative test of of getting <code>SchemaExportContext</code> when <code>SchemaContext</code> behind mount
639      * point is <code>null</code>. Test is expected to fail with <code>NullPointerException</code>.
640      */
641     @Test
642     public void toSchemaExportContextFromIdentifierNullSchemaContextBehindMountPointNegativeTest() {
643         this.thrown.expect(NullPointerException.class);
644         ParserIdentifier.toSchemaExportContextFromIdentifier(
645                 this.schemaContext,
646                 "/"
647                 + RestconfConstants.MOUNT
648                 + "/"
649                 + TEST_MODULE_NAME
650                 + "/"
651                 + TEST_MODULE_REVISION,
652                 this.mockMountPointService,
653                 sourceProvider);
654     }
655
656     /**
657      * Test invoke RPC.
658      *
659      * <p>
660      * Verify if RPC schema node was found.
661      */
662     @Test
663     public void invokeRpcTest() {
664         final InstanceIdentifierContext<?> result = ParserIdentifier.toInstanceIdentifier(
665                 INVOKE_RPC, this.schemaContext, Optional.empty());
666
667         // RPC schema node
668         final QName rpcQName = result.getSchemaNode().getQName();
669         assertEquals("invoke:rpc:module", rpcQName.getModule().getNamespace().toString());
670         assertEquals("rpc-test", rpcQName.getLocalName());
671
672         // other fields
673         assertEquals(IdentifierCodec.deserialize(INVOKE_RPC, schemaContext), result.getInstanceIdentifier());
674         assertEquals(null, result.getMountPoint());
675         assertEquals(this.schemaContext, result.getSchemaContext());
676     }
677
678     /**
679      * Test invoke RPC on mount point.
680      *
681      * <p>
682      * Verify if RPC schema node was found.
683      */
684     @Test
685     public void invokeRpcOnMountPointTest() {
686         final InstanceIdentifierContext<?> result = ParserIdentifier.toInstanceIdentifier(
687                 MOUNT_POINT_IDENT + "/" + INVOKE_RPC, this.schemaContext, Optional.of(this.mountPointService));
688
689         // RPC schema node
690         final QName rpcQName = result.getSchemaNode().getQName();
691         assertEquals("invoke:rpc:module", rpcQName.getModule().getNamespace().toString());
692         assertEquals("rpc-test", rpcQName.getLocalName());
693
694         // other fields
695         assertEquals(IdentifierCodec.deserialize(INVOKE_RPC, schemaContext), result.getInstanceIdentifier());
696         assertEquals(this.mountPoint, result.getMountPoint());
697         assertEquals(this.schemaContextOnMountPoint, result.getSchemaContext());
698     }
699
700     /**
701      * Test Action.
702      * Verify if Action schema node was found.
703      */
704     @Test
705     public void invokeActionTest() {
706         final InstanceIdentifierContext<?> result = ParserIdentifier
707             .toInstanceIdentifier(INVOKE_ACTION, this.schemaContext, Optional.empty());
708
709         // Action schema node
710         final QName actionQName = result.getSchemaNode().getQName();
711         assertEquals("https://example.com/ns/example-actions", actionQName.getModule().getNamespace().toString());
712         assertEquals("reset", actionQName.getLocalName());
713
714         // other fields
715         assertEquals(IdentifierCodec.deserialize(INVOKE_ACTION, schemaContext), result.getInstanceIdentifier());
716         assertNull(result.getMountPoint());
717         assertSame(this.schemaContext, result.getSchemaContext());
718     }
719
720     /**
721      * Test invoke Action on mount point.
722      * Verify if Action schema node was found.
723      */
724     @Test
725     public void invokeActionOnMountPointTest() {
726         final InstanceIdentifierContext<?> result = ParserIdentifier
727             .toInstanceIdentifier(MOUNT_POINT_IDENT + "/" + INVOKE_ACTION, this.schemaContext,
728                 Optional.of(this.mountPointService));
729
730         // Action schema node
731         final QName actionQName = result.getSchemaNode().getQName();
732         assertEquals("https://example.com/ns/example-actions", actionQName.getModule().getNamespace().toString());
733         assertEquals("reset", actionQName.getLocalName());
734
735         // other fields
736         assertEquals(IdentifierCodec.deserialize(INVOKE_ACTION, schemaContext), result.getInstanceIdentifier());
737         assertEquals(this.mountPoint, result.getMountPoint());
738         assertEquals(this.schemaContextOnMountPoint, result.getSchemaContext());
739     }
740 }