Cleanup use of Guava library
[yangtools.git] / yang / yang-data-impl / src / test / java / org / opendaylight / yangtools / yang / data / impl / schema / tree / OrderedListTest.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
9 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
10
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertTrue;
13 import static org.junit.Assert.fail;
14
15 import com.google.common.collect.ImmutableMap;
16 import java.io.File;
17 import java.net.URI;
18 import java.util.Optional;
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.NodeIdentifier;
26 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
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.schema.Builders;
38 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
39 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 public class OrderedListTest {
44     private static final Logger LOG = LoggerFactory.getLogger(OrderedListTest.class);
45
46     private TipProducingDataTree inMemoryDataTree;
47     private SchemaContext context;
48
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;
58
59     @Before
60     public void setup() throws Exception {
61         final File resourceFile = new File(Bug4295Test.class.getResource("/ordered-list-modification-test.yang")
62                 .toURI());
63         context = YangParserTestUtils.parseYangFiles(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);
76     }
77
78     @Test
79     public void testsequentialModifications() throws DataValidationFailedException {
80         modification1();
81         modification2();
82         delete1();
83         delete2();
84         modification3();
85         modification4();
86     }
87
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();
94
95         ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
96                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
97                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
98                 .build();
99
100         YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
101
102         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
103         treeModification.write(path1, parentContainerNode);
104
105         OrderedMapNode childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
106                 new NodeIdentifier(childOrderedList))
107                 .withChild(createChildOrderedListEntry("chkval1", "chlfval1"))
108                 .withChild(createChildOrderedListEntry("chkval2", "chlfval2")).build();
109
110         YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
111                 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList);
112
113         treeModification.write(path2, childOrderedListNode);
114         treeModification.ready();
115         inMemoryDataTree.validate(treeModification);
116         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
117
118         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
119         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
120         assertTrue(readNode.isPresent());
121
122         readNode = snapshotAfterCommits.readNode(path2);
123         assertTrue(readNode.isPresent());
124     }
125
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();
132
133         ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
134                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
135                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
136                 .build();
137
138         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
139
140         YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
141         treeModification.merge(path1, parentContainerNode);
142
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();
148
149         YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
150                 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList);
151         treeModification.merge(path2, childOrderedListNode);
152
153         treeModification.ready();
154         inMemoryDataTree.validate(treeModification);
155         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
156
157         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
158         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
159         assertTrue(readNode.isPresent());
160
161         readNode = snapshotAfterCommits.readNode(path2);
162         assertTrue(readNode.isPresent());
163     }
164
165     public void modification3() throws DataValidationFailedException {
166         OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
167                 new NodeIdentifier(parentOrderedList))
168                 .withChild(createParentOrderedListEntry("pkval1", "plfval1")).build();
169
170         ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
171                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
172                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
173                 .build();
174
175         YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
176
177         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
178         treeModification.write(path1, parentContainerNode);
179
180         OrderedMapNode childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
181                 new NodeIdentifier(childOrderedList))
182                 .withChild(createChildOrderedListEntry("chkval1", "chlfval1new")).build();
183
184         YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
185                 .node(parentOrderedList)
186                 .node(createParentOrderedListEntryPath("pkval4")).node(childOrderedList);
187
188         treeModification.merge(path2, childOrderedListNode);
189
190         try {
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"));
198         }
199
200         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
201         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
202         assertTrue(readNode.isPresent());
203
204         readNode = snapshotAfterCommits.readNode(path2);
205         assertFalse(readNode.isPresent());
206     }
207
208     public void modification4() throws DataValidationFailedException {
209         DataTreeModification treeModification1 = inMemoryDataTree.takeSnapshot().newModification();
210         DataTreeModification treeModification2 = inMemoryDataTree.takeSnapshot().newModification();
211
212         OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
213             new NodeIdentifier(parentOrderedList)).withChild(createParentOrderedListEntry("pkval1", "plfval1"))
214                 .build();
215
216         OrderedMapNode parentOrderedListNode2 = Builders.orderedMapBuilder().withNodeIdentifier(
217             new NodeIdentifier(parentOrderedList)).withChild(createParentOrderedListEntry("pkval2", "plfval2"))
218                 .build();
219
220         ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
221                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
222                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
223                 .build();
224
225         ContainerNode parentContainerNode2 = Builders.containerBuilder().withNodeIdentifier(
226                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
227                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode2).build())
228                 .build();
229
230         YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer);
231
232         treeModification1.write(path, parentContainerNode);
233         treeModification2.write(path, parentContainerNode2);
234         treeModification1.ready();
235         treeModification2.ready();
236
237         inMemoryDataTree.validate(treeModification1);
238         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification1));
239
240         try {
241             inMemoryDataTree.validate(treeModification2);
242             fail("Exception should have been thrown.");
243             inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification2));
244         } catch (ConflictingModificationAppliedException ex) {
245             LOG.debug("ConflictingModificationAppliedException was thrown as expected: {}", ex);
246             assertTrue(ex.getMessage().contains("Node was replaced by other transaction"));
247         }
248
249         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
250         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
251         assertTrue(readNode.isPresent());
252     }
253
254     public void delete1() throws DataValidationFailedException {
255         YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer).node(childContainer)
256                 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList)
257                 .node(createChildOrderedListEntryPath("chkval1"));
258
259         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
260         treeModification.delete(path);
261         treeModification.ready();
262         inMemoryDataTree.validate(treeModification);
263         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
264
265         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
266         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
267         assertFalse(readNode.isPresent());
268     }
269
270     public void delete2() throws DataValidationFailedException {
271         YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer).node(childContainer)
272                 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2"));
273
274         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
275         treeModification.delete(path);
276         treeModification.ready();
277         inMemoryDataTree.validate(treeModification);
278         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
279
280         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
281         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
282         assertFalse(readNode.isPresent());
283     }
284
285     private MapEntryNode createParentOrderedListEntry(final String keyValue, final String leafValue) {
286         return Builders.mapEntryBuilder().withNodeIdentifier(new NodeIdentifierWithPredicates(parentOrderedList,
287                 parentKeyLeaf, keyValue))
288                 .withChild(Builders.leafBuilder().withNodeIdentifier(NodeIdentifier.create(parentOrdinaryLeaf))
289                     .withValue(leafValue).build()).build();
290     }
291
292     private MapEntryNode createChildOrderedListEntry(final String keyValue, final String leafValue) {
293         return Builders.mapEntryBuilder().withNodeIdentifier(new NodeIdentifierWithPredicates(childOrderedList,
294                 childKeyLeaf, keyValue))
295                 .withChild(Builders.leafBuilder().withNodeIdentifier(NodeIdentifier.create(childOrdinaryLeaf))
296                     .withValue(leafValue).build()).build();
297     }
298
299     private NodeIdentifierWithPredicates createParentOrderedListEntryPath(final String keyValue) {
300         ImmutableMap.Builder<QName, Object> builder = ImmutableMap.builder();
301         ImmutableMap<QName, Object> keys = builder.put(parentKeyLeaf, keyValue).build();
302         return new NodeIdentifierWithPredicates(parentOrderedList, keys);
303     }
304
305     private NodeIdentifierWithPredicates createChildOrderedListEntryPath(final String keyValue) {
306         ImmutableMap.Builder<QName, Object> builder = ImmutableMap.builder();
307         ImmutableMap<QName, Object> keys = builder.put(childKeyLeaf, keyValue).build();
308         return new NodeIdentifierWithPredicates(childOrderedList, keys);
309     }
310 }