1 package org.opendaylight.controller.cluster.datastore.node.utils.transformer;
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertNull;
5 import static org.junit.Assert.assertTrue;
6 import static org.mockito.Matchers.any;
7 import static org.mockito.Mockito.doReturn;
8 import static org.mockito.Mockito.mock;
9 import static org.mockito.Mockito.never;
10 import static org.mockito.Mockito.verify;
11 import com.google.common.collect.ImmutableMap;
12 import com.google.common.collect.ImmutableSet;
13 import java.io.IOException;
14 import java.util.concurrent.atomic.AtomicInteger;
15 import javax.xml.transform.dom.DOMSource;
16 import org.junit.Assert;
17 import org.junit.Before;
18 import org.junit.Test;
19 import org.mockito.ArgumentCaptor;
20 import org.mockito.Mock;
21 import org.mockito.MockitoAnnotations;
22 import org.opendaylight.controller.cluster.datastore.node.utils.NormalizedNodeNavigator;
23 import org.opendaylight.controller.cluster.datastore.node.utils.NormalizedNodeVisitor;
24 import org.opendaylight.controller.cluster.datastore.util.TestModel;
25 import org.opendaylight.yangtools.yang.common.QName;
26 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
27 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
28 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
29 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
30 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
31 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
32 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
33 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
34 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
35 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
36 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
37 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetEntryNodeBuilder;
38 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
40 public class NormalizedNodePrunerTest {
42 private NormalizedNodePruner prunerFullSchema;
44 private NormalizedNodePruner prunerNoAugSchema;
47 private NormalizedNodeBuilderWrapper normalizedNodeBuilderWrapper;
50 private NormalizedNodeContainerBuilder normalizedNodeContainerBuilder;
53 private NormalizedNode<?,?> normalizedNode;
57 MockitoAnnotations.initMocks(this);
58 prunerFullSchema = new NormalizedNodePruner(TestModel.createTestContext());
59 prunerNoAugSchema = new NormalizedNodePruner(TestModel.createTestContextWithoutAugmentationSchema());
60 doReturn(normalizedNodeContainerBuilder).when(normalizedNodeBuilderWrapper).builder();
61 doReturn(TestModel.BOOLEAN_LEAF_QNAME).when(normalizedNodeBuilderWrapper).nodeType();
62 doReturn(normalizedNode).when(normalizedNodeContainerBuilder).build();
63 doReturn(new YangInstanceIdentifier.NodeIdentifier(TestModel.BOOLEAN_LEAF_QNAME)).when(normalizedNodeBuilderWrapper).identifier();
67 public void testNodesNotPrunedWhenSchemaPresent() throws IOException {
68 NormalizedNodePruner pruner = prunerFullSchema;
70 NormalizedNodeWriter normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(pruner);
72 NormalizedNode<?, ?> expected = createTestContainer();
74 normalizedNodeWriter.write(expected);
76 NormalizedNode actual = pruner.normalizedNode();
78 assertEquals(expected, actual);
82 @Test(expected = IllegalStateException.class)
83 public void testReusePruner() throws IOException {
84 NormalizedNodePruner pruner = prunerFullSchema;
86 NormalizedNodeWriter normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(pruner);
88 NormalizedNode<?, ?> expected = createTestContainer();
90 normalizedNodeWriter.write(expected);
92 NormalizedNode actual = pruner.normalizedNode();
94 assertEquals(expected, actual);
96 NormalizedNodeWriter.forStreamWriter(pruner).write(expected);
102 public void testNodesPrunedWhenAugmentationSchemaNotPresent() throws IOException {
103 NormalizedNodePruner pruner = prunerNoAugSchema;
105 NormalizedNodeWriter normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(pruner);
107 NormalizedNode<?, ?> expected = createTestContainer();
109 normalizedNodeWriter.write(expected);
111 NormalizedNode actual = pruner.normalizedNode();
113 Assert.assertNotEquals(expected, actual);
115 // Asserting true here instead of checking actual value because I don't want this assertion to be fragile
116 assertTrue(countNodes(expected, "store:aug") > 0);
118 // All nodes from the augmentation module are gone from the resulting node
119 assertEquals(0, countNodes(actual, "store:aug"));
123 public void testNodesPrunedWhenTestSchemaNotPresent() throws IOException {
124 NormalizedNodePruner pruner = new NormalizedNodePruner(TestModel.createTestContextWithoutTestSchema());
126 NormalizedNodeWriter normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(pruner);
128 NormalizedNode<?, ?> expected = createTestContainer();
130 normalizedNodeWriter.write(expected);
132 NormalizedNode actual = pruner.normalizedNode();
134 // Since top level schema is missing null is returned
137 // Asserting true here instead of checking actual value because I don't want this assertion to be fragile
138 assertTrue(countNodes(expected, "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test") > 0);
143 private int countNodes(NormalizedNode<?,?> normalizedNode, final String namespaceFilter){
144 if(normalizedNode == null){
147 final AtomicInteger count = new AtomicInteger();
148 new NormalizedNodeNavigator(new NormalizedNodeVisitor() {
151 public void visitNode(int level, String parentPath, NormalizedNode<?, ?> normalizedNode) {
152 if(!(normalizedNode.getIdentifier() instanceof YangInstanceIdentifier.AugmentationIdentifier)) {
153 if (normalizedNode.getIdentifier().getNodeType().getNamespace().toString().contains(namespaceFilter)) {
154 count.incrementAndGet();
158 }).navigate(YangInstanceIdentifier.builder().build().toString(), normalizedNode);
163 @Test(expected = IllegalStateException.class)
164 public void testLeafNodeHasNoParent() throws IOException {
165 prunerFullSchema.leafNode(new YangInstanceIdentifier.NodeIdentifier(TestModel.BOOLEAN_LEAF_QNAME), mock(Object.class));
169 public void testLeafNodeHasParent() throws IOException {
170 prunerFullSchema.stack().push(normalizedNodeBuilderWrapper);
171 Object o = mock(Object.class);
172 prunerFullSchema.leafNode(new YangInstanceIdentifier.NodeIdentifier(TestModel.BOOLEAN_LEAF_QNAME), o);
174 ArgumentCaptor<NormalizedNode> captor = ArgumentCaptor.forClass(NormalizedNode.class);
176 verify(normalizedNodeContainerBuilder).addChild(captor.capture());
178 NormalizedNode value = captor.getValue();
179 assertEquals(normalizedNodeBuilderWrapper.identifier().getNodeType(), value.getNodeType());
180 assertEquals(normalizedNodeBuilderWrapper.identifier(), value.getIdentifier());
181 assertEquals(o, value.getValue());
186 public void testLeafNodeSchemaMissing() throws IOException {
187 prunerNoAugSchema.stack().push(normalizedNodeBuilderWrapper);
188 prunerNoAugSchema.leafNode(new YangInstanceIdentifier.NodeIdentifier(TestModel.AUG_CONT_QNAME), mock(Object.class));
189 verify(normalizedNodeContainerBuilder, never()).addChild(any(NormalizedNode.class));
192 @Test(expected = IllegalStateException.class)
193 public void testLeafSetEntryNodeHasNoParent() throws IOException {
194 prunerFullSchema.leafSetEntryNode(mock(Object.class));
198 public void testLeafSetEntryNodeHasParent() throws IOException {
199 prunerFullSchema.stack().push(normalizedNodeBuilderWrapper);
200 Object o = mock(Object.class);
201 YangInstanceIdentifier.PathArgument nodeIdentifier
202 = new YangInstanceIdentifier.NodeWithValue(normalizedNodeBuilderWrapper.identifier().getNodeType(), o);
203 prunerFullSchema.leafSetEntryNode(o);
205 ArgumentCaptor<NormalizedNode> captor = ArgumentCaptor.forClass(NormalizedNode.class);
207 verify(normalizedNodeContainerBuilder).addChild(captor.capture());
209 NormalizedNode value = captor.getValue();
210 assertEquals(nodeIdentifier.getNodeType(), value.getNodeType());
211 assertEquals(nodeIdentifier, value.getIdentifier());
212 assertEquals(o, value.getValue());
217 public void testLeafSetEntryNodeSchemaMissing() throws IOException {
218 doReturn(new YangInstanceIdentifier.NodeIdentifier(TestModel.AUG_CONT_QNAME)).when(normalizedNodeBuilderWrapper).identifier();
220 prunerNoAugSchema.stack().push(normalizedNodeBuilderWrapper);
221 prunerNoAugSchema.leafSetEntryNode(new YangInstanceIdentifier.NodeIdentifier(TestModel.AUG_CONT_QNAME));
223 verify(normalizedNodeContainerBuilder, never()).addChild(any(NormalizedNode.class));
226 @Test(expected = IllegalStateException.class)
227 public void testAnyXMLNodeHasNoParent() throws IOException {
228 prunerFullSchema.anyxmlNode(new YangInstanceIdentifier.NodeIdentifier(TestModel.BOOLEAN_LEAF_QNAME), mock(Object.class));
232 public void testAnyXMLNodeHasParent() throws IOException {
233 prunerFullSchema.stack().push(normalizedNodeBuilderWrapper);
234 YangInstanceIdentifier.NodeIdentifier nodeIdentifier = new YangInstanceIdentifier.NodeIdentifier(TestModel.BOOLEAN_LEAF_QNAME);
235 DOMSource o = mock(DOMSource.class);
236 prunerFullSchema.anyxmlNode(nodeIdentifier, o);
238 ArgumentCaptor<NormalizedNode> captor = ArgumentCaptor.forClass(NormalizedNode.class);
240 verify(normalizedNodeContainerBuilder).addChild(captor.capture());
242 NormalizedNode value = captor.getValue();
243 assertEquals(nodeIdentifier.getNodeType(), value.getNodeType());
244 assertEquals(nodeIdentifier, value.getIdentifier());
245 assertEquals(o, value.getValue());
249 public void testAnyXmlNodeSchemaMissing() throws IOException {
250 prunerNoAugSchema.stack().push(normalizedNodeBuilderWrapper);
251 prunerNoAugSchema.anyxmlNode(new YangInstanceIdentifier.NodeIdentifier(TestModel.AUG_CONT_QNAME), mock(DOMSource.class));
253 verify(normalizedNodeContainerBuilder, never()).addChild(any(NormalizedNode.class));
260 public void testLeafSetPushesBuilderToStack() throws IOException {
261 prunerFullSchema.startLeafSet(new YangInstanceIdentifier.NodeIdentifier(TestModel.BOOLEAN_LEAF_QNAME), 10);
263 assertEquals(1, prunerFullSchema.stack().size());
264 assertTrue(prunerFullSchema.stack().peek().toString(), prunerFullSchema.stack().peek() instanceof NormalizedNodeBuilderWrapper);
265 assertTrue(prunerFullSchema.stack().peek().builder().toString(), prunerFullSchema.stack().peek().builder() instanceof ListNodeBuilder);
269 public void testStartContainerNodePushesBuilderToStack() throws IOException {
270 prunerFullSchema.startContainerNode(new YangInstanceIdentifier.NodeIdentifier(TestModel.BOOLEAN_LEAF_QNAME), 10);
272 assertEquals(1, prunerFullSchema.stack().size());
273 assertTrue(prunerFullSchema.stack().peek().toString(), prunerFullSchema.stack().peek() instanceof NormalizedNodeBuilderWrapper);
274 assertTrue(prunerFullSchema.stack().peek().builder().toString(), prunerFullSchema.stack().peek().builder() instanceof DataContainerNodeAttrBuilder);
278 public void testStartUnkeyedListPushesBuilderToStack() throws IOException {
279 prunerFullSchema.startUnkeyedList(new YangInstanceIdentifier.NodeIdentifier(TestModel.BOOLEAN_LEAF_QNAME), 10);
281 assertEquals(1, prunerFullSchema.stack().size());
282 assertTrue(prunerFullSchema.stack().peek().toString(), prunerFullSchema.stack().peek() instanceof NormalizedNodeBuilderWrapper);
283 assertTrue(prunerFullSchema.stack().peek().builder().toString(), prunerFullSchema.stack().peek().builder() instanceof CollectionNodeBuilder);
287 public void testStartUnkeyedListItemPushesBuilderToStack() throws IOException {
288 prunerFullSchema.startUnkeyedListItem(new YangInstanceIdentifier.NodeIdentifier(TestModel.BOOLEAN_LEAF_QNAME), 10);
290 assertEquals(1, prunerFullSchema.stack().size());
291 assertTrue(prunerFullSchema.stack().peek().toString(), prunerFullSchema.stack().peek() instanceof NormalizedNodeBuilderWrapper);
292 assertTrue(prunerFullSchema.stack().peek().builder().toString(), prunerFullSchema.stack().peek().builder() instanceof DataContainerNodeAttrBuilder);
296 public void testStartMapNodePushesBuilderToStack() throws IOException {
297 prunerFullSchema.startMapNode(new YangInstanceIdentifier.NodeIdentifier(TestModel.BOOLEAN_LEAF_QNAME), 10);
299 assertEquals(1, prunerFullSchema.stack().size());
300 assertTrue(prunerFullSchema.stack().peek().toString(), prunerFullSchema.stack().peek() instanceof NormalizedNodeBuilderWrapper);
301 assertTrue(prunerFullSchema.stack().peek().builder().toString(), prunerFullSchema.stack().peek().builder() instanceof CollectionNodeBuilder);
305 public void testStartMapEntryNodePushesBuilderToStack() throws IOException {
306 prunerFullSchema.startMapEntryNode(
307 new YangInstanceIdentifier.NodeIdentifierWithPredicates(TestModel.BOOLEAN_LEAF_QNAME,
308 ImmutableMap.<QName, Object>of(TestModel.BOOLEAN_LEAF_QNAME, "value")), 10);
310 assertEquals(1, prunerFullSchema.stack().size());
311 assertTrue(prunerFullSchema.stack().peek().toString(), prunerFullSchema.stack().peek() instanceof NormalizedNodeBuilderWrapper);
312 assertTrue(prunerFullSchema.stack().peek().builder().toString(), prunerFullSchema.stack().peek().builder() instanceof DataContainerNodeAttrBuilder);
316 public void testStartOrderedMapNodePushesBuilderToStack() throws IOException {
317 prunerFullSchema.startOrderedMapNode(new YangInstanceIdentifier.NodeIdentifier(TestModel.BOOLEAN_LEAF_QNAME), 10);
319 assertEquals(1, prunerFullSchema.stack().size());
320 assertTrue(prunerFullSchema.stack().peek().toString(), prunerFullSchema.stack().peek() instanceof NormalizedNodeBuilderWrapper);
321 assertTrue(prunerFullSchema.stack().peek().builder().toString(), prunerFullSchema.stack().peek().builder() instanceof CollectionNodeBuilder);
325 public void testStartChoiceNodePushesBuilderToStack() throws IOException {
326 prunerFullSchema.startChoiceNode(new YangInstanceIdentifier.NodeIdentifier(TestModel.BOOLEAN_LEAF_QNAME), 10);
328 assertEquals(1, prunerFullSchema.stack().size());
329 assertTrue(prunerFullSchema.stack().peek().toString(), prunerFullSchema.stack().peek() instanceof NormalizedNodeBuilderWrapper);
330 assertTrue(prunerFullSchema.stack().peek().builder().toString(), prunerFullSchema.stack().peek().builder() instanceof DataContainerNodeBuilder);
334 public void testStartAugmentationPushesBuilderToStack() throws IOException {
335 prunerFullSchema.startAugmentationNode(new YangInstanceIdentifier.AugmentationIdentifier(ImmutableSet.of(TestModel.AUG_CONT_QNAME)));
337 assertEquals(1, prunerFullSchema.stack().size());
338 assertTrue(prunerFullSchema.stack().peek().toString(), prunerFullSchema.stack().peek() instanceof NormalizedNodeBuilderWrapper);
339 assertTrue(prunerFullSchema.stack().peek().builder().toString(), prunerFullSchema.stack().peek().builder() instanceof DataContainerNodeBuilder);
342 @Test(expected = IllegalStateException.class)
343 public void testEndNodeWhenNoBuildersOnStack() throws IOException {
344 prunerFullSchema.endNode();
348 public void testEndNodeWhenOneBuildersOnStack() throws IOException {
349 prunerFullSchema.stack().push(normalizedNodeBuilderWrapper);
350 prunerFullSchema.endNode();
351 assertEquals(normalizedNode, prunerFullSchema.normalizedNode());
355 public void testEndNodeSchemaMissing() throws IOException {
356 doReturn(new YangInstanceIdentifier.NodeIdentifier(TestModel.AUG_CONT_QNAME)).when(normalizedNodeBuilderWrapper).identifier();
358 prunerNoAugSchema.stack().push(normalizedNodeBuilderWrapper);
359 prunerNoAugSchema.endNode();
361 assertEquals(null, prunerNoAugSchema.normalizedNode());
365 public void testEndNodeWhenMoreThanOneBuilderOnStack() throws IOException {
366 // A little lazy in adding the "parent" builder
367 prunerFullSchema.stack().push(normalizedNodeBuilderWrapper);
368 prunerFullSchema.stack().push(normalizedNodeBuilderWrapper);
369 prunerFullSchema.endNode();
370 assertEquals(null, prunerFullSchema.normalizedNode());
372 verify(normalizedNodeContainerBuilder).addChild(any(NormalizedNode.class));
375 private NormalizedNode<?, ?> createTestContainer() {
376 byte[] bytes1 = {1,2,3};
377 LeafSetEntryNode<Object> entry1 = ImmutableLeafSetEntryNodeBuilder.create().withNodeIdentifier(
378 new YangInstanceIdentifier.NodeWithValue(TestModel.BINARY_LEAF_LIST_QNAME, bytes1)).
379 withValue(bytes1).build();
382 LeafSetEntryNode<Object> entry2 = ImmutableLeafSetEntryNodeBuilder.create().withNodeIdentifier(
383 new YangInstanceIdentifier.NodeWithValue(TestModel.BINARY_LEAF_LIST_QNAME, bytes2)).
384 withValue(bytes2).build();
386 LeafSetEntryNode<Object> entry3 = ImmutableLeafSetEntryNodeBuilder.create().withNodeIdentifier(
387 new YangInstanceIdentifier.NodeWithValue(TestModel.BINARY_LEAF_LIST_QNAME, null)).
388 withValue(null).build();
391 return TestModel.createBaseTestContainerBuilder().
392 withChild(ImmutableLeafSetNodeBuilder.create().withNodeIdentifier(
393 new YangInstanceIdentifier.NodeIdentifier(TestModel.BINARY_LEAF_LIST_QNAME)).
394 withChild(entry1).withChild(entry2).withChild(entry3).build()).
395 withChild(ImmutableNodes.leafNode(TestModel.SOME_BINARY_DATA_QNAME, new byte[]{1, 2, 3, 4})).
396 withChild(Builders.orderedMapBuilder().
397 withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TestModel.ORDERED_LIST_QNAME)).
398 withChild(ImmutableNodes.mapEntry(TestModel.ORDERED_LIST_ENTRY_QNAME,
399 TestModel.ID_QNAME, 11)).build()).