2 * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.data.tree.impl;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertThrows;
13 import java.util.function.Consumer;
14 import org.junit.BeforeClass;
15 import org.junit.Test;
16 import org.opendaylight.yangtools.yang.common.QName;
17 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
19 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
20 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
21 import org.opendaylight.yangtools.yang.data.tree.api.DataTree;
22 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeConfiguration;
23 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeModification;
24 import org.opendaylight.yangtools.yang.data.tree.api.DataValidationFailedException;
25 import org.opendaylight.yangtools.yang.data.tree.impl.di.InMemoryDataTreeFactory;
26 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
27 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
29 public class YT1276Test {
30 private static final QName FOO = QName.create("foo", "foo");
31 private static final QName BAR = QName.create(FOO, "bar");
32 private static final QName BAZ = QName.create(FOO, "baz");
33 private static final QName XYZZY_LEAF = QName.create(FOO, "xyzzy-leaf");
34 private static final QName XYZZY_AUGMENT = QName.create(FOO, "xyzzy-augment");
35 private static final QName XYZZY_AUGMENT_CONT = QName.create(FOO, "xyzzy-augment-container");
36 private static final QName XYZZY_AUGMENT_CONT_INNER = QName.create(FOO, "xyzzy-augment-container-inner");
37 private static final QName XYZZY_AUGMENT_CONT_LEAF = QName.create(FOO, "xyzzy-augment-container-leaf");
38 private static final QName BAZ_AUG_CASE_MANDAT_LEAF = QName.create(FOO, "augmented-case-mandatory");
39 private static final QName BAZ_AUG_CASE_NON_MANDAT_LEAF = QName.create(FOO, "augmented-case-non-mandatory");
40 private static final QName NESTED_BAZ_CHOICE = QName.create(FOO, "nested-baz");
41 private static final QName NESTED_BAZ_XYZ_CASE_MANDATORY = QName.create(FOO, "nested-xyz-mandatory");
42 private static final QName NESTED_BAZ_XYZ_CASE_NON_MANDATORY = QName.create(FOO, "nested-xyz-non-mandatory");
44 private static EffectiveModelContext MODEL;
46 private final DataTree tree = new InMemoryDataTreeFactory()
47 .create(DataTreeConfiguration.DEFAULT_CONFIGURATION, MODEL);
50 public static void beforeClass() {
51 MODEL = YangParserTestUtils.parseYangResource("/yt1276.yang");
55 public void testFooWithBar() throws DataValidationFailedException {
56 applyOperation(mod -> {
57 mod.write(YangInstanceIdentifier.of(FOO), Builders.containerBuilder()
58 .withNodeIdentifier(new NodeIdentifier(FOO))
59 .withChild(ImmutableNodes.leafNode(BAR, "xyzzy"))
66 public void testFooWithBarLegacy() throws DataValidationFailedException {
67 applyOperation(mod -> {
68 mod.write(YangInstanceIdentifier.of(FOO), Builders.containerBuilder()
69 .withNodeIdentifier(new NodeIdentifier(FOO))
70 .withChild(ImmutableNodes.leafNode(BAR, "xyzzy"))
76 public void testFooWithoutBar() {
77 final IllegalArgumentException ex = assertFailsReady(mod -> {
78 mod.write(YangInstanceIdentifier.of(FOO), Builders.containerBuilder()
79 .withNodeIdentifier(new NodeIdentifier(FOO))
82 assertEquals("Node (foo)foo is missing mandatory descendant /(foo)bar", ex.getMessage());
86 public void testBarWithXyzzyWithSubtree() throws DataValidationFailedException {
87 applyOperation(mod -> {
88 mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
89 .withNodeIdentifier(new NodeIdentifier(BAR))
90 .withChild(Builders.choiceBuilder()
91 .withNodeIdentifier(new NodeIdentifier(BAZ))
92 .withChild(ImmutableNodes.leafNode(XYZZY_LEAF, "xyzzy"))
93 .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT, "xyzzy"))
94 .withChild(Builders.containerBuilder()
95 .withNodeIdentifier(new NodeIdentifier(XYZZY_AUGMENT_CONT))
96 .withChild(Builders.containerBuilder()
97 .withNodeIdentifier(new NodeIdentifier(XYZZY_AUGMENT_CONT_INNER))
98 .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT_CONT_LEAF, "aug-cont-leaf"))
107 public void testBazWithAugmentedCaseWithMandatoryLeaf() throws DataValidationFailedException {
108 applyOperation(mod -> {
109 mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
110 .withNodeIdentifier(new NodeIdentifier(BAR))
111 .withChild(Builders.choiceBuilder()
112 .withNodeIdentifier(new NodeIdentifier(BAZ))
113 .withChild(ImmutableNodes.leafNode(BAZ_AUG_CASE_MANDAT_LEAF, "augmentedCaseMandatory"))
114 .withChild(ImmutableNodes.leafNode(BAZ_AUG_CASE_NON_MANDAT_LEAF, "augmentedCaseNonMandatory"))
120 @Test(expected = IllegalArgumentException.class)
121 public void testBazWithAugmentedCaseWithoutMandatoryLeaf() throws DataValidationFailedException {
122 applyOperation(mod -> {
123 mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
124 .withNodeIdentifier(new NodeIdentifier(BAR))
125 .withChild(Builders.choiceBuilder()
126 .withNodeIdentifier(new NodeIdentifier(BAZ))
127 .withChild(ImmutableNodes.leafNode(BAZ_AUG_CASE_NON_MANDAT_LEAF, "augmentedCaseNonMandatory"))
134 public void testWithAugmentedNestedBazWithMandatoryLeaf() throws DataValidationFailedException {
135 applyOperation(mod -> {
136 mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
137 .withNodeIdentifier(new NodeIdentifier(BAR))
138 .withChild(Builders.choiceBuilder()
139 .withNodeIdentifier(new NodeIdentifier(BAZ))
140 .withChild(Builders.choiceBuilder()
141 .withNodeIdentifier(new NodeIdentifier(NESTED_BAZ_CHOICE))
142 .withChild(ImmutableNodes.leafNode(NESTED_BAZ_XYZ_CASE_MANDATORY, "nestedMandatory"))
143 .withChild(ImmutableNodes.leafNode(NESTED_BAZ_XYZ_CASE_NON_MANDATORY, "nestedNonMandatory"))
150 @Test(expected = IllegalArgumentException.class)
151 public void testWithAugmentedNestedBazWithhoutMandatoryLeaf() throws DataValidationFailedException {
152 applyOperation(mod -> {
153 mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
154 .withNodeIdentifier(new NodeIdentifier(BAR))
155 .withChild(Builders.choiceBuilder()
156 .withNodeIdentifier(new NodeIdentifier(BAZ))
157 .withChild(Builders.choiceBuilder()
158 .withNodeIdentifier(new NodeIdentifier(NESTED_BAZ_CHOICE))
159 .withChild(ImmutableNodes.leafNode(NESTED_BAZ_XYZ_CASE_NON_MANDATORY, "nestedNonMandatory"))
168 public void testBarWithXyzzyLegacy() throws DataValidationFailedException {
169 applyOperation(mod -> {
170 mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
171 .withNodeIdentifier(new NodeIdentifier(BAR))
172 .withChild(Builders.choiceBuilder()
173 .withNodeIdentifier(new NodeIdentifier(BAZ))
174 .withChild(ImmutableNodes.leafNode(XYZZY_LEAF, "xyzzy"))
175 .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT, "xyzzy"))
176 .withChild(Builders.containerBuilder()
177 .withNodeIdentifier(NodeIdentifier.create(XYZZY_AUGMENT_CONT))
178 .withChild(Builders.containerBuilder()
179 .withNodeIdentifier(NodeIdentifier.create(XYZZY_AUGMENT_CONT_INNER))
180 .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT_CONT_LEAF, "aug-cont-leaf"))
189 public void testBarWithoutXyzzyLeaf() {
190 final IllegalArgumentException ex = assertFailsReady(mod -> {
191 mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
192 .withNodeIdentifier(new NodeIdentifier(BAR))
193 .withChild(Builders.choiceBuilder()
194 .withNodeIdentifier(new NodeIdentifier(BAZ))
195 .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT, "xyzzy"))
196 .withChild(Builders.containerBuilder()
197 .withNodeIdentifier(NodeIdentifier.create(XYZZY_AUGMENT_CONT))
198 .withChild(Builders.containerBuilder()
199 .withNodeIdentifier(NodeIdentifier.create(XYZZY_AUGMENT_CONT_INNER))
200 .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT_CONT_LEAF, "aug-cont-leaf"))
207 "Node (foo)baz is missing mandatory descendant /(foo)xyzzy-leaf",
212 public void testBarWithoutXyzzyAugment() {
213 final IllegalArgumentException ex = assertFailsReady(mod -> {
214 mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
215 .withNodeIdentifier(new NodeIdentifier(BAR))
216 .withChild(Builders.choiceBuilder()
217 .withNodeIdentifier(new NodeIdentifier(BAZ))
218 .withChild(ImmutableNodes.leafNode(XYZZY_LEAF, "xyzzy"))
222 assertEquals("Node (foo)baz is missing mandatory descendant /(foo)xyzzy-augment", ex.getMessage());
226 private IllegalArgumentException assertFailsReady(final Consumer<DataTreeModification> operation) {
227 return assertThrows(IllegalArgumentException.class, () -> applyOperation(operation));
230 private void applyOperation(final Consumer<DataTreeModification> operation)
231 throws DataValidationFailedException {
232 final DataTreeModification mod = tree.takeSnapshot().newModification();
233 operation.accept(mod);
235 tree.commit(tree.prepare(mod));