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