Use Optional.isEmpty()
[yangtools.git] / parser / yang-parser-rfc7950 / src / test / java / org / opendaylight / yangtools / yang / stmt / AugmentTest.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.yangtools.yang.stmt;
9
10 import static org.junit.jupiter.api.Assertions.assertEquals;
11 import static org.junit.jupiter.api.Assertions.assertFalse;
12 import static org.junit.jupiter.api.Assertions.assertNotNull;
13 import static org.junit.jupiter.api.Assertions.assertTrue;
14
15 import org.junit.jupiter.api.BeforeAll;
16 import org.junit.jupiter.api.Test;
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.common.QNameModule;
19 import org.opendaylight.yangtools.yang.common.Revision;
20 import org.opendaylight.yangtools.yang.common.XMLNamespace;
21 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
22 import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
23 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
24 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
25 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
26 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
27 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
28 import org.opendaylight.yangtools.yang.model.api.InputSchemaNode;
29 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
30 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
31 import org.opendaylight.yangtools.yang.model.api.Module;
32 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
33 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
34 import org.opendaylight.yangtools.yang.model.api.type.TypeDefinitions;
35
36 class AugmentTest extends AbstractYangTest {
37     private static final QNameModule FOO = QNameModule.create(
38         XMLNamespace.of("urn:opendaylight.foo"), Revision.of("2013-10-13"));
39     private static final QNameModule BAR = QNameModule.create(
40         XMLNamespace.of("urn:opendaylight.bar"), Revision.of("2013-10-14"));
41     private static final QNameModule BAZ = QNameModule.create(
42         XMLNamespace.of("urn:opendaylight.baz"), Revision.of("2013-10-15"));
43
44     private static final QName Q0 = QName.create(BAR, "interfaces");
45     private static final QName Q1 = QName.create(BAR, "ifEntry");
46     private static final QName Q2 = QName.create(BAZ, "augment-holder");
47
48     private static EffectiveModelContext AUGMENT_IN_AUGMENT;
49
50     @BeforeAll
51     static void beforeClass() throws Exception {
52         AUGMENT_IN_AUGMENT = assertEffectiveModelDir("/augment-test/augment-in-augment");
53     }
54
55     @Test
56     void testAugmentParsing() {
57         // foo.yang
58         final Module module1 = AUGMENT_IN_AUGMENT.findModules("foo").iterator().next();
59         var augmentations = module1.getAugmentations();
60         assertEquals(1, augmentations.size());
61         final AugmentationSchemaNode augment = augmentations.iterator().next();
62         assertNotNull(augment);
63
64         assertEquals(Absolute.of(Q0, Q1, Q2), augment.getTargetPath());
65
66         final var augmentChildren = augment.getChildNodes();
67         assertEquals(4, augmentChildren.size());
68         for (final DataSchemaNode dsn : augmentChildren) {
69             checkIsAugmenting(dsn, false);
70         }
71
72         final LeafSchemaNode ds0ChannelNumber = (LeafSchemaNode) augment.getDataChildByName(QName.create(
73             module1.getQNameModule(), "ds0ChannelNumber"));
74         final LeafSchemaNode interfaceId = (LeafSchemaNode) augment.getDataChildByName(QName.create(
75             module1.getQNameModule(), "interface-id"));
76         final ContainerSchemaNode schemas = (ContainerSchemaNode) augment.getDataChildByName(QName.create(
77             module1.getQNameModule(), "schemas"));
78         final ChoiceSchemaNode odl = (ChoiceSchemaNode) augment.getDataChildByName(QName.create(
79             module1.getQNameModule(), "odl"));
80
81         assertNotNull(ds0ChannelNumber);
82         assertNotNull(interfaceId);
83         assertNotNull(schemas);
84         assertNotNull(odl);
85
86         // leaf ds0ChannelNumber
87         assertEquals(QName.create(FOO, "ds0ChannelNumber"), ds0ChannelNumber.getQName());
88         assertFalse(ds0ChannelNumber.isAugmenting());
89         // type of leaf ds0ChannelNumber
90         assertEquals(TypeDefinitions.STRING, ds0ChannelNumber.getType().getQName());
91
92         // leaf interface-id
93         assertEquals(QName.create(FOO, "interface-id"), interfaceId.getQName());
94         assertFalse(interfaceId.isAugmenting());
95
96         // container schemas
97         assertEquals(QName.create(FOO, "schemas"), schemas.getQName());
98         assertFalse(schemas.isAugmenting());
99
100         // choice odl
101         assertEquals(QName.create(FOO, "odl"), odl.getQName());
102         assertFalse(odl.isAugmenting());
103
104         // baz.yang
105         final Module module3 = AUGMENT_IN_AUGMENT.findModules("baz").iterator().next();
106         augmentations = module3.getAugmentations();
107         assertEquals(3, augmentations.size());
108         AugmentationSchemaNode augment1 = null;
109         AugmentationSchemaNode augment2 = null;
110         AugmentationSchemaNode augment3 = null;
111         for (final AugmentationSchemaNode as : augmentations) {
112             if (as.getWhenCondition().isEmpty()) {
113                 augment3 = as;
114             } else if ("br:ifType='ds0'".equals(as.getWhenCondition().orElseThrow().toString())) {
115                 augment1 = as;
116             } else if ("br:ifType='ds2'".equals(as.getWhenCondition().orElseThrow().toString())) {
117                 augment2 = as;
118             }
119         }
120         assertNotNull(augment1);
121         assertNotNull(augment2);
122         assertNotNull(augment3);
123
124         assertEquals(1, augment1.getChildNodes().size());
125         final ContainerSchemaNode augmentHolder = (ContainerSchemaNode) augment1.getDataChildByName(QName.create(
126             module3.getQNameModule(), "augment-holder"));
127         assertNotNull(augmentHolder);
128
129         assertEquals(1, augment2.getChildNodes().size());
130         final ContainerSchemaNode augmentHolder2 = (ContainerSchemaNode) augment2.getDataChildByName(QName.create(
131             module3.getQNameModule(), "augment-holder2"));
132         assertNotNull(augmentHolder2);
133
134         assertEquals(1, augment3.getChildNodes().size());
135         final CaseSchemaNode pause = (CaseSchemaNode) augment3.getDataChildByName(QName.create(
136             module3.getQNameModule(), "pause"));
137         assertNotNull(pause);
138     }
139
140     @Test
141     void testAugmentResolving() {
142         final Module module2 = AUGMENT_IN_AUGMENT.findModules("bar").iterator().next();
143         final ContainerSchemaNode interfaces = (ContainerSchemaNode) module2.getDataChildByName(QName.create(
144             module2.getQNameModule(), "interfaces"));
145         final ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName(QName.create(
146             module2.getQNameModule(), "ifEntry"));
147
148         // baz.yang
149         // augment "/br:interfaces/br:ifEntry" {
150         final ContainerSchemaNode augmentHolder = (ContainerSchemaNode) ifEntry.getDataChildByName(QName.create(BAZ,
151             "augment-holder"));
152         checkIsAugmenting(augmentHolder, true);
153         assertEquals(Q2, augmentHolder.getQName());
154
155         // foo.yang
156         // augment "/br:interfaces/br:ifEntry/bz:augment-holder"
157         final LeafSchemaNode ds0ChannelNumber = (LeafSchemaNode) augmentHolder.getDataChildByName(QName.create(FOO,
158             "ds0ChannelNumber"));
159         final LeafSchemaNode interfaceId = (LeafSchemaNode) augmentHolder.getDataChildByName(QName.create(FOO,
160             "interface-id"));
161         final ContainerSchemaNode schemas = (ContainerSchemaNode) augmentHolder.getDataChildByName(QName.create(FOO,
162             "schemas"));
163         final ChoiceSchemaNode odl = (ChoiceSchemaNode) augmentHolder.getDataChildByName(QName.create(FOO, "odl"));
164
165         assertNotNull(ds0ChannelNumber);
166         assertNotNull(interfaceId);
167         assertNotNull(schemas);
168         assertNotNull(odl);
169
170         // leaf ds0ChannelNumber
171         assertEquals(QName.create(FOO, "ds0ChannelNumber"), ds0ChannelNumber.getQName());
172
173         // leaf interface-id
174         assertEquals(QName.create(FOO, "interface-id"), interfaceId.getQName());
175
176         // container schemas
177         assertEquals(QName.create(FOO, "schemas"), schemas.getQName());
178
179         // choice odl
180         assertEquals(QName.create(FOO, "odl"), odl.getQName());
181     }
182
183     @Test
184     void testAugmentedChoice() {
185         final Module module2 = AUGMENT_IN_AUGMENT.findModules("bar").iterator().next();
186         final ContainerSchemaNode interfaces = (ContainerSchemaNode) module2.getDataChildByName(QName.create(
187             module2.getQNameModule(), "interfaces"));
188         final ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName(QName.create(
189             module2.getQNameModule(), "ifEntry"));
190         final ContainerSchemaNode augmentedHolder = (ContainerSchemaNode) ifEntry.getDataChildByName(QName.create(
191             BAZ, "augment-holder"));
192         checkIsAugmenting(augmentedHolder, true);
193
194         // foo.yang
195         // augment "/br:interfaces/br:ifEntry/bz:augment-holder"
196         final ChoiceSchemaNode odl = (ChoiceSchemaNode) augmentedHolder.getDataChildByName(QName.create(FOO, "odl"));
197         assertNotNull(odl);
198         final var cases = odl.getCases();
199         assertEquals(4, cases.size());
200
201         CaseSchemaNode id = null;
202         CaseSchemaNode node1 = null;
203         CaseSchemaNode node2 = null;
204         CaseSchemaNode node3 = null;
205
206         for (final CaseSchemaNode ccn : cases) {
207             if ("id".equals(ccn.getQName().getLocalName())) {
208                 id = ccn;
209             } else if ("node1".equals(ccn.getQName().getLocalName())) {
210                 node1 = ccn;
211             } else if ("node2".equals(ccn.getQName().getLocalName())) {
212                 node2 = ccn;
213             } else if ("node3".equals(ccn.getQName().getLocalName())) {
214                 node3 = ccn;
215             }
216         }
217
218         assertNotNull(id);
219         assertNotNull(node1);
220         assertNotNull(node2);
221         assertNotNull(node3);
222
223         // case id
224         assertEquals(QName.create(FOO, "id"), id.getQName());
225         final var idChildren = id.getChildNodes();
226         assertEquals(1, idChildren.size());
227
228         // case node1
229         assertEquals(QName.create(FOO, "node1"), node1.getQName());
230         final var node1Children = node1.getChildNodes();
231         assertTrue(node1Children.isEmpty());
232
233         // case node2
234         assertEquals(QName.create(FOO, "node2"), node2.getQName());
235         final var node2Children = node2.getChildNodes();
236         assertTrue(node2Children.isEmpty());
237
238         // case node3
239         assertEquals(QName.create(FOO, "node3"), node3.getQName());
240         final var node3Children = node3.getChildNodes();
241         assertEquals(1, node3Children.size());
242
243         // test cases
244         // case id child
245         final LeafSchemaNode caseIdChild = (LeafSchemaNode) idChildren.iterator().next();
246         assertNotNull(caseIdChild);
247         assertEquals(QName.create(FOO, "id"), caseIdChild.getQName());
248
249         // case node3 child
250         final ContainerSchemaNode caseNode3Child = (ContainerSchemaNode) node3Children.iterator().next();
251         assertNotNull(caseNode3Child);
252         assertEquals(QName.create(FOO, "node3"), caseNode3Child.getQName());
253     }
254
255     @Test
256     void testAugmentRpc() throws Exception {
257         final EffectiveModelContext context = assertEffectiveModelDir("/augment-test/rpc");
258         final XMLNamespace NS_BAR = XMLNamespace.of("urn:opendaylight:bar");
259         final XMLNamespace NS_FOO = XMLNamespace.of("urn:opendaylight:foo");
260         final Revision revision = Revision.of("2013-10-11");
261         final Module bar = context.findModules("bar").iterator().next();
262         final var rpcs = bar.getRpcs();
263         assertEquals(2, rpcs.size());
264
265         RpcDefinition submit = null;
266         for (final RpcDefinition rpc : rpcs) {
267             if ("submit".equals(rpc.getQName().getLocalName())) {
268                 submit = rpc;
269                 break;
270             }
271         }
272         assertNotNull(submit);
273
274         final QName submitQName = QName.create(NS_BAR, revision, "submit");
275         assertEquals(submitQName, submit.getQName());
276         final InputSchemaNode input = submit.getInput();
277         final QName inputQName = QName.create(NS_BAR, revision, "input");
278         assertEquals(inputQName, input.getQName());
279         final ChoiceSchemaNode arguments = (ChoiceSchemaNode) input.getDataChildByName(QName.create(NS_BAR, revision,
280             "arguments"));
281         final QName argumentsQName = QName.create(NS_BAR, revision, "arguments");
282         assertEquals(argumentsQName, arguments.getQName());
283         assertFalse(arguments.isAugmenting());
284         final var cases = arguments.getCases();
285         assertEquals(3, cases.size());
286
287         CaseSchemaNode attach = null;
288         CaseSchemaNode create = null;
289         CaseSchemaNode destroy = null;
290         for (final CaseSchemaNode child : cases) {
291             if ("attach".equals(child.getQName().getLocalName())) {
292                 attach = child;
293             } else if ("create".equals(child.getQName().getLocalName())) {
294                 create = child;
295             } else if ("destroy".equals(child.getQName().getLocalName())) {
296                 destroy = child;
297             }
298         }
299         assertNotNull(attach);
300         assertNotNull(create);
301         assertNotNull(destroy);
302
303         assertTrue(attach.isAugmenting());
304         assertTrue(create.isAugmenting());
305         assertTrue(destroy.isAugmenting());
306
307         // case attach
308         assertEquals(QName.create(NS_FOO, revision, "attach"), attach.getQName());
309         final var attachChildren = attach.getChildNodes();
310         assertEquals(1, attachChildren.size());
311
312         // case create
313         assertEquals(QName.create(NS_FOO, revision, "create"), create.getQName());
314         final var createChildren = create.getChildNodes();
315         assertEquals(1, createChildren.size());
316
317         // case attach
318         assertEquals(QName.create(NS_FOO, revision, "destroy"), destroy.getQName());
319         final var destroyChildren = destroy.getChildNodes();
320         assertEquals(1, destroyChildren.size());
321     }
322
323     @Test
324     void testAugmentInUsesResolving() throws Exception {
325         final EffectiveModelContext context = assertEffectiveModelDir("/augment-test/augment-in-uses");
326         assertEquals(1, context.getModules().size());
327
328         final Module test = context.getModules().iterator().next();
329         final DataNodeContainer links = (DataNodeContainer) test.getDataChildByName(QName.create(test.getQNameModule(),
330             "links"));
331         final DataNodeContainer link = (DataNodeContainer) links.getDataChildByName(QName.create(test.getQNameModule(),
332             "link"));
333         final DataNodeContainer nodes = (DataNodeContainer) link.getDataChildByName(QName.create(test.getQNameModule(),
334             "nodes"));
335         final ContainerSchemaNode node = (ContainerSchemaNode) nodes.getDataChildByName(QName.create(
336             test.getQNameModule(), "node"));
337         final var augments = node.getAvailableAugmentations();
338         assertEquals(1, augments.size());
339         assertEquals(1, node.getChildNodes().size());
340         final LeafSchemaNode id = (LeafSchemaNode) node.getDataChildByName(QName.create(test.getQNameModule(), "id"));
341         assertTrue(id.isAugmenting());
342     }
343
344     /**
345      * Test if node has augmenting flag set to expected value. In case this is  DataNodeContainer/ChoiceNode, check its
346      * child nodes/case nodes too.
347      *
348      * @param node node to check
349      * @param expected expected value
350      */
351     private static void checkIsAugmenting(final DataSchemaNode node, final boolean expected) {
352         assertEquals(expected, node.isAugmenting());
353         if (node instanceof DataNodeContainer) {
354             for (DataSchemaNode child : ((DataNodeContainer) node).getChildNodes()) {
355                 checkIsAugmenting(child, expected);
356             }
357         } else if (node instanceof ChoiceSchemaNode) {
358             for (CaseSchemaNode caseNode : ((ChoiceSchemaNode) node).getCases()) {
359                 checkIsAugmenting(caseNode, expected);
360             }
361         }
362     }
363 }