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