fd4f6a67ffcbaacc02df47a6194203fce80b80cd
[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.List;
18 import java.util.Map.Entry;
19 import java.util.Optional;
20 import org.junit.AfterClass;
21 import org.junit.Before;
22 import org.junit.BeforeClass;
23 import org.junit.Test;
24 import org.junit.runner.RunWith;
25 import org.mockito.Mock;
26 import org.mockito.junit.MockitoJUnitRunner;
27 import org.opendaylight.mdsal.dom.api.DOMMountPoint;
28 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
29 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
30 import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
31 import org.opendaylight.mdsal.dom.broker.DOMMountPointServiceImpl;
32 import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
33 import org.opendaylight.restconf.common.ErrorTags;
34 import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
35 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
36 import org.opendaylight.restconf.common.errors.RestconfError;
37 import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils;
38 import org.opendaylight.restconf.nb.rfc8040.rests.services.api.SchemaExportContext;
39 import org.opendaylight.restconf.nb.rfc8040.utils.RestconfConstants;
40 import org.opendaylight.yangtools.yang.common.ErrorTag;
41 import org.opendaylight.yangtools.yang.common.ErrorType;
42 import org.opendaylight.yangtools.yang.common.QName;
43 import org.opendaylight.yangtools.yang.common.Revision;
44 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
45 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
46 import org.opendaylight.yangtools.yang.model.api.Module;
47 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
48
49 /**
50  * Unit tests for {@link ParserIdentifier}.
51  */
52 @RunWith(MockitoJUnitRunner.StrictStubs.class)
53 public class ParserIdentifierTest {
54     // mount point identifier
55     private static final String MOUNT_POINT_IDENT = "mount-point:mount-container/point-number/yang-ext:mount";
56
57     // invalid mount point identifier
58     private static final String INVALID_MOUNT_POINT_IDENT = "mount-point:point-number/yang-ext:mount";
59
60     // test identifier + expected result
61     private static final String TEST_IDENT =
62             "parser-identifier:cont1/cont2/listTest/list-in-grouping=name/leaf-A.B";
63
64     private static final String TEST_IDENT_RESULT =
65             "/(parser:identifier?revision=2016-06-02)cont1/cont2/listTest/listTest/list-in-grouping/"
66             + "list-in-grouping[{(parser:identifier?revision=2016-06-02)name=name}]/leaf-A.B";
67
68     // test identifier with nodes defined in other modules using augmentation + expected result
69     private static final String TEST_IDENT_OTHERS =
70             "parser-identifier-included:list-1=name,2016-06-02/parser-identifier:augment-leaf";
71
72     private static final String TEST_IDENT_OTHERS_RESULT =
73             "/(parser:identifier:included?revision=2016-06-02)list-1/list-1"
74             + "[{(parser:identifier:included?revision=2016-06-02)name=name, "
75             + "(parser:identifier:included?revision=2016-06-02)revision=2016-06-02}]"
76             + "/AugmentationIdentifier{childNames=[(parser:identifier?revision=2016-06-02)augment-leaf]}/"
77             + "(parser:identifier?revision=2016-06-02)augment-leaf";
78
79     // invalid test identifier
80     private static final String INVALID_TEST_IDENT =
81             "parser-identifier:cont2/listTest/list-in-grouping=name/leaf-A.B";
82
83     private static final String TEST_MODULE_NAME = "test-module";
84     private static final String TEST_MODULE_REVISION = "2016-06-02";
85     private static final String TEST_MODULE_NAMESPACE = "test:module";
86
87     private static final String INVOKE_RPC = "invoke-rpc-module:rpc-test";
88     private static final String INVOKE_ACTION = "example-actions:interfaces/interface=eth0/reset";
89
90     // schema context with test modules
91     private static EffectiveModelContext SCHEMA_CONTEXT;
92     // contains the same modules but it is different object (it can be compared with equals)
93     private static EffectiveModelContext SCHEMA_CONTEXT_ON_MOUNT_POINT;
94
95     // mount point and mount point service
96     private DOMMountPoint mountPoint;
97     private DOMMountPointService mountPointService;
98
99     // mock mount point and mount point service
100     @Mock
101     private DOMMountPoint mockMountPoint;
102     @Mock
103     private DOMMountPointService mockMountPointService;
104     @Mock
105     private DOMSchemaService domSchemaService;
106     @Mock
107     private DOMYangTextSourceProvider sourceProvider;
108
109     @BeforeClass
110     public static void beforeClass() throws Exception {
111         SCHEMA_CONTEXT = YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/parser-identifier"));
112         SCHEMA_CONTEXT_ON_MOUNT_POINT =
113                 YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/parser-identifier"));
114     }
115
116     @AfterClass
117     public static void afterClass() {
118         SCHEMA_CONTEXT = null;
119         SCHEMA_CONTEXT_ON_MOUNT_POINT = null;
120     }
121
122     @Before
123     public void setup() throws Exception {
124         mountPointService = new DOMMountPointServiceImpl();
125
126         // create and register mount point
127         final YangInstanceIdentifier mountPointId = YangInstanceIdentifier.builder()
128                 .node(QName.create("mount:point", "2016-06-02", "mount-container"))
129                 .node(QName.create("mount:point", "2016-06-02", "point-number"))
130                 .build();
131
132         mountPoint = mountPointService.createMountPoint(mountPointId)
133                 .addService(DOMSchemaService.class, FixedDOMSchemaService.of(SCHEMA_CONTEXT_ON_MOUNT_POINT))
134                 .register()
135                 .getInstance();
136
137         // register mount point with null schema context
138         when(mockMountPointService.getMountPoint(YangInstanceIdentifier.empty()))
139                 .thenReturn(Optional.of(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(mountPointService));
180
181         assertEquals("Returned not expected identifier",
182                 TEST_IDENT_RESULT.toString(), context.getInstanceIdentifier().toString());
183
184         assertEquals("Mount point not found",
185                 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(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("/yang-ext:mount", SCHEMA_CONTEXT,
253                 Optional.of(mountPointService)));
254         final List<RestconfError> errors = ex.getErrors();
255         assertEquals(1, errors.size());
256         assertEquals("Not expected error type", ErrorType.PROTOCOL, errors.get(0).getErrorType());
257         assertEquals("Not expected error tag", ErrorTags.RESOURCE_DENIED_TRANSPORT, errors.get(0).getErrorTag());
258     }
259
260     /**
261      * Negative test when <code>{@link DOMMountPointService}</code> is absent. Test is expected to fail with
262      * <code>RestconfDocumentedException</code> error type, error tag and error status code are
263      * compared to expected values.
264      */
265     @Test
266     public void toInstanceIdentifierMissingMountPointServiceNegativeTest() {
267         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
268             () -> ParserIdentifier.toInstanceIdentifier("yang-ext:mount", SCHEMA_CONTEXT, Optional.empty()));
269         assertEquals("Not expected error type", ErrorType.APPLICATION, ex.getErrors().get(0).getErrorType());
270         assertEquals("Not expected error tag", ErrorTag.OPERATION_FAILED, ex.getErrors().get(0).getErrorTag());
271     }
272
273     /**
274      * {@link ParserIdentifier#makeQNameFromIdentifier(String)} tests.
275      */
276
277     /**
278      * Positive test of making <code>QName</code> from identifier and compare values from returned <code>QName</code>
279      * to expected values.
280      */
281     @Test
282     public void makeQNameFromIdentifierTest() {
283         final Entry<String, Revision> qName = ParserIdentifier.makeQNameFromIdentifier(
284             TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION);
285
286         assertNotNull("QName should be created", qName);
287         assertEquals("Returned not expected module name", TEST_MODULE_NAME, qName.getKey());
288         assertEquals("Returned not expected module revision", Revision.of(TEST_MODULE_REVISION), qName.getValue());
289     }
290
291     /**
292      * Negative test when supplied identifier is in invalid format and then revision is not parsable.
293      * <code>RestconfDocumentedException</code> is expected and error type, error tag and error status code are
294      * compared to expected values.
295      */
296     @Test
297     public void makeQNameFromIdentifierInvalidIdentifierNegativeTest() {
298         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
299             () -> ParserIdentifier.makeQNameFromIdentifier(TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME));
300         assertEquals("Not expected error type", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
301         assertEquals("Not expected error tag", ErrorTag.INVALID_VALUE,
302             ex.getErrors().get(0).getErrorTag());
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", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
315         assertEquals("Not expected error tag", ErrorTag.INVALID_VALUE,
316             ex.getErrors().get(0).getErrorTag());
317     }
318
319     /**
320      * Positive test of making <code>QName</code> from identifier for module behind mount point. Value from returned
321      * <code>QName</code> are compared to expected values.
322      */
323     @Test
324     public void makeQNameFromIdentifierMountTest() {
325         final Entry<String, Revision> qName = ParserIdentifier.makeQNameFromIdentifier(
326                 MOUNT_POINT_IDENT
327                 + "/"
328                 + TEST_MODULE_NAME
329                 + "/"
330                 + TEST_MODULE_REVISION);
331
332         assertNotNull("QName should be created", qName);
333         assertEquals("Returned not expected module name", TEST_MODULE_NAME, qName.getKey());
334         assertEquals("Returned not expected module revision", Revision.of(TEST_MODULE_REVISION), qName.getValue());
335     }
336
337     /**
338      * Negative test when supplied identifier for module behind mount point is in invalid format and then revision is
339      * not parsable. <code>RestconfDocumentedException</code> is expected and error type, error tag and error status
340      * code are compared to expected values.
341      */
342     @Test
343     public void makeQNameFromIdentifierMountPointInvalidIdentifierNegativeTest() {
344         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
345             () -> ParserIdentifier.makeQNameFromIdentifier(
346                     MOUNT_POINT_IDENT + "/" + TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME));
347         assertEquals("Not expected error type", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
348         assertEquals("Not expected error tag", ErrorTag.INVALID_VALUE,
349             ex.getErrors().get(0).getErrorTag());
350     }
351
352     /**
353      * Negative test when supplied identifier for module behind mount point is too short (contains only module name).
354      * <code>RestconfDocumentedException</code> is expected and error type, error tag and error status code
355      * are compared to expected values.
356      */
357     @Test
358     public void makeQNameFromIdentifierMountPointTooShortIdentifierNegativeTest() {
359         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
360             () -> ParserIdentifier.makeQNameFromIdentifier(MOUNT_POINT_IDENT + "/" + TEST_MODULE_NAME));
361         assertEquals("Not expected error type", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
362         assertEquals("Not expected error tag", ErrorTag.INVALID_VALUE,
363             ex.getErrors().get(0).getErrorTag());
364     }
365
366     /**
367      * Negative test trying to make <code>QName</code> from <code>null</code> identifier. Test is expected to fail with
368      * <code>NullPointerException</code>.
369      */
370     @Test
371     public void makeQNameFromIdentifierNullIdentifierNegativeTest() {
372         assertThrows(NullPointerException.class, () -> ParserIdentifier.makeQNameFromIdentifier(null));
373     }
374
375     /**
376      * Negative test trying to make <code>QName</code> from empty identifier. Test is expected to fail with
377      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code is compared to expected
378      * values.
379      */
380     @Test
381     public void makeQNameFromIdentifierEmptyIdentifierNegativeTest() {
382         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
383             () -> ParserIdentifier.makeQNameFromIdentifier(""));
384         assertEquals("Not expected error type", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
385         assertEquals("Not expected error tag", ErrorTag.INVALID_VALUE,
386             ex.getErrors().get(0).getErrorTag());
387     }
388
389     /**
390      * Negative test with identifier containing double slash. Between // there is one empty string which will be
391      * incorrectly considered to be module revision. Test is expected to fail with
392      * <code>RestconfDocumentedException</code> and error type, error tag and error status code are compared to
393      * expected values.
394      */
395     @Test
396     public void makeQNameFromIdentifierDoubleSlashNegativeTest() {
397         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
398             () -> ParserIdentifier.makeQNameFromIdentifier(TEST_MODULE_NAME + "//" + TEST_MODULE_REVISION));
399         assertEquals("Not expected error type", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
400         assertEquals("Not expected error tag", ErrorTag.INVALID_VALUE,
401             ex.getErrors().get(0).getErrorTag());
402     }
403
404     /**
405      * {@link ParserIdentifier#toSchemaExportContextFromIdentifier(SchemaContext, String, DOMMountPointService)} tests.
406      */
407
408     /**
409      * Positive test of getting <code>SchemaExportContext</code>. Expected module name, revision and namespace are
410      * verified.
411      */
412     @Test
413     public void toSchemaExportContextFromIdentifierTest() {
414         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
415                 SCHEMA_CONTEXT, TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null, sourceProvider);
416
417         assertNotNull("Export context should be parsed", exportContext);
418
419         final Module module = exportContext.getModule();
420         assertNotNull("Export context should contains test module", module);
421
422         assertEquals("Returned not expected module name", TEST_MODULE_NAME, module.getName());
423         assertEquals("Returned not expected module revision",
424                 Revision.ofNullable(TEST_MODULE_REVISION), module.getRevision());
425         assertEquals("Returned not expected module namespace", TEST_MODULE_NAMESPACE, module.getNamespace().toString());
426     }
427
428     /**
429      * Test of getting <code>SchemaExportContext</code> when desired module is not found.
430      * <code>SchemaExportContext</code> should be created but module should be set to <code>null</code>.
431      */
432     @Test
433     public void toSchemaExportContextFromIdentifierNotFoundTest() {
434         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
435                 SCHEMA_CONTEXT,
436                 "not-existing-module" + "/" + "2016-01-01",
437                 null, sourceProvider);
438
439         assertNotNull("Export context should be parsed", exportContext);
440         assertNull("Not-existing module should be null", exportContext.getModule());
441     }
442
443     /**
444      * Negative test trying to get <code>SchemaExportContext</code> with invalid identifier. Test is expected to fail
445      * with <code>RestconfDocumentedException</code> error type, error tag and error status code are compared to
446      * expected values.
447      */
448     @Test
449     public void toSchemaExportContextFromIdentifierInvalidIdentifierNegativeTest() {
450         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
451             () -> ParserIdentifier.toSchemaExportContextFromIdentifier(
452                     SCHEMA_CONTEXT, TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME, null, sourceProvider));
453         assertEquals("Not expected error type", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
454         assertEquals("Not expected error tag", ErrorTag.INVALID_VALUE,
455             ex.getErrors().get(0).getErrorTag());
456     }
457
458     /**
459      * Positive test of getting <code>SchemaExportContext</code> for module behind mount point.
460      * Expected module name, revision and namespace are verified.
461      */
462     @Test
463     public void toSchemaExportContextFromIdentifierMountPointTest() {
464         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
465                 SCHEMA_CONTEXT,
466                 MOUNT_POINT_IDENT + "/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION,
467                 mountPointService, sourceProvider);
468
469         final Module module = exportContext.getModule();
470         assertNotNull("Export context should contains test module", module);
471
472         assertEquals("Returned not expected module name",
473                 TEST_MODULE_NAME, module.getName());
474         assertEquals("Returned not expected module revision",
475                 Revision.ofNullable(TEST_MODULE_REVISION), module.getRevision());
476         assertEquals("Returned not expected module namespace",
477                 TEST_MODULE_NAMESPACE, module.getNamespace().toString());
478     }
479
480     /**
481      * Negative test of getting <code>SchemaExportContext</code> when desired module is not found behind mount point.
482      * <code>SchemaExportContext</code> should be still created but module should be set to <code>null</code>.
483      */
484     @Test
485     public void toSchemaExportContextFromIdentifierMountPointNotFoundTest() {
486         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
487                 SCHEMA_CONTEXT,
488                 MOUNT_POINT_IDENT + "/" + "not-existing-module" + "/" + "2016-01-01",
489                 mountPointService, sourceProvider);
490
491         assertNotNull("Export context should be parsed", exportContext);
492         assertNull("Not-existing module should be null", exportContext.getModule());
493     }
494
495     /**
496      * Negative test trying to get <code>SchemaExportContext</code> behind mount point with invalid identifier. Test is
497      * expected to fail with <code>RestconfDocumentedException</code> error type, error tag and error status code are
498      * compared to expected values.
499      */
500     @Test
501     public void toSchemaExportContextFromIdentifierMountPointInvalidIdentifierNegativeTest() {
502         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
503             () -> ParserIdentifier.toSchemaExportContextFromIdentifier(SCHEMA_CONTEXT,
504                 MOUNT_POINT_IDENT + "/" + TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME, mountPointService,
505                 sourceProvider));
506
507         assertEquals("Not expected error type", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
508         assertEquals("Not expected error tag", ErrorTag.INVALID_VALUE,
509             ex.getErrors().get(0).getErrorTag());
510     }
511
512     /**
513      * Negative test of getting <code>SchemaExportContext</code> when supplied identifier is null.
514      * <code>NullPointerException</code> is expected. <code>DOMMountPointService</code> is not used.
515      */
516     @Test
517     public void toSchemaExportContextFromIdentifierNullIdentifierNegativeTest() {
518         assertThrows(NullPointerException.class,
519             () -> ParserIdentifier.toSchemaExportContextFromIdentifier(SCHEMA_CONTEXT, null, null, sourceProvider));
520     }
521
522     /**
523      * Negative test of of getting <code>SchemaExportContext</code> when supplied <code>SchemaContext</code> is
524      * <code>null</code>. Test is expected to fail with <code>NullPointerException</code>.
525      */
526     @Test
527     public void toSchemaExportContextFromIdentifierNullSchemaContextNegativeTest() {
528         assertThrows(NullPointerException.class, () -> ParserIdentifier.toSchemaExportContextFromIdentifier(null,
529             TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null, sourceProvider));
530     }
531
532     /**
533      * Negative test of of getting <code>SchemaExportContext</code> when supplied <code>SchemaContext</code> is
534      * <code>null</code> and identifier specifies module behind mount point. Test is expected to fail with
535      * <code>NullPointerException</code>.
536      */
537     @Test
538     public void toSchemaExportContextFromIdentifierMountPointNullSchemaContextNegativeTest() {
539         assertThrows(NullPointerException.class, () -> ParserIdentifier.toSchemaExportContextFromIdentifier(null,
540             MOUNT_POINT_IDENT + "/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, mountPointService,
541             sourceProvider));
542     }
543
544     /**
545      * Negative test of of getting <code>SchemaExportContext</code> when supplied <code>DOMMountPointService</code>
546      * is <code>null</code> and identifier defines module behind mount point. Test is expected to fail with
547      * <code>NullPointerException</code>.
548      */
549     @Test
550     public void toSchemaExportContextFromIdentifierNullMountPointServiceNegativeTest() {
551         assertThrows(NullPointerException.class, () -> ParserIdentifier.toSchemaExportContextFromIdentifier(
552             SCHEMA_CONTEXT, MOUNT_POINT_IDENT + "/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null,
553             sourceProvider));
554     }
555
556     @Test
557     public void toSchemaExportContextFromIdentifierNullSchemaContextBehindMountPointNegativeTest() {
558         assertThrows(IllegalStateException.class, () -> ParserIdentifier.toSchemaExportContextFromIdentifier(
559                 SCHEMA_CONTEXT, "/yang-ext:mount/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION,
560                 mockMountPointService, sourceProvider));
561     }
562
563     /**
564      * Test invoke RPC.
565      *
566      * <p>
567      * Verify if RPC schema node was found.
568      */
569     @Test
570     public void invokeRpcTest() {
571         final InstanceIdentifierContext result = ParserIdentifier.toInstanceIdentifier(
572                 INVOKE_RPC, SCHEMA_CONTEXT, Optional.empty());
573
574         // RPC schema node
575         final QName rpcQName = result.getSchemaNode().getQName();
576         assertEquals("invoke:rpc:module", rpcQName.getModule().getNamespace().toString());
577         assertEquals("rpc-test", rpcQName.getLocalName());
578
579         // other fields
580         assertEquals(IdentifierCodec.deserialize(INVOKE_RPC, SCHEMA_CONTEXT), result.getInstanceIdentifier());
581         assertEquals(null, result.getMountPoint());
582         assertEquals(SCHEMA_CONTEXT, result.getSchemaContext());
583     }
584
585     /**
586      * Test invoke RPC on mount point.
587      *
588      * <p>
589      * Verify if RPC schema node was found.
590      */
591     @Test
592     public void invokeRpcOnMountPointTest() {
593         final InstanceIdentifierContext result = ParserIdentifier.toInstanceIdentifier(
594                 MOUNT_POINT_IDENT + "/" + INVOKE_RPC, SCHEMA_CONTEXT, Optional.of(mountPointService));
595
596         // RPC schema node
597         final QName rpcQName = result.getSchemaNode().getQName();
598         assertEquals("invoke:rpc:module", rpcQName.getModule().getNamespace().toString());
599         assertEquals("rpc-test", rpcQName.getLocalName());
600
601         // other fields
602         assertEquals(IdentifierCodec.deserialize(INVOKE_RPC, SCHEMA_CONTEXT), result.getInstanceIdentifier());
603         assertEquals(mountPoint, result.getMountPoint());
604         assertEquals(SCHEMA_CONTEXT_ON_MOUNT_POINT, result.getSchemaContext());
605     }
606
607     /**
608      * Test Action.
609      * Verify if Action schema node was found.
610      */
611     @Test
612     public void invokeActionTest() {
613         final InstanceIdentifierContext result = ParserIdentifier
614             .toInstanceIdentifier(INVOKE_ACTION, SCHEMA_CONTEXT, Optional.empty());
615
616         // Action schema node
617         final QName actionQName = result.getSchemaNode().getQName();
618         assertEquals("https://example.com/ns/example-actions", actionQName.getModule().getNamespace().toString());
619         assertEquals("reset", actionQName.getLocalName());
620
621         // other fields
622         assertEquals(IdentifierCodec.deserialize(INVOKE_ACTION, SCHEMA_CONTEXT), result.getInstanceIdentifier());
623         assertNull(result.getMountPoint());
624         assertSame(SCHEMA_CONTEXT, result.getSchemaContext());
625     }
626
627     /**
628      * Test invoke Action on mount point.
629      * Verify if Action schema node was found.
630      */
631     @Test
632     public void invokeActionOnMountPointTest() {
633         final InstanceIdentifierContext result = ParserIdentifier
634             .toInstanceIdentifier(MOUNT_POINT_IDENT + "/" + INVOKE_ACTION, SCHEMA_CONTEXT,
635                 Optional.of(mountPointService));
636
637         // Action schema node
638         final QName actionQName = result.getSchemaNode().getQName();
639         assertEquals("https://example.com/ns/example-actions", actionQName.getModule().getNamespace().toString());
640         assertEquals("reset", actionQName.getLocalName());
641
642         // other fields
643         assertEquals(IdentifierCodec.deserialize(INVOKE_ACTION, SCHEMA_CONTEXT), result.getInstanceIdentifier());
644         assertEquals(mountPoint, result.getMountPoint());
645         assertEquals(SCHEMA_CONTEXT_ON_MOUNT_POINT, result.getSchemaContext());
646     }
647 }