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