Populate data/ hierarchy
[yangtools.git] / data / yang-data-impl / src / test / java / org / opendaylight / yangtools / yang / data / impl / schema / tree / 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.impl.schema.tree;
9
10 import com.google.common.collect.ImmutableMap;
11 import com.google.common.collect.ImmutableMap.Builder;
12 import org.junit.Before;
13 import org.junit.Test;
14 import org.opendaylight.yangtools.yang.common.QName;
15 import org.opendaylight.yangtools.yang.common.QNameModule;
16 import org.opendaylight.yangtools.yang.common.XMLNamespace;
17 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
20 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
21 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
22 import org.opendaylight.yangtools.yang.data.api.schema.SystemMapNode;
23 import org.opendaylight.yangtools.yang.data.api.schema.builder.CollectionNodeBuilder;
24 import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
25 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
26 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
27 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
28 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
29 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
30 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
31 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
32
33 public class Bug4295Test {
34
35     private DataTree inMemoryDataTree;
36     private QName root;
37     private QName subRoot;
38     private QName outerList;
39     private QName innerList;
40     private QName oid;
41     private QName iid;
42     private QName oleaf;
43     private QName ileaf;
44     private QNameModule foo;
45
46     @Before
47     public void init() {
48         foo = QNameModule.create(XMLNamespace.of("foo"));
49         root = QName.create(foo, "root");
50         subRoot = QName.create(foo, "sub-root");
51         outerList = QName.create(foo, "outer-list");
52         innerList = QName.create(foo, "inner-list");
53         oid = QName.create(foo, "o-id");
54         iid = QName.create(foo, "i-id");
55         oleaf = QName.create(foo, "o");
56         ileaf = QName.create(foo, "i");
57         inMemoryDataTree = new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_OPERATIONAL,
58             YangParserTestUtils.parseYangResource("/bug-4295/foo.yang"));
59     }
60
61     @Test
62     public void test() throws DataValidationFailedException {
63         firstModification();
64         secondModification(1);
65         secondModification(2);
66         secondModification(3);
67     }
68
69
70     private void firstModification() throws DataValidationFailedException {
71         /*  MERGE */
72         SystemMapNode outerListNode = ImmutableNodes.mapNodeBuilder()
73             .withNodeIdentifier(NodeIdentifier.create(outerList))
74             .withChild(createOuterListEntry("1", "o-1"))
75             .withChild(createOuterListEntry("2", "o-2"))
76             .withChild(createOuterListEntry("3", "o-3"))
77             .build();
78         ContainerNode rootContainerNode = createRootContainerBuilder()
79             .withChild(createSubRootContainerBuilder().withChild(outerListNode).build())
80             .build();
81         YangInstanceIdentifier path = YangInstanceIdentifier.of(root);
82         DataTreeModification modification = inMemoryDataTree.takeSnapshot().newModification();
83         modification.merge(path, rootContainerNode);
84
85         /*  WRITE INNER LIST WITH ENTRIES*/
86         SystemMapNode innerListNode = createInnerListBuilder()
87             .withChild(createInnerListEntry("a", "i-a"))
88             .withChild(createInnerListEntry("b", "i-b"))
89             .build();
90         path = YangInstanceIdentifier.of(root).node(subRoot).node(outerList).node(createOuterListEntryPath("2"))
91                 .node(innerList);
92         modification.write(path, innerListNode);
93
94         /*  COMMIT */
95         modification.ready();
96         inMemoryDataTree.validate(modification);
97         inMemoryDataTree.commit(inMemoryDataTree.prepare(modification));
98     }
99
100     private void secondModification(final int testScenarioNumber) throws DataValidationFailedException {
101         /*  MERGE */
102         SystemMapNode outerListNode = ImmutableNodes.mapNodeBuilder()
103             .withNodeIdentifier(NodeIdentifier.create(outerList))
104             .withChild(createOuterListEntry("3", "o-3"))
105             .withChild(createOuterListEntry("4", "o-4"))
106             .withChild(createOuterListEntry("5", "o-5"))
107             .build();
108
109         ContainerNode rootContainerNode = createRootContainerBuilder()
110             .withChild(createSubRootContainerBuilder().withChild(outerListNode).build())
111             .build();
112
113         YangInstanceIdentifier path = YangInstanceIdentifier.of(root);
114         DataTreeModification modification = inMemoryDataTree.takeSnapshot().newModification();
115         modification.merge(path, rootContainerNode);
116
117         if (testScenarioNumber == 1) {
118             /* WRITE EMPTY INNER LIST */
119             writeEmptyInnerList(modification, "2");
120         } else if (testScenarioNumber == 2) {
121             /* WRITE INNER LIST ENTRY */
122             MapEntryNode innerListEntryA = createInnerListEntry("a", "i-a-2");
123             path = YangInstanceIdentifier.of(root).node(subRoot).node(outerList).node(createOuterListEntryPath("2"))
124                     .node(innerList).node(createInnerListEntryPath("a"));
125             modification.write(path, innerListEntryA);
126         } else if (testScenarioNumber == 3) {
127             /* WRITE INNER LIST WITH ENTRIES */
128             SystemMapNode innerListNode = createInnerListBuilder().withChild(createInnerListEntry("a", "i-a-3"))
129                     .withChild(createInnerListEntry("c", "i-c")).build();
130             path = YangInstanceIdentifier.of(root).node(subRoot).node(outerList).node(createOuterListEntryPath("2"))
131                     .node(innerList);
132             modification.write(path, innerListNode);
133         }
134
135         /*  COMMIT */
136         modification.ready();
137         inMemoryDataTree.validate(modification);
138         inMemoryDataTree.commit(inMemoryDataTree.prepare(modification));
139     }
140
141     private void writeEmptyInnerList(final DataTreeModification modification, final String outerListEntryKey) {
142         YangInstanceIdentifier path = YangInstanceIdentifier.of(root).node(subRoot).node(outerList)
143                 .node(createOuterListEntryPath(outerListEntryKey)).node(innerList);
144         modification.write(path, createInnerListBuilder().build());
145     }
146
147     private DataContainerNodeBuilder<NodeIdentifier, ContainerNode> createRootContainerBuilder() {
148         return ImmutableContainerNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(root));
149     }
150
151     private DataContainerNodeBuilder<NodeIdentifier, ContainerNode> createSubRootContainerBuilder() {
152         return ImmutableContainerNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(subRoot));
153     }
154
155     private CollectionNodeBuilder<MapEntryNode, SystemMapNode> createInnerListBuilder() {
156         return ImmutableNodes.mapNodeBuilder().withNodeIdentifier(NodeIdentifier.create(innerList));
157     }
158
159     private NodeIdentifierWithPredicates createInnerListEntryPath(final String keyValue) {
160         Builder<QName, Object> builder = ImmutableMap.builder();
161         ImmutableMap<QName, Object> keys = builder.put(iid, keyValue).build();
162         return NodeIdentifierWithPredicates.of(innerList, keys);
163     }
164
165     private NodeIdentifierWithPredicates createOuterListEntryPath(final String keyValue) {
166         Builder<QName, Object> builder = ImmutableMap.builder();
167         ImmutableMap<QName, Object> keys = builder.put(oid, keyValue).build();
168         return NodeIdentifierWithPredicates.of(outerList, keys);
169     }
170
171     private MapEntryNode createOuterListEntry(final String keyValue, final String leafValue) {
172         return ImmutableNodes.mapEntryBuilder(outerList, oid, keyValue)
173                 .withChild(ImmutableNodes.leafNode(oleaf, leafValue)).build();
174     }
175
176     private MapEntryNode createInnerListEntry(final String keyValue, final String leafValue) {
177         return ImmutableNodes.mapEntryBuilder(innerList, iid, keyValue)
178                 .withChild(ImmutableNodes.leafNode(ileaf, leafValue)).build();
179     }
180 }