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;
13 import org.junit.Before;
14 import org.junit.Test;
15 import org.opendaylight.yangtools.yang.common.QName;
16 import org.opendaylight.yangtools.yang.common.QNameModule;
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.MapNode;
23 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
24 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
25 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
26 import org.opendaylight.yangtools.yang.data.api.schema.tree.TipProducingDataTree;
27 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
28 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
29 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
30 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
31 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
32 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
34 public class Bug4295Test {
36 private TipProducingDataTree inMemoryDataTree;
37 private SchemaContext context;
39 private QName subRoot;
40 private QName outerList;
41 private QName innerList;
46 private QNameModule foo;
50 context = YangParserTestUtils.parseYangResource("/bug-4295/foo.yang");
51 foo = QNameModule.create(URI.create("foo"), null);
52 root = QName.create(foo, "root");
53 subRoot = QName.create(foo, "sub-root");
54 outerList = QName.create(foo, "outer-list");
55 innerList = QName.create(foo, "inner-list");
56 oid = QName.create(foo, "o-id");
57 iid = QName.create(foo, "i-id");
58 oleaf = QName.create(foo, "o");
59 ileaf = QName.create(foo, "i");
60 inMemoryDataTree = InMemoryDataTreeFactory.getInstance().create(DataTreeConfiguration.DEFAULT_OPERATIONAL);
61 inMemoryDataTree.setSchemaContext(context);
65 public void test() throws DataValidationFailedException {
67 secondModification(1);
68 secondModification(2);
69 secondModification(3);
73 private void firstModification() throws DataValidationFailedException {
75 MapNode outerListNode = ImmutableNodes.mapNodeBuilder().withNodeIdentifier(NodeIdentifier.create(outerList))
76 .withChild(createOuterListEntry("1", "o-1"))
77 .withChild(createOuterListEntry("2", "o-2"))
78 .withChild(createOuterListEntry("3", "o-3"))
80 ContainerNode rootContainerNode = createRootContainerBuilder()
81 .withChild(createSubRootContainerBuilder().withChild(outerListNode).build())
83 YangInstanceIdentifier path = YangInstanceIdentifier.of(root);
84 DataTreeModification modification = inMemoryDataTree.takeSnapshot().newModification();
85 modification.merge(path, rootContainerNode);
87 /* WRITE INNER LIST WITH ENTRIES*/
88 MapNode innerListNode = createInnerListBuilder()
89 .withChild(createInnerListEntry("a", "i-a"))
90 .withChild(createInnerListEntry("b", "i-b"))
92 path = YangInstanceIdentifier.of(root).node(subRoot).node(outerList).node(createOuterListEntryPath("2"))
94 modification.write(path, innerListNode);
98 inMemoryDataTree.validate(modification);
99 inMemoryDataTree.commit(inMemoryDataTree.prepare(modification));
102 private void secondModification(final int testScenarioNumber) throws DataValidationFailedException {
104 MapNode outerListNode = ImmutableNodes.mapNodeBuilder().withNodeIdentifier(NodeIdentifier.create(outerList))
105 .withChild(createOuterListEntry("3", "o-3"))
106 .withChild(createOuterListEntry("4", "o-4"))
107 .withChild(createOuterListEntry("5", "o-5"))
110 ContainerNode rootContainerNode = createRootContainerBuilder()
111 .withChild(createSubRootContainerBuilder().withChild(outerListNode).build())
114 YangInstanceIdentifier path = YangInstanceIdentifier.of(root);
115 DataTreeModification modification = inMemoryDataTree.takeSnapshot().newModification();
116 modification.merge(path, rootContainerNode);
118 if (testScenarioNumber == 1) {
119 /* WRITE EMPTY INNER LIST */
120 writeEmptyInnerList(modification, "2");
121 } else if (testScenarioNumber == 2) {
122 /* WRITE INNER LIST ENTRY */
123 MapEntryNode innerListEntryA = createInnerListEntry("a", "i-a-2");
124 path = YangInstanceIdentifier.of(root).node(subRoot).node(outerList).node(createOuterListEntryPath("2"))
125 .node(innerList).node(createInnerListEntryPath("a"));
126 modification.write(path, innerListEntryA);
127 } else if (testScenarioNumber == 3) {
128 /* WRITE INNER LIST WITH ENTRIES */
129 MapNode innerListNode = createInnerListBuilder().withChild(createInnerListEntry("a", "i-a-3"))
130 .withChild(createInnerListEntry("c", "i-c")).build();
131 path = YangInstanceIdentifier.of(root).node(subRoot).node(outerList).node(createOuterListEntryPath("2"))
133 modification.write(path, innerListNode);
137 modification.ready();
138 inMemoryDataTree.validate(modification);
139 inMemoryDataTree.commit(inMemoryDataTree.prepare(modification));
142 private void writeEmptyInnerList(final DataTreeModification modification, final String outerListEntryKey) {
143 YangInstanceIdentifier path = YangInstanceIdentifier.of(root).node(subRoot).node(outerList)
144 .node(createOuterListEntryPath(outerListEntryKey)).node(innerList);
145 modification.write(path, createInnerListBuilder().build());
148 private DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> createRootContainerBuilder() {
149 return ImmutableContainerNodeBuilder.create().withNodeIdentifier(
150 new YangInstanceIdentifier.NodeIdentifier(root));
153 private DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> createSubRootContainerBuilder() {
154 return ImmutableContainerNodeBuilder.create().withNodeIdentifier(
155 new YangInstanceIdentifier.NodeIdentifier(subRoot));
158 private CollectionNodeBuilder<MapEntryNode, MapNode> createInnerListBuilder() {
159 return ImmutableNodes.mapNodeBuilder().withNodeIdentifier(NodeIdentifier.create(innerList));
162 private NodeIdentifierWithPredicates createInnerListEntryPath(final String keyValue) {
163 Builder<QName, Object> builder = ImmutableMap.builder();
164 ImmutableMap<QName, Object> keys = builder.put(iid, keyValue).build();
165 return new YangInstanceIdentifier.NodeIdentifierWithPredicates(innerList, keys);
168 private NodeIdentifierWithPredicates createOuterListEntryPath(final String keyValue) {
169 Builder<QName, Object> builder = ImmutableMap.builder();
170 ImmutableMap<QName, Object> keys = builder.put(oid, keyValue).build();
171 return new YangInstanceIdentifier.NodeIdentifierWithPredicates(outerList, keys);
174 private MapEntryNode createOuterListEntry(final String keyValue, final String leafValue) {
175 return ImmutableNodes.mapEntryBuilder(outerList, oid, keyValue)
176 .withChild(ImmutableNodes.leafNode(oleaf, leafValue)).build();
179 private MapEntryNode createInnerListEntry(final String keyValue, final String leafValue) {
180 return ImmutableNodes.mapEntryBuilder(innerList, iid, keyValue)
181 .withChild(ImmutableNodes.leafNode(ileaf, leafValue)).build();