2 * Copyright (c) 2015 Pantheon Technologies s.r.o. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
10 import com.google.common.collect.ImmutableMap;
11 import com.google.common.collect.ImmutableMap.Builder;
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.TestUtils;
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;
36 public class Bug4295Test {
38 private TipProducingDataTree inMemoryDataTree;
39 private SchemaContext context;
41 private QName subRoot;
42 private QName outerList;
43 private QName innerList;
48 private QNameModule foo;
51 public void init() throws Exception {
52 final File resourceFile = new File(Bug4295Test.class.getResource("/bug-4295/foo.yang")
54 context = TestUtils.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);
69 public void test() throws DataValidationFailedException {
71 secondModification(1);
72 secondModification(2);
73 secondModification(3);
77 private void firstModification() throws DataValidationFailedException {
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"))
84 ContainerNode rootContainerNode = createRootContainerBuilder()
86 createSubRootContainerBuilder()
87 .withChild(outerListNode)
90 YangInstanceIdentifier path = YangInstanceIdentifier.of(root);
91 DataTreeModification modification = inMemoryDataTree.takeSnapshot().newModification();
92 modification.merge(path, rootContainerNode);
94 /* WRITE INNER LIST WITH ENTRIES*/
95 MapNode innerListNode = createInnerListBuilder()
96 .withChild(createInnerListEntry("a", "i-a"))
97 .withChild(createInnerListEntry("b", "i-b"))
99 path = YangInstanceIdentifier.of(root).node(subRoot).node(outerList).node(createOuterListEntryPath("2")).node(innerList);
100 modification.write(path, innerListNode);
103 modification.ready();
104 inMemoryDataTree.validate(modification);
105 inMemoryDataTree.commit(inMemoryDataTree.prepare(modification));
108 private void secondModification(int testScenarioNumber) throws DataValidationFailedException {
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"))
116 ContainerNode rootContainerNode = createRootContainerBuilder()
118 createSubRootContainerBuilder()
119 .withChild(outerListNode)
123 YangInstanceIdentifier path = YangInstanceIdentifier.of(root);
124 DataTreeModification modification = inMemoryDataTree.takeSnapshot().newModification();
125 modification.merge(path, rootContainerNode);
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"))
142 modification.write(path, innerListNode);
146 modification.ready();
147 inMemoryDataTree.validate(modification);
148 inMemoryDataTree.commit(inMemoryDataTree.prepare(modification));
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());
157 private DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> createRootContainerBuilder() {
158 return ImmutableContainerNodeBuilder.create().withNodeIdentifier(
159 new YangInstanceIdentifier.NodeIdentifier(root));
162 private DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> createSubRootContainerBuilder() {
163 return ImmutableContainerNodeBuilder.create().withNodeIdentifier(
164 new YangInstanceIdentifier.NodeIdentifier(subRoot));
167 private CollectionNodeBuilder<MapEntryNode, MapNode> createInnerListBuilder() {
168 return ImmutableNodes.mapNodeBuilder().withNodeIdentifier(NodeIdentifier.create(innerList));
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);
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);
183 private MapEntryNode createOuterListEntry(String keyValue, String leafValue) {
184 return ImmutableNodes.mapEntryBuilder(outerList, oId, keyValue)
185 .withChild(ImmutableNodes.leafNode(oLeaf, leafValue)).build();
188 private MapEntryNode createInnerListEntry(String keyValue, String leafValue) {
189 return ImmutableNodes.mapEntryBuilder(innerList, iId, keyValue)
190 .withChild(ImmutableNodes.leafNode(iLeaf, leafValue)).build();