2 * Copyright (c) 2016 Cisco Systems, Inc. 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.impl.schema.tree;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.fail;
14 import com.google.common.collect.ImmutableMap;
15 import org.junit.Before;
16 import org.junit.Test;
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
21 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
22 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
23 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
24 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
25 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
26 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
27 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
28 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
29 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
30 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
31 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
33 public class Bug5968Test {
34 private static final String NS = "foo";
35 private static final String REV = "2016-07-28";
36 private static final QName ROOT = QName.create(NS, REV, "root");
37 private static final QName MY_LIST = QName.create(NS, REV, "my-list");
38 private static final QName LIST_ID = QName.create(NS, REV, "list-id");
39 private static final QName MANDATORY_LEAF = QName.create(NS, REV, "mandatory-leaf");
40 private static final QName COMMON_LEAF = QName.create(NS, REV, "common-leaf");
41 private SchemaContext schemaContext;
44 public void init() throws ReactorException {
45 this.schemaContext = TestModel.createTestContext("/bug5968/foo.yang");
46 assertNotNull("Schema context must not be null.", this.schemaContext);
49 private static InMemoryDataTree initDataTree(final SchemaContext schemaContext, final boolean withMapNode)
50 throws DataValidationFailedException {
51 final InMemoryDataTree inMemoryDataTree = (InMemoryDataTree) InMemoryDataTreeFactory.getInstance().create(
52 DataTreeConfiguration.DEFAULT_CONFIGURATION);
53 inMemoryDataTree.setSchemaContext(schemaContext);
55 final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> root = Builders.containerBuilder()
56 .withNodeIdentifier(new NodeIdentifier(ROOT));
57 final InMemoryDataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
58 modificationTree.write(
59 YangInstanceIdentifier.of(ROOT),
60 withMapNode ? root.withChild(
61 Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(MY_LIST)).build()).build() : root
63 modificationTree.ready();
65 inMemoryDataTree.validate(modificationTree);
66 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
67 inMemoryDataTree.commit(prepare);
69 return inMemoryDataTree;
72 private static InMemoryDataTree emptyDataTree(final SchemaContext schemaContext)
73 throws DataValidationFailedException {
74 final InMemoryDataTree inMemoryDataTree = (InMemoryDataTree) InMemoryDataTreeFactory.getInstance().create(
75 DataTreeConfiguration.DEFAULT_CONFIGURATION);
76 inMemoryDataTree.setSchemaContext(schemaContext);
78 return inMemoryDataTree;
82 public void writeInvalidContainerTest() throws ReactorException, DataValidationFailedException {
83 final InMemoryDataTree inMemoryDataTree = emptyDataTree(schemaContext);
85 final MapNode myList = createMap(true);
86 final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> root = Builders.containerBuilder()
87 .withNodeIdentifier(new NodeIdentifier(ROOT)).withChild(myList);
89 final InMemoryDataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
90 modificationTree.write(YangInstanceIdentifier.of(ROOT), root.build());
93 modificationTree.ready();
94 inMemoryDataTree.validate(modificationTree);
95 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
96 inMemoryDataTree.commit(prepare);
97 fail("Should fail due to missing mandatory leaf.");
98 } catch (final IllegalArgumentException e) {
100 "Node (foo?revision=2016-07-28)my-list[{(foo?revision=2016-07-28)list-id=1}] is missing mandatory "
101 + "descendant /(foo?revision=2016-07-28)mandatory-leaf", e.getMessage());
106 public void writeInvalidMapTest() throws ReactorException, DataValidationFailedException {
107 final InMemoryDataTree inMemoryDataTree = emptyDataTree(schemaContext);
108 final InMemoryDataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
109 writeMap(modificationTree, true);
112 modificationTree.ready();
113 inMemoryDataTree.validate(modificationTree);
114 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
115 inMemoryDataTree.commit(prepare);
116 fail("Should fail due to missing mandatory leaf.");
117 } catch (final IllegalArgumentException e) {
119 "Node (foo?revision=2016-07-28)my-list[{(foo?revision=2016-07-28)list-id=1}] is missing mandatory "
120 + "descendant /(foo?revision=2016-07-28)mandatory-leaf", e.getMessage());
125 public void writeInvalidMapEntryTest() throws ReactorException, DataValidationFailedException {
126 final InMemoryDataTree inMemoryDataTree = initDataTree(schemaContext, true);
127 final InMemoryDataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
129 writeMapEntry(modificationTree, "1", null, "common-value");
132 modificationTree.ready();
133 inMemoryDataTree.validate(modificationTree);
134 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
135 inMemoryDataTree.commit(prepare);
136 fail("Should fail due to missing mandatory leaf.");
137 } catch (final IllegalArgumentException e) {
139 "Node (foo?revision=2016-07-28)my-list[{(foo?revision=2016-07-28)list-id=1}] is missing mandatory "
140 + "descendant /(foo?revision=2016-07-28)mandatory-leaf", e.getMessage());
144 private static void writeMap(final InMemoryDataTreeModification modificationTree, final boolean mandatoryDataMissing)
145 throws DataValidationFailedException {
146 final MapNode myList = createMap(mandatoryDataMissing);
147 modificationTree.write(YangInstanceIdentifier.of(ROOT).node(MY_LIST), myList);
150 private static MapNode createMap(final boolean mandatoryDataMissing) throws DataValidationFailedException {
153 .withNodeIdentifier(new NodeIdentifier(MY_LIST))
155 mandatoryDataMissing ? createMapEntry("1", "common-value") : createMapEntry("1",
156 "mandatory-value", "common-value")).build();
159 private static void writeMapEntry(final InMemoryDataTreeModification modificationTree, final Object listIdValue,
160 final Object mandatoryLeafValue, final Object commonLeafValue) throws DataValidationFailedException {
161 final MapEntryNode taskEntryNode = mandatoryLeafValue == null ? createMapEntry(listIdValue, commonLeafValue)
162 : createMapEntry(listIdValue, mandatoryLeafValue, commonLeafValue);
164 modificationTree.write(
165 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
166 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, listIdValue))),
170 private static MapEntryNode createMapEntry(final Object listIdValue, final Object mandatoryLeafValue,
171 final Object commonLeafValue) throws DataValidationFailedException {
172 return Builders.mapEntryBuilder()
173 .withNodeIdentifier(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, listIdValue)))
174 .withChild(ImmutableNodes.leafNode(LIST_ID, listIdValue))
175 .withChild(ImmutableNodes.leafNode(MANDATORY_LEAF, mandatoryLeafValue))
176 .withChild(ImmutableNodes.leafNode(COMMON_LEAF, commonLeafValue)).build();
179 private static MapEntryNode createMapEntry(final Object listIdValue, final Object commonLeafValue)
180 throws DataValidationFailedException {
181 return Builders.mapEntryBuilder()
182 .withNodeIdentifier(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, listIdValue)))
183 .withChild(ImmutableNodes.leafNode(LIST_ID, listIdValue))
184 .withChild(ImmutableNodes.leafNode(COMMON_LEAF, commonLeafValue)).build();
188 public void writeValidContainerTest() throws ReactorException, DataValidationFailedException {
189 final InMemoryDataTree inMemoryDataTree = emptyDataTree(schemaContext);
191 final MapNode myList = createMap(false);
192 final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> root = Builders.containerBuilder()
193 .withNodeIdentifier(new NodeIdentifier(ROOT)).withChild(myList);
195 final InMemoryDataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
196 modificationTree.write(YangInstanceIdentifier.of(ROOT), root.build());
197 modificationTree.ready();
198 inMemoryDataTree.validate(modificationTree);
199 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
200 inMemoryDataTree.commit(prepare);
204 public void writeValidMapTest() throws ReactorException, DataValidationFailedException {
205 final InMemoryDataTree inMemoryDataTree = emptyDataTree(schemaContext);
206 final InMemoryDataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
207 writeMap(modificationTree, false);
209 modificationTree.ready();
210 inMemoryDataTree.validate(modificationTree);
211 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
212 inMemoryDataTree.commit(prepare);
216 public void writeValidMapEntryTest() throws ReactorException, DataValidationFailedException {
217 final InMemoryDataTree inMemoryDataTree = initDataTree(schemaContext, true);
218 final InMemoryDataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
220 writeMapEntry(modificationTree, "1", "mandatory-value", "common-value");
222 modificationTree.ready();
223 inMemoryDataTree.validate(modificationTree);
224 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
225 inMemoryDataTree.commit(prepare);