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
9 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertTrue;
13 import static org.junit.Assert.fail;
15 import com.google.common.base.Optional;
16 import com.google.common.collect.ImmutableMap;
19 import org.junit.Before;
20 import org.junit.Test;
21 import org.opendaylight.yangtools.yang.common.QName;
22 import org.opendaylight.yangtools.yang.common.QNameModule;
23 import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
24 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
25 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
26 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
27 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
28 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
29 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
30 import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
31 import org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException;
32 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
33 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
34 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
35 import org.opendaylight.yangtools.yang.data.api.schema.tree.TipProducingDataTree;
36 import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
37 import org.opendaylight.yangtools.yang.data.impl.RetestUtils;
38 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
39 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
43 public class OrderedListTest {
44 private Logger LOG = LoggerFactory.getLogger(OrderedListTest.class);
46 private TipProducingDataTree inMemoryDataTree;
47 private SchemaContext context;
49 private QNameModule testModule;
50 private QName parentContainer;
51 private QName childContainer;
52 private QName parentOrderedList;
53 private QName childOrderedList;
54 private QName parentKeyLeaf;
55 private QName parentOrdinaryLeaf;
56 private QName childKeyLeaf;
57 private QName childOrdinaryLeaf;
60 public void setup() throws Exception {
61 final File resourceFile = new File(Bug4295Test.class.getResource("/ordered-list-modification-test.yang")
63 context = RetestUtils.parseYangSources(resourceFile);
64 testModule = QNameModule.create(new URI("ordered-list-modification-test"),
65 SimpleDateFormatUtil.getRevisionFormat().parse("1970-01-01"));
66 parentContainer = QName.create(testModule, "parent-container");
67 childContainer = QName.create(testModule, "child-container");
68 parentOrderedList = QName.create(testModule, "parent-ordered-list");
69 childOrderedList = QName.create(testModule, "child-ordered-list");
70 parentKeyLeaf = QName.create(testModule, "parent-key-leaf");
71 childKeyLeaf = QName.create(testModule, "child-key-leaf");
72 parentOrdinaryLeaf = QName.create(testModule, "parent-ordinary-leaf");
73 childOrdinaryLeaf = QName.create(testModule, "child-ordinary-leaf");
74 inMemoryDataTree = InMemoryDataTreeFactory.getInstance().create(TreeType.OPERATIONAL);
75 inMemoryDataTree.setSchemaContext(context);
79 public void testsequentialModifications() throws DataValidationFailedException {
88 public void modification1() throws DataValidationFailedException {
89 OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
90 new NodeIdentifier(parentOrderedList))
91 .withChild(createParentOrderedListEntry("pkval1", "plfval1"))
92 .withChild(createParentOrderedListEntry("pkval2", "plfval2"))
93 .withChild(createParentOrderedListEntry("pkval3", "plfval3")).build();
95 ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
96 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
97 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
100 YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
102 DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
103 treeModification.write(path1, parentContainerNode);
105 OrderedMapNode childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
106 new NodeIdentifier(childOrderedList))
107 .withChild(createChildOrderedListEntry("chkval1", "chlfval1"))
108 .withChild(createChildOrderedListEntry("chkval2", "chlfval2")).build();
110 YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
111 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList);
113 treeModification.write(path2, childOrderedListNode);
114 treeModification.ready();
115 inMemoryDataTree.validate(treeModification);
116 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
118 DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
119 Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
120 assertTrue(readNode.isPresent());
122 readNode = snapshotAfterCommits.readNode(path2);
123 assertTrue(readNode.isPresent());
126 public void modification2() throws DataValidationFailedException {
127 OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
128 new NodeIdentifier(parentOrderedList))
129 .withChild(createParentOrderedListEntry("pkval3", "plfval3updated"))
130 .withChild(createParentOrderedListEntry("pkval4", "plfval4"))
131 .withChild(createParentOrderedListEntry("pkval5", "plfval5")).build();
133 ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
134 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
135 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
138 DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
140 YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
141 treeModification.merge(path1, parentContainerNode);
143 OrderedMapNode childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
144 new NodeIdentifier(childOrderedList))
145 .withChild(createChildOrderedListEntry("chkval1", "chlfval1updated"))
146 .withChild(createChildOrderedListEntry("chkval2", "chlfval2updated"))
147 .withChild(createChildOrderedListEntry("chkval3", "chlfval3")).build();
149 YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer).node
150 (parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList);
151 treeModification.merge(path2, childOrderedListNode);
153 treeModification.ready();
154 inMemoryDataTree.validate(treeModification);
155 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
157 DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
158 Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
159 assertTrue(readNode.isPresent());
161 readNode = snapshotAfterCommits.readNode(path2);
162 assertTrue(readNode.isPresent());
165 public void modification3() throws DataValidationFailedException {
166 OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
167 new NodeIdentifier(parentOrderedList))
168 .withChild(createParentOrderedListEntry("pkval1", "plfval1")).build();
170 ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
171 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
172 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
175 YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
177 DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
178 treeModification.write(path1, parentContainerNode);
180 OrderedMapNode childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
181 new NodeIdentifier(childOrderedList))
182 .withChild(createChildOrderedListEntry("chkval1", "chlfval1new")).build();
184 YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer).node
186 .node(createParentOrderedListEntryPath("pkval4")).node(childOrderedList);
188 treeModification.merge(path2, childOrderedListNode);
191 treeModification.ready();
192 fail("Exception should have been thrown.");
193 inMemoryDataTree.validate(treeModification);
194 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
195 } catch (final IllegalArgumentException ex) {
196 LOG.debug("IllegalArgumentException was thrown as expected: {}", ex);
197 assertTrue(ex.getMessage().contains("Metadata not available for modification NodeModification"));
200 DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
201 Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
202 assertTrue(readNode.isPresent());
204 readNode = snapshotAfterCommits.readNode(path2);
205 assertFalse(readNode.isPresent());
208 public void modification4() throws DataValidationFailedException {
209 DataTreeModification treeModification1 = inMemoryDataTree.takeSnapshot().newModification();
210 DataTreeModification treeModification2 = inMemoryDataTree.takeSnapshot().newModification();
212 OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(new
213 NodeIdentifier(parentOrderedList)).withChild(createParentOrderedListEntry("pkval1",
216 OrderedMapNode parentOrderedListNode2 = Builders.orderedMapBuilder().withNodeIdentifier(new
217 NodeIdentifier(parentOrderedList)).withChild(createParentOrderedListEntry("pkval2",
220 ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
221 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
222 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build()).build();
224 ContainerNode parentContainerNode2 = Builders.containerBuilder().withNodeIdentifier(
225 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
226 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode2).build())
229 YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer);
231 treeModification1.write(path, parentContainerNode);
232 treeModification2.write(path, parentContainerNode2);
233 treeModification1.ready();
234 treeModification2.ready();
236 inMemoryDataTree.validate(treeModification1);
237 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification1));
240 inMemoryDataTree.validate(treeModification2);
241 fail("Exception should have been thrown.");
242 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification2));
243 } catch (ConflictingModificationAppliedException ex) {
244 LOG.debug("ConflictingModificationAppliedException was thrown as expected: {}", ex);
245 assertTrue(ex.getMessage().contains("Node was replaced by other transaction"));
248 DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
249 Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
250 assertTrue(readNode.isPresent());
253 public void delete1() throws DataValidationFailedException {
254 YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer).node(childContainer)
255 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList)
256 .node(createChildOrderedListEntryPath("chkval1"));
258 DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
259 treeModification.delete(path);
260 treeModification.ready();
261 inMemoryDataTree.validate(treeModification);
262 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
264 DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
265 Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
266 assertFalse(readNode.isPresent());
269 public void delete2() throws DataValidationFailedException {
270 YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer).node(childContainer)
271 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2"));
273 DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
274 treeModification.delete(path);
275 treeModification.ready();
276 inMemoryDataTree.validate(treeModification);
277 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
279 DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
280 Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
281 assertFalse(readNode.isPresent());
284 private MapEntryNode createParentOrderedListEntry(String keyValue, String leafValue) {
285 return Builders.mapEntryBuilder().withNodeIdentifier(new NodeIdentifierWithPredicates(parentOrderedList,
286 parentKeyLeaf, keyValue))
287 .withChild(Builders.leafBuilder().withNodeIdentifier(NodeIdentifier.create(parentOrdinaryLeaf)).withValue
288 (leafValue).build()).build();
291 private MapEntryNode createChildOrderedListEntry(String keyValue, String leafValue) {
292 return Builders.mapEntryBuilder().withNodeIdentifier(new NodeIdentifierWithPredicates(childOrderedList,
293 childKeyLeaf, keyValue))
294 .withChild(Builders.leafBuilder().withNodeIdentifier(NodeIdentifier.create(childOrdinaryLeaf)).withValue
295 (leafValue).build()).build();
298 private NodeIdentifierWithPredicates createParentOrderedListEntryPath(String keyValue) {
299 ImmutableMap.Builder<QName, Object> builder = ImmutableMap.builder();
300 ImmutableMap<QName, Object> keys = builder.put(parentKeyLeaf, keyValue).build();
301 return new NodeIdentifierWithPredicates(parentOrderedList, keys);
304 private NodeIdentifierWithPredicates createChildOrderedListEntryPath(String keyValue) {
305 ImmutableMap.Builder<QName, Object> builder = ImmutableMap.builder();
306 ImmutableMap<QName, Object> keys = builder.put(childKeyLeaf, keyValue).build();
307 return new NodeIdentifierWithPredicates(childOrderedList, keys);