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