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