Migrate yang-data-tree-ri to JUnit5
[yangtools.git] / data / yang-data-tree-ri / src / test / java / org / opendaylight / yangtools / yang / data / tree / impl / 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 package org.opendaylight.yangtools.yang.data.tree.impl;
9
10 import static org.junit.jupiter.api.Assertions.assertFalse;
11 import static org.junit.jupiter.api.Assertions.assertTrue;
12 import static org.junit.jupiter.api.Assertions.fail;
13
14 import com.google.common.collect.ImmutableMap;
15 import org.junit.jupiter.api.BeforeEach;
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.XMLNamespace;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
23 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
24 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
25 import org.opendaylight.yangtools.yang.data.tree.api.ConflictingModificationAppliedException;
26 import org.opendaylight.yangtools.yang.data.tree.api.DataTree;
27 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeConfiguration;
28 import org.opendaylight.yangtools.yang.data.tree.api.DataValidationFailedException;
29 import org.opendaylight.yangtools.yang.data.tree.impl.di.InMemoryDataTreeFactory;
30 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 class OrderedListTest {
35     private static final Logger LOG = LoggerFactory.getLogger(OrderedListTest.class);
36
37     private DataTree inMemoryDataTree;
38
39     private QNameModule testModule;
40     private QName parentContainer;
41     private QName childContainer;
42     private QName parentOrderedList;
43     private QName childOrderedList;
44     private QName parentKeyLeaf;
45     private QName parentOrdinaryLeaf;
46     private QName childKeyLeaf;
47     private QName childOrdinaryLeaf;
48
49     @BeforeEach
50     void setup() {
51         testModule = QNameModule.create(XMLNamespace.of("ordered-list-modification-test"));
52         parentContainer = QName.create(testModule, "parent-container");
53         childContainer = QName.create(testModule, "child-container");
54         parentOrderedList = QName.create(testModule, "parent-ordered-list");
55         childOrderedList = QName.create(testModule, "child-ordered-list");
56         parentKeyLeaf = QName.create(testModule, "parent-key-leaf");
57         childKeyLeaf = QName.create(testModule, "child-key-leaf");
58         parentOrdinaryLeaf = QName.create(testModule, "parent-ordinary-leaf");
59         childOrdinaryLeaf = QName.create(testModule, "child-ordinary-leaf");
60         inMemoryDataTree = new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_OPERATIONAL,
61             YangParserTestUtils.parseYang("""
62                 module ordered-list-modification-test {
63                   namespace "ordered-list-modification-test";
64                   prefix "olmt";
65
66                   container parent-container {
67                     container child-container {
68                       list parent-ordered-list {
69                         ordered-by user;
70                         key "parent-key-leaf";
71
72                         leaf parent-key-leaf {
73                           type string;
74                         }
75                         leaf parent-ordinary-leaf {
76                           type string;
77                         }
78
79                         list child-ordered-list {
80                           ordered-by user;
81                           key "child-key-leaf";
82
83                           leaf child-key-leaf {
84                             type string;
85                           }
86                           leaf child-ordinary-leaf {
87                             type string;
88                           }
89                         }
90                       }
91                     }
92                   }
93                 }"""));
94     }
95
96     @Test
97     void testsequentialModifications() throws DataValidationFailedException {
98         modification1();
99         modification2();
100         delete1();
101         delete2();
102         modification3();
103         modification4();
104     }
105
106     public void modification1() throws DataValidationFailedException {
107         final var parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
108                 new NodeIdentifier(parentOrderedList))
109                 .withChild(createParentOrderedListEntry("pkval1", "plfval1"))
110                 .withChild(createParentOrderedListEntry("pkval2", "plfval2"))
111                 .withChild(createParentOrderedListEntry("pkval3", "plfval3")).build();
112
113         final var parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
114                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
115                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
116                 .build();
117
118         final var path1 = YangInstanceIdentifier.of(parentContainer);
119
120         final var treeModification = inMemoryDataTree.takeSnapshot().newModification();
121         treeModification.write(path1, parentContainerNode);
122
123         final var childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
124                 new NodeIdentifier(childOrderedList))
125                 .withChild(createChildOrderedListEntry("chkval1", "chlfval1"))
126                 .withChild(createChildOrderedListEntry("chkval2", "chlfval2")).build();
127
128         final var path2 = YangInstanceIdentifier.of(parentContainer, childContainer, parentOrderedList)
129             .node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList);
130
131         treeModification.write(path2, childOrderedListNode);
132         treeModification.ready();
133         inMemoryDataTree.validate(treeModification);
134         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
135
136         final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
137         var readNode = snapshotAfterCommits.readNode(path1);
138         assertTrue(readNode.isPresent());
139
140         readNode = snapshotAfterCommits.readNode(path2);
141         assertTrue(readNode.isPresent());
142     }
143
144     public void modification2() throws DataValidationFailedException {
145         final var parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
146                 new NodeIdentifier(parentOrderedList))
147                 .withChild(createParentOrderedListEntry("pkval3", "plfval3updated"))
148                 .withChild(createParentOrderedListEntry("pkval4", "plfval4"))
149                 .withChild(createParentOrderedListEntry("pkval5", "plfval5")).build();
150
151         final var parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
152                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
153                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
154                 .build();
155
156         final var treeModification = inMemoryDataTree.takeSnapshot().newModification();
157
158         final var path1 = YangInstanceIdentifier.of(parentContainer);
159         treeModification.merge(path1, parentContainerNode);
160
161         final var childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
162                 new NodeIdentifier(childOrderedList))
163                 .withChild(createChildOrderedListEntry("chkval1", "chlfval1updated"))
164                 .withChild(createChildOrderedListEntry("chkval2", "chlfval2updated"))
165                 .withChild(createChildOrderedListEntry("chkval3", "chlfval3")).build();
166
167         final var path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
168                 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList);
169         treeModification.merge(path2, childOrderedListNode);
170
171         treeModification.ready();
172         inMemoryDataTree.validate(treeModification);
173         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
174
175         final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
176         var readNode = snapshotAfterCommits.readNode(path1);
177         assertTrue(readNode.isPresent());
178
179         readNode = snapshotAfterCommits.readNode(path2);
180         assertTrue(readNode.isPresent());
181     }
182
183     public void modification3() throws DataValidationFailedException {
184         final var parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
185                 new NodeIdentifier(parentOrderedList))
186                 .withChild(createParentOrderedListEntry("pkval1", "plfval1")).build();
187
188         final var parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
189                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
190                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
191                 .build();
192
193         final var path1 = YangInstanceIdentifier.of(parentContainer);
194
195         final var treeModification = inMemoryDataTree.takeSnapshot().newModification();
196         treeModification.write(path1, parentContainerNode);
197
198         final var childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
199                 new NodeIdentifier(childOrderedList))
200                 .withChild(createChildOrderedListEntry("chkval1", "chlfval1new")).build();
201
202         final var path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
203                 .node(parentOrderedList)
204                 .node(createParentOrderedListEntryPath("pkval4")).node(childOrderedList);
205
206         treeModification.merge(path2, childOrderedListNode);
207
208         try {
209             treeModification.ready();
210             fail("Exception should have been thrown.");
211             inMemoryDataTree.validate(treeModification);
212             inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
213         } catch (final IllegalArgumentException ex) {
214             LOG.debug("IllegalArgumentException was thrown as expected", ex);
215             assertTrue(ex.getMessage().contains("Metadata not available for modification ModifiedNode"));
216         }
217
218         final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
219         var readNode = snapshotAfterCommits.readNode(path1);
220         assertTrue(readNode.isPresent());
221
222         readNode = snapshotAfterCommits.readNode(path2);
223         assertFalse(readNode.isPresent());
224     }
225
226     public void modification4() throws DataValidationFailedException {
227         final var treeModification1 = inMemoryDataTree.takeSnapshot().newModification();
228         final var treeModification2 = inMemoryDataTree.takeSnapshot().newModification();
229
230         final var parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
231             new NodeIdentifier(parentOrderedList)).withChild(createParentOrderedListEntry("pkval1", "plfval1"))
232                 .build();
233
234         final var parentOrderedListNode2 = Builders.orderedMapBuilder().withNodeIdentifier(
235             new NodeIdentifier(parentOrderedList)).withChild(createParentOrderedListEntry("pkval2", "plfval2"))
236                 .build();
237
238         final var parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
239                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
240                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
241                 .build();
242
243         final var parentContainerNode2 = Builders.containerBuilder().withNodeIdentifier(
244                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
245                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode2).build())
246                 .build();
247
248         final var path = YangInstanceIdentifier.of(parentContainer);
249
250         treeModification1.write(path, parentContainerNode);
251         treeModification2.write(path, parentContainerNode2);
252         treeModification1.ready();
253         treeModification2.ready();
254
255         inMemoryDataTree.validate(treeModification1);
256         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification1));
257
258         try {
259             inMemoryDataTree.validate(treeModification2);
260             fail("Exception should have been thrown.");
261             inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification2));
262         } catch (ConflictingModificationAppliedException ex) {
263             LOG.debug("ConflictingModificationAppliedException was thrown as expected", ex);
264             assertTrue(ex.getMessage().contains("Node was replaced by other transaction"));
265         }
266
267         final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
268         final var readNode = snapshotAfterCommits.readNode(path);
269         assertTrue(readNode.isPresent());
270     }
271
272     public void delete1() throws DataValidationFailedException {
273         final var path = YangInstanceIdentifier.of(parentContainer).node(childContainer)
274                 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList)
275                 .node(createChildOrderedListEntryPath("chkval1"));
276
277         final var treeModification = inMemoryDataTree.takeSnapshot().newModification();
278         treeModification.delete(path);
279         treeModification.ready();
280         inMemoryDataTree.validate(treeModification);
281         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
282
283         final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
284         final var readNode = snapshotAfterCommits.readNode(path);
285         assertFalse(readNode.isPresent());
286     }
287
288     public void delete2() throws DataValidationFailedException {
289         final var path = YangInstanceIdentifier.of(parentContainer).node(childContainer)
290                 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2"));
291
292         final var treeModification = inMemoryDataTree.takeSnapshot().newModification();
293         treeModification.delete(path);
294         treeModification.ready();
295         inMemoryDataTree.validate(treeModification);
296         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
297
298         final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
299         final var readNode = snapshotAfterCommits.readNode(path);
300         assertFalse(readNode.isPresent());
301     }
302
303     private MapEntryNode createParentOrderedListEntry(final String keyValue, final String leafValue) {
304         return Builders.mapEntryBuilder().withNodeIdentifier(NodeIdentifierWithPredicates.of(parentOrderedList,
305                 parentKeyLeaf, keyValue))
306                 .withChild(Builders.leafBuilder().withNodeIdentifier(NodeIdentifier.create(parentOrdinaryLeaf))
307                     .withValue(leafValue).build()).build();
308     }
309
310     private MapEntryNode createChildOrderedListEntry(final String keyValue, final String leafValue) {
311         return Builders.mapEntryBuilder().withNodeIdentifier(NodeIdentifierWithPredicates.of(childOrderedList,
312                 childKeyLeaf, keyValue))
313                 .withChild(Builders.leafBuilder().withNodeIdentifier(NodeIdentifier.create(childOrdinaryLeaf))
314                     .withValue(leafValue).build()).build();
315     }
316
317     private NodeIdentifierWithPredicates createParentOrderedListEntryPath(final String keyValue) {
318         ImmutableMap.Builder<QName, Object> builder = ImmutableMap.builder();
319         ImmutableMap<QName, Object> keys = builder.put(parentKeyLeaf, keyValue).build();
320         return NodeIdentifierWithPredicates.of(parentOrderedList, keys);
321     }
322
323     private NodeIdentifierWithPredicates createChildOrderedListEntryPath(final String keyValue) {
324         ImmutableMap.Builder<QName, Object> builder = ImmutableMap.builder();
325         ImmutableMap<QName, Object> keys = builder.put(childKeyLeaf, keyValue).build();
326         return NodeIdentifierWithPredicates.of(childOrderedList, keys);
327     }
328 }