a02c512b0a6e2e76544173b50e8fb8f8e2112b13
[yangtools.git] / data / yang-data-tree-ri / src / test / java / org / opendaylight / yangtools / yang / data / tree / impl / Bug4295Test.java
1 /*
2  * Copyright (c) 2015 Pantheon Technologies s.r.o. 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 org.junit.Before;
11 import org.junit.Test;
12 import org.opendaylight.yangtools.yang.common.QName;
13 import org.opendaylight.yangtools.yang.common.QNameModule;
14 import org.opendaylight.yangtools.yang.common.XMLNamespace;
15 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
16 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
17 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
18 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
19 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
20 import org.opendaylight.yangtools.yang.data.api.schema.SystemMapNode;
21 import org.opendaylight.yangtools.yang.data.api.schema.builder.CollectionNodeBuilder;
22 import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
23 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
24 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
25 import org.opendaylight.yangtools.yang.data.tree.api.DataTree;
26 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeConfiguration;
27 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeModification;
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
32 public class Bug4295Test {
33
34     private DataTree inMemoryDataTree;
35     private QName root;
36     private QName subRoot;
37     private QName outerList;
38     private QName innerList;
39     private QName oid;
40     private QName iid;
41     private QName oleaf;
42     private QName ileaf;
43     private QNameModule foo;
44
45     @Before
46     public void init() {
47         foo = QNameModule.create(XMLNamespace.of("foo"));
48         root = QName.create(foo, "root");
49         subRoot = QName.create(foo, "sub-root");
50         outerList = QName.create(foo, "outer-list");
51         innerList = QName.create(foo, "inner-list");
52         oid = QName.create(foo, "o-id");
53         iid = QName.create(foo, "i-id");
54         oleaf = QName.create(foo, "o");
55         ileaf = QName.create(foo, "i");
56         inMemoryDataTree = new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_OPERATIONAL,
57             YangParserTestUtils.parseYang("""
58                 module foo {
59                   namespace "foo";
60                   prefix foo;
61
62                   container root {
63                     container sub-root {
64                       list outer-list {
65                         key "o-id";
66                         leaf o-id {
67                           type string;
68                         }
69                         list inner-list {
70                           key "i-id";
71                           leaf i-id {
72                             type string;
73                           }
74                           leaf i {
75                             type string;
76                           }
77                         }
78                         leaf o {
79                           type string;
80                         }
81                       }
82                     }
83                   }
84                 }"""));
85     }
86
87     @Test
88     public void test() throws DataValidationFailedException {
89         firstModification();
90         secondModification(1);
91         secondModification(2);
92         secondModification(3);
93     }
94
95     private void firstModification() throws DataValidationFailedException {
96         /*  MERGE */
97         YangInstanceIdentifier path = YangInstanceIdentifier.of(root);
98         DataTreeModification modification = inMemoryDataTree.takeSnapshot().newModification();
99         modification.merge(path, createRootContainerBuilder()
100             .withChild(createSubRootContainerBuilder()
101                 .withChild(ImmutableNodes.mapNodeBuilder()
102                     .withNodeIdentifier(NodeIdentifier.create(outerList))
103                     .withChild(createOuterListEntry("1", "o-1"))
104                     .withChild(createOuterListEntry("2", "o-2"))
105                     .withChild(createOuterListEntry("3", "o-3"))
106                     .build())
107                 .build())
108             .build());
109
110         /*  WRITE INNER LIST WITH ENTRIES*/
111         path = YangInstanceIdentifier.of(root).node(subRoot).node(outerList).node(createOuterListEntryPath("2"))
112                 .node(innerList);
113         modification.write(path, createInnerListBuilder()
114             .withChild(createInnerListEntry("a", "i-a"))
115             .withChild(createInnerListEntry("b", "i-b"))
116             .build());
117
118         /*  COMMIT */
119         modification.ready();
120         inMemoryDataTree.validate(modification);
121         inMemoryDataTree.commit(inMemoryDataTree.prepare(modification));
122     }
123
124     private void secondModification(final int testScenarioNumber) throws DataValidationFailedException {
125         /*  MERGE */
126         ContainerNode rootContainerNode = createRootContainerBuilder()
127             .withChild(createSubRootContainerBuilder()
128                 .withChild(ImmutableNodes.mapNodeBuilder()
129                     .withNodeIdentifier(NodeIdentifier.create(outerList))
130                     .withChild(createOuterListEntry("3", "o-3"))
131                     .withChild(createOuterListEntry("4", "o-4"))
132                     .withChild(createOuterListEntry("5", "o-5"))
133                     .build())
134                 .build())
135             .build();
136
137         YangInstanceIdentifier path = YangInstanceIdentifier.of(root);
138         DataTreeModification modification = inMemoryDataTree.takeSnapshot().newModification();
139         modification.merge(path, rootContainerNode);
140
141         switch (testScenarioNumber) {
142             case 1:
143                 /* WRITE EMPTY INNER LIST */
144                 writeEmptyInnerList(modification, "2");
145                 break;
146             case 2: {
147                 /* WRITE INNER LIST ENTRY */
148                 MapEntryNode innerListEntryA = createInnerListEntry("a", "i-a-2");
149                 path = YangInstanceIdentifier.of(root, subRoot, outerList).node(createOuterListEntryPath("2"))
150                     .node(innerList).node(createInnerListEntryPath("a"));
151                 modification.write(path, innerListEntryA);
152                 break;
153             }
154             case 3: {
155                 /* WRITE INNER LIST WITH ENTRIES */
156                 path = YangInstanceIdentifier.of(root, subRoot, outerList).node(createOuterListEntryPath("2"))
157                     .node(innerList);
158                 modification.write(path, createInnerListBuilder()
159                     .withChild(createInnerListEntry("a", "i-a-3"))
160                     .withChild(createInnerListEntry("c", "i-c"))
161                     .build());
162                 break;
163             }
164             default:
165                 break;
166         }
167
168         /*  COMMIT */
169         modification.ready();
170         inMemoryDataTree.validate(modification);
171         inMemoryDataTree.commit(inMemoryDataTree.prepare(modification));
172     }
173
174     private void writeEmptyInnerList(final DataTreeModification modification, final String outerListEntryKey) {
175         YangInstanceIdentifier path = YangInstanceIdentifier.of(root, subRoot, outerList)
176                 .node(createOuterListEntryPath(outerListEntryKey)).node(innerList);
177         modification.write(path, createInnerListBuilder().build());
178     }
179
180     private DataContainerNodeBuilder<NodeIdentifier, ContainerNode> createRootContainerBuilder() {
181         return Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(root));
182     }
183
184     private DataContainerNodeBuilder<NodeIdentifier, ContainerNode> createSubRootContainerBuilder() {
185         return  Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(subRoot));
186     }
187
188     private CollectionNodeBuilder<MapEntryNode, SystemMapNode> createInnerListBuilder() {
189         return ImmutableNodes.mapNodeBuilder().withNodeIdentifier(NodeIdentifier.create(innerList));
190     }
191
192     private NodeIdentifierWithPredicates createInnerListEntryPath(final String keyValue) {
193         return NodeIdentifierWithPredicates.of(innerList, iid, keyValue);
194     }
195
196     private NodeIdentifierWithPredicates createOuterListEntryPath(final String keyValue) {
197         return NodeIdentifierWithPredicates.of(outerList, oid, keyValue);
198     }
199
200     private MapEntryNode createOuterListEntry(final String keyValue, final String leafValue) {
201         return ImmutableNodes.mapEntryBuilder(outerList, oid, keyValue)
202                 .withChild(ImmutableNodes.leafNode(oleaf, leafValue)).build();
203     }
204
205     private MapEntryNode createInnerListEntry(final String keyValue, final String leafValue) {
206         return ImmutableNodes.mapEntryBuilder(innerList, iid, keyValue)
207                 .withChild(ImmutableNodes.leafNode(ileaf, leafValue)).build();
208     }
209 }