Add SerializationUtils unit test
[controller.git] / opendaylight / md-sal / sal-clustering-commons / src / test / java / org / opendaylight / controller / cluster / datastore / node / utils / stream / SerializationUtilsTest.java
1 /*
2  * Copyright (c) 2017 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.controller.cluster.datastore.node.utils.stream;
9
10 import com.google.common.collect.ImmutableSet;
11 import java.io.ByteArrayInputStream;
12 import java.io.ByteArrayOutputStream;
13 import java.io.DataInputStream;
14 import java.io.DataOutput;
15 import java.io.DataOutputStream;
16 import java.nio.charset.Charset;
17 import java.util.Arrays;
18 import java.util.Set;
19 import java.util.concurrent.atomic.AtomicBoolean;
20 import java.util.stream.Collectors;
21 import javax.xml.transform.dom.DOMSource;
22 import org.custommonkey.xmlunit.Diff;
23 import org.custommonkey.xmlunit.XMLUnit;
24 import org.junit.Assert;
25 import org.junit.Test;
26 import org.opendaylight.yangtools.util.xml.UntrustedXML;
27 import org.opendaylight.yangtools.yang.common.QName;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
29 import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
30 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
31 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
32 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
33 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
35 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
36 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
37 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
38 import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
39 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
40 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
41 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
42 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
43 import org.w3c.dom.Document;
44
45 public class SerializationUtilsTest {
46
47     private static final QName CONTAINER_Q_NAME = QName.create("ns-1", "2017-03-17", "container1");
48
49     @Test
50     public void testSerializeDeserializeNodes() throws Exception {
51         final NormalizedNode<?, ?> normalizedNode = createNormalizedNode();
52         final byte[] bytes = SerializationUtils.serializeNormalizedNode(normalizedNode);
53         Assert.assertEquals(normalizedNode, SerializationUtils.deserializeNormalizedNode(bytes));
54
55     }
56
57     @Test
58     public void testSerializeDeserializeAnyXmlNode() throws Exception {
59         final ByteArrayInputStream is =
60                 new ByteArrayInputStream("<xml><data/></xml>".getBytes(Charset.defaultCharset()));
61         final Document parse = UntrustedXML.newDocumentBuilder().parse(is);
62         final AnyXmlNode anyXmlNode = Builders.anyXmlBuilder()
63                 .withNodeIdentifier(id("anyXmlNode"))
64                 .withValue(new DOMSource(parse))
65                 .build();
66         final byte[] bytes = SerializationUtils.serializeNormalizedNode(anyXmlNode);
67         final NormalizedNode<?, ?> deserialized = SerializationUtils.deserializeNormalizedNode(bytes);
68         final DOMSource value = (DOMSource) deserialized.getValue();
69         final Diff diff = XMLUnit.compareXML((Document) anyXmlNode.getValue().getNode(),
70                 value.getNode().getOwnerDocument());
71         Assert.assertTrue(diff.toString(), diff.similar());
72     }
73
74     @Test
75     public void testSerializeDeserializePath() throws Exception {
76         final ByteArrayOutputStream bos = new ByteArrayOutputStream();
77         final DataOutput out = new DataOutputStream(bos);
78         final YangInstanceIdentifier path = YangInstanceIdentifier.builder()
79                 .node(id("container1"))
80                 .node(autmentationId("list1", "list2"))
81                 .node(listId("list1", "keyName1", "keyValue1"))
82                 .node(leafSetId("leafSer1", "leafSetValue1"))
83                 .build();
84         SerializationUtils.serializePath(path, out);
85         final YangInstanceIdentifier deserialized =
86                 SerializationUtils.deserializePath(new DataInputStream(new ByteArrayInputStream(bos.toByteArray())));
87         Assert.assertEquals(path, deserialized);
88     }
89
90     @Test
91     public void testSerializeDeserializePathAndNode() throws Exception {
92         final ByteArrayOutputStream bos = new ByteArrayOutputStream();
93         final DataOutput out = new DataOutputStream(bos);
94         final NormalizedNode<?, ?> node = createNormalizedNode();
95         final YangInstanceIdentifier path = YangInstanceIdentifier.create(id("container1"));
96         SerializationUtils.serializePathAndNode(path, node, out);
97         final DataInputStream in = new DataInputStream(new ByteArrayInputStream(bos.toByteArray()));
98         final AtomicBoolean applierCalled = new AtomicBoolean(false);
99         SerializationUtils.deserializePathAndNode(in, applierCalled, (instance, deserializedPath, deserializedNode) -> {
100             Assert.assertEquals(path, deserializedPath);
101             Assert.assertEquals(node, deserializedNode);
102             applierCalled.set(true);
103         });
104         Assert.assertTrue(applierCalled.get());
105     }
106
107     private static NormalizedNode<?, ?> createNormalizedNode() {
108         final LeafSetNode<Object> leafSetNode = Builders.leafSetBuilder()
109                 .withNodeIdentifier(id("leafSetNode"))
110                 .withChild(createLeafSetEntry("leafSetNode", "leafSetValue1"))
111                 .withChild(createLeafSetEntry("leafSetNode", "leafSetValue2"))
112                 .build();
113         final LeafSetNode<Object> orderedLeafSetNode = Builders.orderedLeafSetBuilder()
114                 .withNodeIdentifier(id("orderedLeafSetNode"))
115                 .withChild(createLeafSetEntry("orderedLeafSetNode", "value1"))
116                 .withChild(createLeafSetEntry("orderedLeafSetNode", "value2"))
117                 .build();
118         final LeafNode<Boolean> booleanLeaf = createLeaf("booleanLeaf", true);
119         final LeafNode<Byte> byteLeaf = createLeaf("byteLeaf", (byte) 0);
120         final LeafNode<Short> shortLeaf = createLeaf("shortLeaf", (short) 55);
121         final LeafNode<Integer> intLeaf = createLeaf("intLeaf", 11);
122         final LeafNode<Long> longLeaf = createLeaf("longLeaf", 151515L);
123         final LeafNode<String> stringLeaf = createLeaf("stringLeaf", "stringValue");
124         final LeafNode<String> longStringLeaf = createLeaf("longStringLeaf", getLongString());
125         final LeafNode<QName> qNameLeaf = createLeaf("stringLeaf", QName.create("base", "qName"));
126         final LeafNode<YangInstanceIdentifier> idLeaf = createLeaf("stringLeaf", YangInstanceIdentifier.EMPTY);
127         final MapEntryNode entry1 = Builders.mapEntryBuilder()
128                 .withNodeIdentifier(listId("mapNode", "key", "key1"))
129                 .withChild(stringLeaf)
130                 .build();
131         final MapEntryNode entry2 = Builders.mapEntryBuilder()
132                 .withNodeIdentifier(listId("mapNode", "key", "key2"))
133                 .withChild(stringLeaf)
134                 .build();
135         final MapNode mapNode = Builders.mapBuilder()
136                 .withNodeIdentifier(id("mapNode"))
137                 .withChild(entry1)
138                 .withChild(entry2)
139                 .build();
140         final OrderedMapNode orderedMapNode = Builders.orderedMapBuilder()
141                 .withNodeIdentifier(id("orderedMapNode"))
142                 .withChild(entry2)
143                 .withChild(entry1)
144                 .build();
145         final UnkeyedListEntryNode unkeyedListEntry1 = Builders.unkeyedListEntryBuilder()
146                 .withNodeIdentifier(id("unkeyedList"))
147                 .withChild(stringLeaf)
148                 .build();
149         final UnkeyedListEntryNode unkeyedListEntry2 = Builders.unkeyedListEntryBuilder()
150                 .withNodeIdentifier(id("unkeyedList"))
151                 .withChild(stringLeaf)
152                 .build();
153         final UnkeyedListNode unkeyedListNode = Builders.unkeyedListBuilder()
154                 .withNodeIdentifier(id("unkeyedList"))
155                 .withChild(unkeyedListEntry1)
156                 .withChild(unkeyedListEntry2)
157                 .build();
158         final ImmutableSet<QName> childNames =
159                 ImmutableSet.of(QName.create(CONTAINER_Q_NAME, "aug1"), QName.create(CONTAINER_Q_NAME, "aug1"));
160         final AugmentationNode augmentationNode = Builders.augmentationBuilder()
161                 .withNodeIdentifier(new YangInstanceIdentifier.AugmentationIdentifier(childNames))
162                 .withChild(createLeaf("aug1", "aug1Value"))
163                 .withChild(createLeaf("aug2", "aug2Value"))
164                 .build();
165         final ChoiceNode choiceNode = Builders.choiceBuilder()
166                 .withNodeIdentifier(id("choiceNode"))
167                 .withChild(createLeaf("choiceLeaf", 12))
168                 .build();
169         return Builders.containerBuilder()
170                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(CONTAINER_Q_NAME))
171                 .withChild(booleanLeaf)
172                 .withChild(byteLeaf)
173                 .withChild(shortLeaf)
174                 .withChild(intLeaf)
175                 .withChild(longLeaf)
176                 .withChild(stringLeaf)
177                 .withChild(longStringLeaf)
178                 .withChild(qNameLeaf)
179                 .withChild(idLeaf)
180                 .withChild(mapNode)
181                 .withChild(orderedMapNode)
182                 .withChild(unkeyedListNode)
183                 .withChild(leafSetNode)
184                 .withChild(orderedLeafSetNode)
185                 .withChild(augmentationNode)
186                 .withChild(choiceNode)
187                 .build();
188     }
189
190     private static <T> LeafNode<T> createLeaf(final String name, final T value) {
191         return ImmutableNodes.leafNode(id(name), value);
192     }
193
194     private static LeafSetEntryNode<Object> createLeafSetEntry(final String leafSet, final String value) {
195         return Builders.leafSetEntryBuilder()
196                 .withNodeIdentifier(leafSetId(leafSet, value))
197                 .withValue(value)
198                 .build();
199     }
200
201     private static YangInstanceIdentifier.NodeIdentifier id(final String name) {
202         return new YangInstanceIdentifier.NodeIdentifier(QName.create(CONTAINER_Q_NAME, name));
203     }
204
205     private static YangInstanceIdentifier.NodeIdentifierWithPredicates listId(final String listName,
206                                                                               final String keyName,
207                                                                               final Object keyValue) {
208         return new YangInstanceIdentifier.NodeIdentifierWithPredicates(QName.create(CONTAINER_Q_NAME, listName),
209                 QName.create(CONTAINER_Q_NAME, keyName), keyValue);
210     }
211
212     private static <T> YangInstanceIdentifier.NodeWithValue<T> leafSetId(final String node, final T value) {
213         return new YangInstanceIdentifier.NodeWithValue<>(QName.create(CONTAINER_Q_NAME, node), value);
214     }
215
216     private static YangInstanceIdentifier.AugmentationIdentifier autmentationId(final String... nodes) {
217         final Set<QName> qNames = Arrays.stream(nodes)
218                 .map(node -> QName.create(CONTAINER_Q_NAME, node))
219                 .collect(Collectors.toSet());
220         return new YangInstanceIdentifier.AugmentationIdentifier(qNames);
221     }
222
223     private static String getLongString() {
224         final StringBuilder builder = new StringBuilder(10000);
225         for (int i = 0; i < 1000; i++) {
226             builder.append("0123456789");
227         }
228         return builder.toString();
229     }
230 }