Migrate users of deprecated QNameModule methods
[yangtools.git] / parser / rfc8040-parser-support / src / test / java / org / opendaylight / yangtools / rfc8040 / parser / YangDataExtensionTest.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.yangtools.rfc8040.parser;
9
10 import static org.hamcrest.CoreMatchers.startsWith;
11 import static org.hamcrest.MatcherAssert.assertThat;
12 import static org.junit.jupiter.api.Assertions.assertEquals;
13 import static org.junit.jupiter.api.Assertions.assertFalse;
14 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
15 import static org.junit.jupiter.api.Assertions.assertNotNull;
16 import static org.junit.jupiter.api.Assertions.assertThrows;
17
18 import java.util.Optional;
19 import org.junit.jupiter.api.Test;
20 import org.opendaylight.yangtools.rfc8040.model.api.YangDataSchemaNode;
21 import org.opendaylight.yangtools.yang.common.QName;
22 import org.opendaylight.yangtools.yang.common.QNameModule;
23 import org.opendaylight.yangtools.yang.common.Revision;
24 import org.opendaylight.yangtools.yang.common.XMLNamespace;
25 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
26 import org.opendaylight.yangtools.yang.model.api.stmt.FeatureSet;
27 import org.opendaylight.yangtools.yang.parser.spi.meta.InvalidSubstatementException;
28 import org.opendaylight.yangtools.yang.parser.spi.meta.MissingSubstatementException;
29 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
30 import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
31
32 class YangDataExtensionTest extends AbstractYangDataTest {
33     private static final StatementStreamSource FOO_MODULE = sourceForResource(
34             "/yang-data-extension-test/foo.yang");
35     private static final StatementStreamSource FOO_INVALID_1_MODULE = sourceForResource(
36             "/yang-data-extension-test/foo-invalid-1.yang");
37     private static final StatementStreamSource FOO_INVALID_2_MODULE = sourceForResource(
38             "/yang-data-extension-test/foo-invalid-2.yang");
39     private static final StatementStreamSource FOO_INVALID_3_MODULE = sourceForResource(
40             "/yang-data-extension-test/foo-invalid-3.yang");
41     private static final StatementStreamSource BAR_MODULE = sourceForResource(
42             "/yang-data-extension-test/bar.yang");
43     private static final StatementStreamSource BAZ_MODULE = sourceForResource(
44             "/yang-data-extension-test/baz.yang");
45     private static final StatementStreamSource FOOBAR_MODULE = sourceForResource(
46             "/yang-data-extension-test/foobar.yang");
47
48     private static final Revision REVISION = Revision.of("2017-06-01");
49     private static final QNameModule FOO_QNAMEMODULE = QNameModule.of(XMLNamespace.of("foo"), REVISION);
50
51     @Test
52     void testYangData() throws Exception {
53         final var schemaContext = REACTOR.newBuild().addSources(FOO_MODULE, IETF_RESTCONF_MODULE).buildEffective();
54         assertNotNull(schemaContext);
55
56         final var extensions = schemaContext.getExtensions();
57         assertEquals(1, extensions.size());
58
59         final var unknownSchemaNodes = schemaContext.findModule(FOO_QNAMEMODULE).orElseThrow().getUnknownSchemaNodes();
60         assertEquals(2, unknownSchemaNodes.size());
61         final var it = unknownSchemaNodes.iterator();
62         assertEquals("my-yang-data-a", assertInstanceOf(YangDataSchemaNode.class, it.next()).getNodeParameter());
63         assertEquals("my-yang-data-b", assertInstanceOf(YangDataSchemaNode.class, it.next()).getNodeParameter());
64         assertFalse(it.hasNext());
65     }
66
67     @Test
68     void testConfigStatementBeingIgnoredInYangDataBody() throws Exception {
69         final var schemaContext = REACTOR.newBuild().addSources(BAZ_MODULE, IETF_RESTCONF_MODULE).buildEffective();
70         assertNotNull(schemaContext);
71
72         final var baz = schemaContext.findModule("baz", REVISION).orElseThrow();
73         final var unknownSchemaNodes = baz.getUnknownSchemaNodes();
74         assertEquals(1, unknownSchemaNodes.size());
75
76         final var myYangDataNode = assertInstanceOf(YangDataSchemaNode.class, unknownSchemaNodes.iterator().next());
77
78         final var yangDataChildren = myYangDataNode.getChildNodes();
79         assertEquals(1, yangDataChildren.size());
80
81         final var contInYangData = assertInstanceOf(ContainerSchemaNode.class, yangDataChildren.iterator().next());
82         assertEquals(Optional.empty(), contInYangData.effectiveConfig());
83         final var innerCont = assertInstanceOf(ContainerSchemaNode.class,
84             contInYangData.dataChildByName(QName.create(baz.getQNameModule(), "inner-cont")));
85         assertEquals(Optional.empty(), innerCont.effectiveConfig());
86         final var grpCont = assertInstanceOf(ContainerSchemaNode.class,
87             contInYangData.dataChildByName(QName.create(baz.getQNameModule(), "grp-cont")));
88         assertEquals(Optional.empty(), grpCont.effectiveConfig());
89     }
90
91     @Test
92     void testIfFeatureStatementBeingIgnoredInYangDataBody() throws Exception {
93         final var schemaContext = REACTOR.newBuild()
94             .setSupportedFeatures(FeatureSet.of())
95             .addSources(FOOBAR_MODULE, IETF_RESTCONF_MODULE)
96             .buildEffective();
97         assertNotNull(schemaContext);
98
99         final var foobar = schemaContext.findModule("foobar", REVISION).orElseThrow();
100         final var unknownSchemaNodes = foobar.getUnknownSchemaNodes();
101         assertEquals(1, unknownSchemaNodes.size());
102
103         final var myYangDataNode = assertInstanceOf(YangDataSchemaNode.class, unknownSchemaNodes.iterator().next());
104
105         final var yangDataChildren = myYangDataNode.getChildNodes();
106         assertEquals(1, yangDataChildren.size());
107
108         final var contInYangData = assertInstanceOf(ContainerSchemaNode.class, yangDataChildren.iterator().next());
109         assertInstanceOf(ContainerSchemaNode.class,
110             contInYangData.dataChildByName(QName.create(foobar.getQNameModule(), "inner-cont")));
111         assertInstanceOf(ContainerSchemaNode.class,
112             contInYangData.dataChildByName(QName.create(foobar.getQNameModule(), "grp-cont")));
113     }
114
115     @Test
116     void testYangDataBeingIgnored() throws Exception {
117         // yang-data statement is ignored if it does not appear as a top-level statement
118         // i.e., it will not appear in the final SchemaContext
119         final var schemaContext = REACTOR.newBuild().addSources(BAR_MODULE, IETF_RESTCONF_MODULE).buildEffective();
120         assertNotNull(schemaContext);
121
122         final var bar = schemaContext.findModule("bar", REVISION).orElseThrow();
123         final var cont = assertInstanceOf(ContainerSchemaNode.class,
124             bar.dataChildByName(QName.create(bar.getQNameModule(), "cont")));
125
126         final var extensions = schemaContext.getExtensions();
127         assertEquals(1, extensions.size());
128
129         final var unknownSchemaNodes = cont.getUnknownSchemaNodes();
130         assertEquals(0, unknownSchemaNodes.size());
131     }
132
133     @Test
134     void testYangDataWithMissingTopLevelContainer() {
135         final var build = REACTOR.newBuild().addSources(FOO_INVALID_1_MODULE, IETF_RESTCONF_MODULE);
136         final var ex = assertThrows(ReactorException.class, () -> build.buildEffective());
137         final var cause = assertInstanceOf(MissingSubstatementException.class, ex.getCause());
138         assertThat(cause.getMessage(), startsWith("yang-data requires at least one substatement [at "));
139     }
140
141     @Test
142     void testYangDataWithTwoTopLevelContainers() {
143         final var build = REACTOR.newBuild().addSources(FOO_INVALID_2_MODULE, IETF_RESTCONF_MODULE);
144         final var ex = assertThrows(ReactorException.class, () -> build.buildEffective());
145         final var cause = assertInstanceOf(InvalidSubstatementException.class, ex.getCause());
146         assertThat(cause.getMessage(),
147             startsWith("yang-data requires exactly one container data node definition, found ["));
148     }
149 }