2 * Copyright (c) 2017 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.controller.cluster.datastore.node.utils.stream;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertTrue;
14 import java.io.ByteArrayInputStream;
15 import java.io.ByteArrayOutputStream;
16 import java.io.DataInputStream;
17 import java.io.DataOutputStream;
18 import java.io.IOException;
19 import java.nio.charset.StandardCharsets;
20 import java.util.concurrent.atomic.AtomicBoolean;
21 import javax.xml.transform.dom.DOMSource;
22 import org.junit.Test;
23 import org.opendaylight.yangtools.util.xml.UntrustedXML;
24 import org.opendaylight.yangtools.yang.common.QName;
25 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
26 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
27 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
29 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
30 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
31 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
32 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
33 import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
34 import org.xmlunit.builder.DiffBuilder;
36 public class SerializationUtilsTest {
37 private static final QName CONTAINER1 = QName.create("ns-1", "2017-03-17", "container1");
40 public void testSerializeDeserializeNodes() throws Exception {
41 final var normalizedNode = createNormalizedNode();
42 final var bytes = serialize(normalizedNode);
43 assertEquals(10567, bytes.length);
44 assertEquals(normalizedNode, deserialize(bytes));
48 public void testSerializeDeserializeAnyXmlNode() throws Exception {
49 final var parse = UntrustedXML.newDocumentBuilder().parse(
50 new ByteArrayInputStream("<xml><data/></xml>".getBytes(StandardCharsets.UTF_8)));
51 final var anyXmlNode = ImmutableNodes.newAnyxmlBuilder(DOMSource.class)
52 .withNodeIdentifier(id("anyXmlNode"))
53 .withValue(new DOMSource(parse))
55 final byte[] bytes = serialize(anyXmlNode);
56 assertEquals(113, bytes.length);
58 final var diff = DiffBuilder.compare(anyXmlNode.body().getNode())
59 // FIXME: why all this magic?
60 .withTest(((DOMSource) deserialize(bytes).body()).getNode().getOwnerDocument())
63 assertFalse(diff.toString(), diff.hasDifferences());
67 public void testSerializeDeserializePath() throws IOException {
68 final var path = YangInstanceIdentifier.builder()
69 .node(id("container1"))
70 .node(listId("list1", "keyName1", "keyValue1"))
71 .node(leafSetId("leafSer1", "leafSetValue1"))
74 final var bos = new ByteArrayOutputStream();
75 try (var out = new DataOutputStream(bos)) {
76 SerializationUtils.writePath(out, path);
79 final var bytes = bos.toByteArray();
80 assertEquals(105, bytes.length);
82 assertEquals(path, SerializationUtils.readPath(new DataInputStream(new ByteArrayInputStream(bytes))));
86 public void testSerializeDeserializePathAndNode() throws IOException {
87 final var path = YangInstanceIdentifier.of(id("container1"));
88 final var node = createNormalizedNode();
90 final var bos = new ByteArrayOutputStream();
91 try (var out = new DataOutputStream(bos)) {
92 SerializationUtils.writeNodeAndPath(out, path, node);
95 final byte[] bytes = bos.toByteArray();
96 assertEquals(10569, bytes.length);
98 final var applierCalled = new AtomicBoolean(false);
99 try (var in = new DataInputStream(new ByteArrayInputStream(bytes))) {
100 SerializationUtils.readNodeAndPath(in, applierCalled, (instance, deserializedPath, deserializedNode) -> {
101 assertEquals(path, deserializedPath);
102 assertEquals(node, deserializedNode);
103 applierCalled.set(true);
106 assertTrue(applierCalled.get());
109 private static NormalizedNode deserialize(final byte[] bytes) throws Exception {
110 return SerializationUtils.readNormalizedNode(new DataInputStream(new ByteArrayInputStream(bytes)))
114 private static byte[] serialize(final NormalizedNode node) throws Exception {
115 final var bos = new ByteArrayOutputStream();
116 SerializationUtils.writeNormalizedNode(new DataOutputStream(bos), node);
117 return bos.toByteArray();
120 private static ContainerNode createNormalizedNode() {
121 final var stringLeaf = createLeaf("stringLeaf", "stringValue");
122 final var entry1 = ImmutableNodes.newMapEntryBuilder()
123 .withNodeIdentifier(listId("mapNode", "key", "key1"))
124 .withChild(stringLeaf)
126 final var entry2 = ImmutableNodes.newMapEntryBuilder()
127 .withNodeIdentifier(listId("mapNode", "key", "key2"))
128 .withChild(stringLeaf)
131 return ImmutableNodes.newContainerBuilder()
132 .withNodeIdentifier(new NodeIdentifier(CONTAINER1))
133 .withChild(createLeaf("booleanLeaf", true))
134 .withChild(createLeaf("byteLeaf", (byte) 0))
135 .withChild(createLeaf("shortLeaf", (short) 55))
136 .withChild(createLeaf("intLeaf", 11))
137 .withChild(createLeaf("longLeaf", 151515L))
138 .withChild(stringLeaf)
139 .withChild(createLeaf("longStringLeaf", "0123456789".repeat(1000)))
140 .withChild(createLeaf("stringLeaf", QName.create("base", "qName")))
141 .withChild(createLeaf("stringLeaf", YangInstanceIdentifier.of(QName.create("test", "test"))))
142 .withChild(ImmutableNodes.newSystemMapBuilder()
143 .withNodeIdentifier(id("mapNode"))
147 .withChild(ImmutableNodes.newUserMapBuilder()
148 .withNodeIdentifier(id("orderedMapNode"))
152 .withChild(ImmutableNodes.newUnkeyedListBuilder()
153 .withNodeIdentifier(id("unkeyedList"))
154 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
155 .withNodeIdentifier(id("unkeyedList"))
156 .withChild(stringLeaf)
158 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
159 .withNodeIdentifier(id("unkeyedList"))
160 .withChild(stringLeaf)
163 .withChild(ImmutableNodes.newSystemLeafSetBuilder()
164 .withNodeIdentifier(id("leafSetNode"))
165 .withChild(createLeafSetEntry("leafSetNode", "leafSetValue1"))
166 .withChild(createLeafSetEntry("leafSetNode", "leafSetValue2"))
168 .withChild(ImmutableNodes.newUserLeafSetBuilder()
169 .withNodeIdentifier(id("orderedLeafSetNode"))
170 .withChild(createLeafSetEntry("orderedLeafSetNode", "value1"))
171 .withChild(createLeafSetEntry("orderedLeafSetNode", "value2"))
173 .withChild(createLeaf("aug1", "aug1Value"))
174 .withChild(createLeaf("aug2", "aug2Value"))
175 .withChild(ImmutableNodes.newChoiceBuilder()
176 .withNodeIdentifier(id("choiceNode"))
177 .withChild(createLeaf("choiceLeaf", 12))
182 private static <T> LeafNode<T> createLeaf(final String name, final T value) {
183 return ImmutableNodes.leafNode(id(name), value);
186 private static LeafSetEntryNode<Object> createLeafSetEntry(final String leafSet, final String value) {
187 return ImmutableNodes.leafSetEntry(leafSetId(leafSet, value));
190 private static NodeIdentifier id(final String name) {
191 return new NodeIdentifier(QName.create(CONTAINER1, name));
194 private static NodeIdentifierWithPredicates listId(final String listName, final String keyName,
195 final Object keyValue) {
196 return NodeIdentifierWithPredicates.of(QName.create(CONTAINER1, listName), QName.create(CONTAINER1, keyName),
200 private static <T> NodeWithValue<T> leafSetId(final String node, final T value) {
201 return new NodeWithValue<>(QName.create(CONTAINER1, node), value);