2 * Copyright (c) 2020 PANTHEON.tech, 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.mdsal.binding.dom.codec.impl;
10 import static org.hamcrest.CoreMatchers.instanceOf;
11 import static org.hamcrest.MatcherAssert.assertThat;
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertFalse;
14 import static org.junit.Assert.assertSame;
15 import static org.junit.Assert.assertThrows;
16 import static org.junit.Assert.assertTrue;
17 import static org.mockito.Mockito.mock;
19 import java.util.Collection;
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.List;
24 import java.util.Map.Entry;
26 import org.junit.BeforeClass;
27 import org.junit.Test;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.TopBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelList;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.top.level.list.NestedListBuilder;
34 import org.opendaylight.yangtools.binding.lib.DataObject;
35 import org.opendaylight.yangtools.binding.lib.InstanceIdentifier;
36 import org.opendaylight.yangtools.binding.lib.KeyAware;
38 public class LazyBindingMapTest extends AbstractBindingCodecTest {
39 private static Top TOP;
42 public static void prepareTop() {
43 final Map<TopLevelListKey, TopLevelList> map = new HashMap<>();
44 for (int i = 0; i < 2 * LazyBindingMap.LAZY_CUTOFF; i++) {
45 final TopLevelList item = new TopLevelListBuilder().setName(String.valueOf(i)).build();
46 map.put(item.key(), item);
49 TOP = new TopBuilder().setTopLevelList(map).build();
53 public void testSimpleEquals() {
54 final Top actual = prepareData();
55 assertThat(actual.getTopLevelList(), instanceOf(LazyBindingMap.class));
56 // AbstractMap.equals() goes through its entrySet and performs lookup for each key, hence it is excercising
57 // primarily LookupState
58 assertEquals(TOP, actual);
62 public void testEqualEntrySet() {
63 final Top actual = prepareData();
64 // Check equality based on entry set. This primarily exercises IterState
65 assertEquals(TOP.getTopLevelList().entrySet(), actual.getTopLevelList().entrySet());
69 public void testEqualKeySet() {
70 final Top actual = prepareData();
71 // Check equality based on key set. This primarily exercises IterState
72 assertEquals(TOP.getTopLevelList().keySet(), actual.getTopLevelList().keySet());
76 public void testIterKeySetLookup() {
77 final Top actual = prepareData();
78 // Forces IterState but then switches to key lookups
79 assertTrue(actual.getTopLevelList().keySet().containsAll(TOP.getTopLevelList().keySet()));
83 public void testIterEntrySetLookup() {
84 final Top actual = prepareData();
85 // Forces IterState but then switches to value lookups
86 assertTrue(actual.getTopLevelList().entrySet().containsAll(TOP.getTopLevelList().entrySet()));
90 public void testIterValueIteration() {
91 assertSameIteratorObjects(prepareData().getTopLevelList().values());
95 public void testLookupValueIteration() {
96 final Map<TopLevelListKey, TopLevelList> list = prepareData().getTopLevelList();
97 // Force lookup state instantiation
98 assertFalse(list.containsKey(new TopLevelListKey("blah")));
100 assertSameIteratorObjects(list.values());
104 public void testIterKeysetIteration() {
105 assertSameIteratorObjects(prepareData().getTopLevelList().keySet());
109 public void testLookupKeysetIteration() {
110 final Map<TopLevelListKey, TopLevelList> list = prepareData().getTopLevelList();
111 // Force lookup state instantiation
112 assertFalse(list.containsKey(new TopLevelListKey("blah")));
114 assertSameIteratorObjects(list.keySet());
117 private static void assertSameIteratorObjects(final Collection<?> collection) {
118 final var iter1 = collection.iterator();
119 final var iter2 = collection.iterator();
121 while (iter1.hasNext()) {
122 // Both iterators should return same values
123 assertSame(iter1.next(), iter2.next());
125 assertFalse(iter2.hasNext());
129 public void testIterSameViews() {
130 final Map<TopLevelListKey, TopLevelList> list = prepareData().getTopLevelList();
131 assertSame(list.values(), list.values());
132 assertSame(list.keySet(), list.keySet());
133 assertSame(list.entrySet(), list.entrySet());
137 public void testLookupSameViews() {
138 final Map<TopLevelListKey, TopLevelList> list = prepareData().getTopLevelList();
139 // Force lookup state instantiation
140 assertFalse(list.containsKey(new TopLevelListKey("blah")));
142 // Careful now ... first compare should end up changing the iteration of keyset/entryset
143 final Set<TopLevelListKey> keySet1 = list.keySet();
144 final Set<TopLevelListKey> keySet2 = list.keySet();
145 final Set<Entry<TopLevelListKey, TopLevelList>> entrySet1 = list.entrySet();
146 final Set<Entry<TopLevelListKey, TopLevelList>> entrySet2 = list.entrySet();
149 assertSame(list.values(), list.values());
150 // ... so this should end up iterating slightly differently
151 assertEquals(new HashSet<>(list.values()), new HashSet<>(list.values()));
153 // ... and as we do not reuse keyset/entryset, we need to run full compare
154 assertEquals(keySet1, keySet2);
155 assertEquals(keySet1, new HashSet<>(keySet2));
156 assertEquals(entrySet1, entrySet2);
157 assertEquals(entrySet1, new HashSet<>(entrySet2));
161 public void testIterSameSize() {
162 final Map<TopLevelListKey, TopLevelList> list = prepareData().getTopLevelList();
163 // Force lookup state instantiation
164 assertFalse(list.containsKey(new TopLevelListKey("blah")));
166 assertEquals(list.size(), list.entrySet().size());
167 assertEquals(list.size(), list.keySet().size());
168 assertEquals(list.size(), list.values().size());
172 public void testLookupSameSize() {
173 final Map<TopLevelListKey, TopLevelList> list = prepareData().getTopLevelList();
174 assertEquals(list.size(), list.entrySet().size());
175 assertEquals(list.size(), list.keySet().size());
176 assertEquals(list.size(), list.values().size());
180 public void testImmutableThrows() {
181 final Map<TopLevelListKey, TopLevelList> list = prepareData().getTopLevelList();
182 // Various asserts for completeness' sake
183 assertThrows(UnsupportedOperationException.class, () -> list.clear());
184 assertThrows(UnsupportedOperationException.class, () -> list.remove(null));
185 assertThrows(UnsupportedOperationException.class, () -> list.putAll(null));
189 public void testLookupContainsValueThrows() {
190 final Map<TopLevelListKey, TopLevelList> list = prepareData().getTopLevelList();
191 assertThrows(NullPointerException.class, () -> list.containsValue(null));
192 assertThrows(ClassCastException.class, () -> list.containsValue(mock(DataObject.class)));
196 public void testLookupContainsKeyThrows() {
197 final Map<TopLevelListKey, TopLevelList> list = prepareData().getTopLevelList();
198 assertThrows(NullPointerException.class, () -> list.containsKey(null));
199 assertThrows(ClassCastException.class, () -> list.containsKey(mock(KeyAware.class)));
203 public void testLookupKey() {
204 final Map<TopLevelListKey, TopLevelList> list = prepareData().getTopLevelList();
205 for (TopLevelListKey key : TOP.getTopLevelList().keySet()) {
206 assertTrue(list.containsKey(key));
209 assertFalse(list.containsKey(new TopLevelListKey("blah")));
213 public void testLookupValue() {
214 final Map<TopLevelListKey, TopLevelList> list = prepareData().getTopLevelList();
215 for (TopLevelList val : TOP.getTopLevelList().values()) {
216 assertTrue(list.containsValue(val));
219 assertFalse(list.containsValue(new TopLevelListBuilder().setName("blah").build()));
221 // We checked this key, but this is a different object
222 assertFalse(list.containsValue(new TopLevelListBuilder(TOP.getTopLevelList().values().iterator().next())
223 .setNestedList(List.of(new NestedListBuilder().setName("foo").build()))
227 private Top prepareData() {
228 return thereAndBackAgain(InstanceIdentifier.create(Top.class), TOP);