Bump upstreams
[netconf.git] / restconf / restconf-nb / 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             + "/(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         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                 .addService(DOMSchemaService.class, FixedDOMSchemaService.of(SCHEMA_CONTEXT_ON_MOUNT_POINT))
133                 .register()
134                 .getInstance();
135
136         // register mount point with null schema context
137         when(mockMountPointService.getMountPoint(YangInstanceIdentifier.empty()))
138                 .thenReturn(Optional.of(mockMountPoint));
139     }
140
141     /**
142      * {@link ParserIdentifier#toInstanceIdentifier(String, SchemaContext)} tests.
143      */
144
145     /**
146      * Positive test of creating <code>InstanceIdentifierContext</code> from identifier when all nodes are defined
147      * in one module.
148      */
149     @Test
150     public void toInstanceIdentifierTest() {
151         final InstanceIdentifierContext context = ParserIdentifier.toInstanceIdentifier(
152                 TEST_IDENT, SCHEMA_CONTEXT, Optional.empty());
153
154         assertEquals("Returned not expected identifier",
155                 TEST_IDENT_RESULT, context .getInstanceIdentifier().toString());
156     }
157
158     /**
159      * Positive test of creating <code>InstanceIdentifierContext</code> from identifier when nodes are defined in
160      * multiple modules.
161      */
162     @Test
163     public void toInstanceIdentifierOtherModulesTest() {
164         final InstanceIdentifierContext context = ParserIdentifier.toInstanceIdentifier(
165                 TEST_IDENT_OTHERS, SCHEMA_CONTEXT, Optional.empty());
166
167         assertEquals("Returned not expected identifier",
168                 TEST_IDENT_OTHERS_RESULT, context.getInstanceIdentifier().toString());
169     }
170
171     /**
172      * Positive test of creating <code>InstanceIdentifierContext</code> from identifier containing
173      * {@link RestconfConstants#MOUNT}.
174      */
175     @Test
176     public void toInstanceIdentifierMountPointTest() {
177         final InstanceIdentifierContext context = ParserIdentifier.toInstanceIdentifier(
178                 MOUNT_POINT_IDENT + "/" + TEST_IDENT, SCHEMA_CONTEXT, Optional.of(mountPointService));
179
180         assertEquals("Returned not expected identifier",
181                 TEST_IDENT_RESULT.toString(), context.getInstanceIdentifier().toString());
182
183         assertEquals("Mount point not found",
184                 mountPoint, context.getMountPoint());
185
186         assertEquals("Schema context from mount point expected",
187                 SCHEMA_CONTEXT_ON_MOUNT_POINT, context.getSchemaContext());
188     }
189
190     /**
191      * Test of creating <code>InstanceIdentifierContext</code> when identifier is <code>null</code>.
192      * <code>{@link YangInstanceIdentifier#empty()}</code> should be returned.
193      */
194     @Test
195     public void toInstanceIdentifierNullIdentifierTest() {
196         final InstanceIdentifierContext context = ParserIdentifier.toInstanceIdentifier(
197                 null, SCHEMA_CONTEXT, Optional.empty());
198         assertEquals("Returned not expected identifier",
199                 YangInstanceIdentifier.empty(), context.getInstanceIdentifier());
200     }
201
202     /**
203      * Negative test of creating <code>InstanceIdentifierContext</code> when <code>SchemaContext</code> is
204      * <code>null</code>. Test fails expecting <code>NullPointerException</code>.
205      */
206     @Test
207     public void toInstanceIdentifierNullSchemaContextNegativeTest() {
208         assertThrows(NullPointerException.class,
209             () -> ParserIdentifier.toInstanceIdentifier(TEST_IDENT, null, Optional.empty()));
210     }
211
212     /**
213      * Api path can be empty. <code>YangInstanceIdentifier.EMPTY</code> is expected to be returned.
214      */
215     @Test
216     public void toInstanceIdentifierEmptyIdentifierTest() {
217         final InstanceIdentifierContext context = ParserIdentifier.toInstanceIdentifier(
218                 "", SCHEMA_CONTEXT, Optional.empty());
219         assertEquals("Returned not expected identifier",
220                 YangInstanceIdentifier.empty(), context.getInstanceIdentifier());
221     }
222
223     /**
224      * Negative test with invalid test identifier. Test should fail with <code>RestconfDocumentedException</code>.
225      */
226     @Test
227     public void toInstanceIdentifierInvalidIdentifierNegativeTest() {
228         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
229             () -> ParserIdentifier.toInstanceIdentifier(INVALID_TEST_IDENT, SCHEMA_CONTEXT, Optional.empty()));
230     }
231
232     /**
233      * Negative test when identifier contains {@link RestconfConstants#MOUNT} but identifier part is not valid. Test
234      * should fail with <code>RestconfDocumentedException</code>.
235      */
236     @Test
237     public void toInstanceIdentifierMountPointInvalidIdentifierNegativeTest() {
238         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
239             () -> ParserIdentifier.toInstanceIdentifier(INVALID_MOUNT_POINT_IDENT, SCHEMA_CONTEXT,
240                 Optional.of(mountPointService)));
241     }
242
243     /**
244      * Negative test when <code>DOMMountPoint</code> cannot be found. Test is expected to fail with
245      * <code>RestconfDocumentedException</code> error type, error tag and error status code are
246      * compared to expected values.
247      */
248     @Test
249     public void toInstanceIdentifierMissingMountPointNegativeTest() {
250         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
251             () -> ParserIdentifier.toInstanceIdentifier("/yang-ext:mount", SCHEMA_CONTEXT,
252                 Optional.of(mountPointService)));
253         final List<RestconfError> errors = ex.getErrors();
254         assertEquals(1, errors.size());
255         assertEquals("Not expected error type", ErrorType.PROTOCOL, errors.get(0).getErrorType());
256         assertEquals("Not expected error tag", ErrorTags.RESOURCE_DENIED_TRANSPORT, errors.get(0).getErrorTag());
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         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
267             () -> ParserIdentifier.toInstanceIdentifier("yang-ext:mount", SCHEMA_CONTEXT, Optional.empty()));
268         assertEquals("Not expected error type", ErrorType.APPLICATION, ex.getErrors().get(0).getErrorType());
269         assertEquals("Not expected error tag", ErrorTag.OPERATION_FAILED, ex.getErrors().get(0).getErrorTag());
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", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
300         assertEquals("Not expected error tag", ErrorTag.INVALID_VALUE,
301             ex.getErrors().get(0).getErrorTag());
302     }
303
304     /**
305      * Negative test when supplied identifier is too short (contains only module name).
306      * <code>RestconfDocumentedException</code> is expected and error type, error tag and error status code are
307      * compared to expected values.
308      */
309     @Test
310     public void makeQNameFromIdentifierTooShortIdentifierNegativeTest() {
311         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
312             () -> ParserIdentifier.makeQNameFromIdentifier(TEST_MODULE_NAME));
313         assertEquals("Not expected error type", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
314         assertEquals("Not expected error tag", ErrorTag.INVALID_VALUE,
315             ex.getErrors().get(0).getErrorTag());
316     }
317
318     /**
319      * Positive test of making <code>QName</code> from identifier for module behind mount point. Value from returned
320      * <code>QName</code> are compared to expected values.
321      */
322     @Test
323     public void makeQNameFromIdentifierMountTest() {
324         final Entry<String, Revision> qName = ParserIdentifier.makeQNameFromIdentifier(
325                 MOUNT_POINT_IDENT
326                 + "/"
327                 + TEST_MODULE_NAME
328                 + "/"
329                 + TEST_MODULE_REVISION);
330
331         assertNotNull("QName should be created", qName);
332         assertEquals("Returned not expected module name", TEST_MODULE_NAME, qName.getKey());
333         assertEquals("Returned not expected module revision", Revision.of(TEST_MODULE_REVISION), qName.getValue());
334     }
335
336     /**
337      * Negative test when supplied identifier for module behind mount point is in invalid format and then revision is
338      * not parsable. <code>RestconfDocumentedException</code> is expected and error type, error tag and error status
339      * code are compared to expected values.
340      */
341     @Test
342     public void makeQNameFromIdentifierMountPointInvalidIdentifierNegativeTest() {
343         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
344             () -> ParserIdentifier.makeQNameFromIdentifier(
345                     MOUNT_POINT_IDENT + "/" + TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME));
346         assertEquals("Not expected error type", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
347         assertEquals("Not expected error tag", ErrorTag.INVALID_VALUE,
348             ex.getErrors().get(0).getErrorTag());
349     }
350
351     /**
352      * Negative test when supplied identifier for module behind mount point is too short (contains only module name).
353      * <code>RestconfDocumentedException</code> is expected and error type, error tag and error status code
354      * are compared to expected values.
355      */
356     @Test
357     public void makeQNameFromIdentifierMountPointTooShortIdentifierNegativeTest() {
358         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
359             () -> ParserIdentifier.makeQNameFromIdentifier(MOUNT_POINT_IDENT + "/" + TEST_MODULE_NAME));
360         assertEquals("Not expected error type", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
361         assertEquals("Not expected error tag", ErrorTag.INVALID_VALUE,
362             ex.getErrors().get(0).getErrorTag());
363     }
364
365     /**
366      * Negative test trying to make <code>QName</code> from <code>null</code> identifier. Test is expected to fail with
367      * <code>NullPointerException</code>.
368      */
369     @Test
370     public void makeQNameFromIdentifierNullIdentifierNegativeTest() {
371         assertThrows(NullPointerException.class, () -> ParserIdentifier.makeQNameFromIdentifier(null));
372     }
373
374     /**
375      * Negative test trying to make <code>QName</code> from empty identifier. Test is expected to fail with
376      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code is compared to expected
377      * values.
378      */
379     @Test
380     public void makeQNameFromIdentifierEmptyIdentifierNegativeTest() {
381         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
382             () -> ParserIdentifier.makeQNameFromIdentifier(""));
383         assertEquals("Not expected error type", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
384         assertEquals("Not expected error tag", ErrorTag.INVALID_VALUE,
385             ex.getErrors().get(0).getErrorTag());
386     }
387
388     /**
389      * Negative test with identifier containing double slash. Between // there is one empty string which will be
390      * incorrectly considered to be module revision. Test is expected to fail with
391      * <code>RestconfDocumentedException</code> and error type, error tag and error status code are compared to
392      * expected values.
393      */
394     @Test
395     public void makeQNameFromIdentifierDoubleSlashNegativeTest() {
396         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
397             () -> ParserIdentifier.makeQNameFromIdentifier(TEST_MODULE_NAME + "//" + TEST_MODULE_REVISION));
398         assertEquals("Not expected error type", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
399         assertEquals("Not expected error tag", ErrorTag.INVALID_VALUE,
400             ex.getErrors().get(0).getErrorTag());
401     }
402
403     /**
404      * {@link ParserIdentifier#toSchemaExportContextFromIdentifier(SchemaContext, String, DOMMountPointService)} tests.
405      */
406
407     /**
408      * Positive test of getting <code>SchemaExportContext</code>. Expected module name, revision and namespace are
409      * verified.
410      */
411     @Test
412     public void toSchemaExportContextFromIdentifierTest() {
413         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
414                 SCHEMA_CONTEXT, TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null, sourceProvider);
415
416         assertNotNull("Export context should be parsed", exportContext);
417
418         final Module module = exportContext.getModule();
419         assertNotNull("Export context should contains test module", module);
420
421         assertEquals("Returned not expected module name", TEST_MODULE_NAME, module.getName());
422         assertEquals("Returned not expected module revision",
423                 Revision.ofNullable(TEST_MODULE_REVISION), module.getRevision());
424         assertEquals("Returned not expected module namespace", TEST_MODULE_NAMESPACE, module.getNamespace().toString());
425     }
426
427     /**
428      * Test of getting <code>SchemaExportContext</code> when desired module is not found.
429      * <code>SchemaExportContext</code> should be created but module should be set to <code>null</code>.
430      */
431     @Test
432     public void toSchemaExportContextFromIdentifierNotFoundTest() {
433         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
434                 SCHEMA_CONTEXT,
435                 "not-existing-module" + "/" + "2016-01-01",
436                 null, sourceProvider);
437
438         assertNotNull("Export context should be parsed", exportContext);
439         assertNull("Not-existing module should be null", exportContext.getModule());
440     }
441
442     /**
443      * Negative test trying to get <code>SchemaExportContext</code> with invalid identifier. Test is expected to fail
444      * with <code>RestconfDocumentedException</code> error type, error tag and error status code are compared to
445      * expected values.
446      */
447     @Test
448     public void toSchemaExportContextFromIdentifierInvalidIdentifierNegativeTest() {
449         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
450             () -> ParserIdentifier.toSchemaExportContextFromIdentifier(
451                     SCHEMA_CONTEXT, TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME, null, sourceProvider));
452         assertEquals("Not expected error type", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
453         assertEquals("Not expected error tag", ErrorTag.INVALID_VALUE,
454             ex.getErrors().get(0).getErrorTag());
455     }
456
457     /**
458      * Positive test of getting <code>SchemaExportContext</code> for module behind mount point.
459      * Expected module name, revision and namespace are verified.
460      */
461     @Test
462     public void toSchemaExportContextFromIdentifierMountPointTest() {
463         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
464                 SCHEMA_CONTEXT,
465                 MOUNT_POINT_IDENT + "/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION,
466                 mountPointService, sourceProvider);
467
468         final Module module = exportContext.getModule();
469         assertNotNull("Export context should contains test module", module);
470
471         assertEquals("Returned not expected module name",
472                 TEST_MODULE_NAME, module.getName());
473         assertEquals("Returned not expected module revision",
474                 Revision.ofNullable(TEST_MODULE_REVISION), module.getRevision());
475         assertEquals("Returned not expected module namespace",
476                 TEST_MODULE_NAMESPACE, module.getNamespace().toString());
477     }
478
479     /**
480      * Negative test of getting <code>SchemaExportContext</code> when desired module is not found behind mount point.
481      * <code>SchemaExportContext</code> should be still created but module should be set to <code>null</code>.
482      */
483     @Test
484     public void toSchemaExportContextFromIdentifierMountPointNotFoundTest() {
485         final SchemaExportContext exportContext = ParserIdentifier.toSchemaExportContextFromIdentifier(
486                 SCHEMA_CONTEXT,
487                 MOUNT_POINT_IDENT + "/" + "not-existing-module" + "/" + "2016-01-01",
488                 mountPointService, sourceProvider);
489
490         assertNotNull("Export context should be parsed", exportContext);
491         assertNull("Not-existing module should be null", exportContext.getModule());
492     }
493
494     /**
495      * Negative test trying to get <code>SchemaExportContext</code> behind mount point with invalid identifier. Test is
496      * expected to fail with <code>RestconfDocumentedException</code> error type, error tag and error status code are
497      * compared to expected values.
498      */
499     @Test
500     public void toSchemaExportContextFromIdentifierMountPointInvalidIdentifierNegativeTest() {
501         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
502             () -> ParserIdentifier.toSchemaExportContextFromIdentifier(SCHEMA_CONTEXT,
503                 MOUNT_POINT_IDENT + "/" + TEST_MODULE_REVISION + "/" + TEST_MODULE_NAME, mountPointService,
504                 sourceProvider));
505
506         assertEquals("Not expected error type", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
507         assertEquals("Not expected error tag", ErrorTag.INVALID_VALUE,
508             ex.getErrors().get(0).getErrorTag());
509     }
510
511     /**
512      * Negative test of getting <code>SchemaExportContext</code> when supplied identifier is null.
513      * <code>NullPointerException</code> is expected. <code>DOMMountPointService</code> is not used.
514      */
515     @Test
516     public void toSchemaExportContextFromIdentifierNullIdentifierNegativeTest() {
517         assertThrows(NullPointerException.class,
518             () -> ParserIdentifier.toSchemaExportContextFromIdentifier(SCHEMA_CONTEXT, null, null, sourceProvider));
519     }
520
521     /**
522      * Negative test of of getting <code>SchemaExportContext</code> when supplied <code>SchemaContext</code> is
523      * <code>null</code>. Test is expected to fail with <code>NullPointerException</code>.
524      */
525     @Test
526     public void toSchemaExportContextFromIdentifierNullSchemaContextNegativeTest() {
527         assertThrows(NullPointerException.class, () -> ParserIdentifier.toSchemaExportContextFromIdentifier(null,
528             TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null, sourceProvider));
529     }
530
531     /**
532      * Negative test of of getting <code>SchemaExportContext</code> when supplied <code>SchemaContext</code> is
533      * <code>null</code> and identifier specifies module behind mount point. Test is expected to fail with
534      * <code>NullPointerException</code>.
535      */
536     @Test
537     public void toSchemaExportContextFromIdentifierMountPointNullSchemaContextNegativeTest() {
538         assertThrows(NullPointerException.class, () -> ParserIdentifier.toSchemaExportContextFromIdentifier(null,
539             MOUNT_POINT_IDENT + "/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, mountPointService,
540             sourceProvider));
541     }
542
543     /**
544      * Negative test of of getting <code>SchemaExportContext</code> when supplied <code>DOMMountPointService</code>
545      * is <code>null</code> and identifier defines module behind mount point. Test is expected to fail with
546      * <code>NullPointerException</code>.
547      */
548     @Test
549     public void toSchemaExportContextFromIdentifierNullMountPointServiceNegativeTest() {
550         assertThrows(NullPointerException.class, () -> ParserIdentifier.toSchemaExportContextFromIdentifier(
551             SCHEMA_CONTEXT, MOUNT_POINT_IDENT + "/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION, null,
552             sourceProvider));
553     }
554
555     @Test
556     public void toSchemaExportContextFromIdentifierNullSchemaContextBehindMountPointNegativeTest() {
557         assertThrows(IllegalStateException.class, () -> ParserIdentifier.toSchemaExportContextFromIdentifier(
558                 SCHEMA_CONTEXT, "/yang-ext:mount/" + TEST_MODULE_NAME + "/" + TEST_MODULE_REVISION,
559                 mockMountPointService, sourceProvider));
560     }
561
562     /**
563      * Test invoke RPC.
564      *
565      * <p>
566      * Verify if RPC schema node was found.
567      */
568     @Test
569     public void invokeRpcTest() {
570         final InstanceIdentifierContext result = ParserIdentifier.toInstanceIdentifier(
571                 INVOKE_RPC, SCHEMA_CONTEXT, Optional.empty());
572
573         // RPC schema node
574         final QName rpcQName = result.getSchemaNode().getQName();
575         assertEquals("invoke:rpc:module", rpcQName.getModule().getNamespace().toString());
576         assertEquals("rpc-test", rpcQName.getLocalName());
577
578         // other fields
579         assertEquals(IdentifierCodec.deserialize(INVOKE_RPC, SCHEMA_CONTEXT), result.getInstanceIdentifier());
580         assertEquals(null, result.getMountPoint());
581         assertEquals(SCHEMA_CONTEXT, result.getSchemaContext());
582     }
583
584     /**
585      * Test invoke RPC on mount point.
586      *
587      * <p>
588      * Verify if RPC schema node was found.
589      */
590     @Test
591     public void invokeRpcOnMountPointTest() {
592         final InstanceIdentifierContext result = ParserIdentifier.toInstanceIdentifier(
593                 MOUNT_POINT_IDENT + "/" + INVOKE_RPC, SCHEMA_CONTEXT, Optional.of(mountPointService));
594
595         // RPC schema node
596         final QName rpcQName = result.getSchemaNode().getQName();
597         assertEquals("invoke:rpc:module", rpcQName.getModule().getNamespace().toString());
598         assertEquals("rpc-test", rpcQName.getLocalName());
599
600         // other fields
601         assertEquals(IdentifierCodec.deserialize(INVOKE_RPC, SCHEMA_CONTEXT), result.getInstanceIdentifier());
602         assertEquals(mountPoint, result.getMountPoint());
603         assertEquals(SCHEMA_CONTEXT_ON_MOUNT_POINT, result.getSchemaContext());
604     }
605
606     /**
607      * Test Action.
608      * Verify if Action schema node was found.
609      */
610     @Test
611     public void invokeActionTest() {
612         final InstanceIdentifierContext result = ParserIdentifier
613             .toInstanceIdentifier(INVOKE_ACTION, SCHEMA_CONTEXT, Optional.empty());
614
615         // Action schema node
616         final QName actionQName = result.getSchemaNode().getQName();
617         assertEquals("https://example.com/ns/example-actions", actionQName.getModule().getNamespace().toString());
618         assertEquals("reset", actionQName.getLocalName());
619
620         // other fields
621         assertEquals(IdentifierCodec.deserialize(INVOKE_ACTION, SCHEMA_CONTEXT), result.getInstanceIdentifier());
622         assertNull(result.getMountPoint());
623         assertSame(SCHEMA_CONTEXT, result.getSchemaContext());
624     }
625
626     /**
627      * Test invoke Action on mount point.
628      * Verify if Action schema node was found.
629      */
630     @Test
631     public void invokeActionOnMountPointTest() {
632         final InstanceIdentifierContext result = ParserIdentifier
633             .toInstanceIdentifier(MOUNT_POINT_IDENT + "/" + INVOKE_ACTION, SCHEMA_CONTEXT,
634                 Optional.of(mountPointService));
635
636         // Action schema node
637         final QName actionQName = result.getSchemaNode().getQName();
638         assertEquals("https://example.com/ns/example-actions", actionQName.getModule().getNamespace().toString());
639         assertEquals("reset", actionQName.getLocalName());
640
641         // other fields
642         assertEquals(IdentifierCodec.deserialize(INVOKE_ACTION, SCHEMA_CONTEXT), result.getInstanceIdentifier());
643         assertEquals(mountPoint, result.getMountPoint());
644         assertEquals(SCHEMA_CONTEXT_ON_MOUNT_POINT, result.getSchemaContext());
645     }
646 }