Map system-ordered keyed lists to Map
[mdsal.git] / binding / mdsal-binding-dom-codec / src / test / java / org / opendaylight / mdsal / binding / dom / codec / test / CachingCodecTest.java
index 03d5d7c1964a7c4b4ab0e574d7c1ffdc508b73a8..7c8fa7a72950b820315c06dc8de13df81f6b90f7 100644 (file)
@@ -8,57 +8,80 @@
 package org.opendaylight.mdsal.binding.dom.codec.test;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import java.util.Collection;
-import java.util.List;
+import java.util.Map;
 import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeNode;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataObjectCodecTreeNode;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeCachingCodec;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.TopBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListKey;
+import org.opendaylight.yang.gen.v1.urn.test.leaf.caching.codec.rev190201.Cont;
+import org.opendaylight.yang.gen.v1.urn.test.leaf.caching.codec.rev190201.ContBuilder;
+import org.opendaylight.yang.gen.v1.urn.test.leaf.caching.codec.rev190201.MyType;
+import org.opendaylight.yangtools.yang.binding.BindingObject;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.nodes.LazyLeafOperations;
 
 public class CachingCodecTest extends AbstractBindingCodecTest {
 
     private static final NodeIdentifier TOP_LEVEL_LIST_ARG = new NodeIdentifier(TopLevelList.QNAME);
     private static final InstanceIdentifier<Top> TOP_PATH = InstanceIdentifier.create(Top.class);
-    private static final List<TopLevelList> TWO_LIST = createList(2);
-    private static final List<TopLevelList> THREE_LIST = createList(3);
+    private static final Map<TopLevelListKey, TopLevelList> TWO_LIST = createList(2);
+    private static final Map<TopLevelListKey, TopLevelList> THREE_LIST = createList(3);
 
     private static final Top TOP_TWO_LIST_DATA = new TopBuilder().setTopLevelList(TWO_LIST).build();
     private static final Top TOP_THREE_LIST_DATA = new TopBuilder().setTopLevelList(THREE_LIST).build();
 
-    private BindingCodecTreeNode<Top> topNode;
+    private static final NodeIdentifier LEAF_ARG = new NodeIdentifier(QName.create(Cont.QNAME, "caching"));
+    private static final InstanceIdentifier<Cont> CONT_PATH = InstanceIdentifier.create(Cont.class);
+
+    private static final Cont CONT_DATA = new ContBuilder().setCaching(new MyType(dataValue())).setNonCaching("test")
+            .build();
+    private static final Cont CONT2_DATA = new ContBuilder().setCaching(new MyType(dataValue())).setNonCaching("test2")
+            .build();
+
+    private BindingDataObjectCodecTreeNode<Top> topNode;
+    private BindingDataObjectCodecTreeNode<Cont> contNode;
+
+    private static String dataValue() {
+        // We are battling interning here
+        return new StringBuilder("foo").toString();
+    }
 
     @Override
     @Before
     public void before() {
         super.before();
         topNode = registry.getCodecContext().getSubtreeCodec(TOP_PATH);
+        contNode = registry.getCodecContext().getSubtreeCodec(CONT_PATH);
     }
 
-    private static List<TopLevelList> createList(final int num) {
-
-        final ImmutableList.Builder<TopLevelList> builder = ImmutableList.builder();
+    private static Map<TopLevelListKey, TopLevelList> createList(final int num) {
+        final ImmutableMap.Builder<TopLevelListKey, TopLevelList> builder = ImmutableMap.builder();
         for (int i = 0; i < num; i++) {
             final TopLevelListKey key = new TopLevelListKey("test-" + i);
-            builder.add(new TopLevelListBuilder().withKey(key).build());
+            builder.put(key, new TopLevelListBuilder().withKey(key).build());
         }
         return builder.build();
     }
@@ -91,13 +114,26 @@ public class CachingCodecTest extends AbstractBindingCodecTest {
         verifyListItemSame(first, third);
     }
 
+    @Test
+    public void testLeafCache() {
+        // The integers should be distinct
+        assertNotSame(CONT_DATA.getCaching().getValue(), CONT2_DATA.getCaching().getValue());
+
+        final BindingNormalizedNodeCachingCodec<Cont> cachingCodec = createContCachingCodec(Cont.class, MyType.class);
+        final NormalizedNode<?, ?> first = cachingCodec.serialize(CONT_DATA);
+        final NormalizedNode<?, ?> second = cachingCodec.serialize(CONT2_DATA);
+
+        assertNotEquals(first, second);
+        verifyLeafItemSame(first, second);
+    }
+
     @Test
     public void testDefaultInvocation() {
         final BindingNormalizedNodeCachingCodec<Top> cachingCodec = createCachingCodec(Top.class, TopLevelList.class);
 
         final Top input = new TopBuilder().build();
         assertNull(input.getTopLevelList());
-        assertEquals(ImmutableList.of(), input.nonnullTopLevelList());
+        assertEquals(ImmutableMap.of(), input.nonnullTopLevelList());
 
         final NormalizedNode<?, ?> dom = cachingCodec.serialize(input);
         final Top output = cachingCodec.deserialize(dom);
@@ -105,7 +141,7 @@ public class CachingCodecTest extends AbstractBindingCodecTest {
         assertTrue(output.equals(input));
 
         assertNull(output.getTopLevelList());
-        assertEquals(ImmutableList.of(), output.nonnullTopLevelList());
+        assertEquals(ImmutableMap.of(), output.nonnullTopLevelList());
     }
 
     @SafeVarargs
@@ -114,6 +150,12 @@ public class CachingCodecTest extends AbstractBindingCodecTest {
         return topNode.createCachingCodec(ImmutableSet.copyOf(classes));
     }
 
+    @SafeVarargs
+    private final BindingNormalizedNodeCachingCodec<Cont> createContCachingCodec(
+            final Class<? extends BindingObject>... classes) {
+        return contNode.createCachingCodec(ImmutableSet.copyOf(classes));
+    }
+
     private static void verifyListItemSame(final NormalizedNode<?, ?> firstTop, final NormalizedNode<?, ?> secondTop) {
         final Collection<MapEntryNode> initialNodes = getListItems(firstTop).getValue();
         final MapNode secondMap = getListItems(secondTop);
@@ -128,4 +170,21 @@ public class CachingCodecTest extends AbstractBindingCodecTest {
     private static MapNode getListItems(final NormalizedNode<?, ?> top) {
         return (MapNode) ((DataContainerNode<?>) top).getChild(TOP_LEVEL_LIST_ARG).get();
     }
+
+    private static void verifyLeafItemSame(final NormalizedNode<?, ?> firstCont,
+            final NormalizedNode<?, ?> secondCont) {
+        final DataContainerChild<?, ?> first = ((DataContainerNode<?>) firstCont).getChild(LEAF_ARG).get();
+        assertTrue(first instanceof LeafNode);
+
+        final DataContainerChild<?, ?> second = ((DataContainerNode<?>) secondCont).getChild(LEAF_ARG).get();
+        assertTrue(second instanceof LeafNode);
+
+        if (LazyLeafOperations.isEnabled()) {
+            // The leaf nodes are transient, but the values should be the same
+            assertEquals(first, second);
+            assertSame(first.getValue(), second.getValue());
+        } else {
+            assertSame(first, second);
+        }
+    }
 }