Rename org.opendaylight.yangtools.yang.binding
[yangtools.git] / binding / binding-data-codec-dynamic / src / test / java / org / opendaylight / mdsal / binding / dom / codec / impl / LazyBindingMapTest.java
1 /*
2  * Copyright (c) 2020 PANTHEON.tech, 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.mdsal.binding.dom.codec.impl;
9
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;
18
19 import java.util.Collection;
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Map.Entry;
25 import java.util.Set;
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;
37
38 public class LazyBindingMapTest extends AbstractBindingCodecTest {
39     private static Top TOP;
40
41     @BeforeClass
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);
47         }
48
49         TOP = new TopBuilder().setTopLevelList(map).build();
50     }
51
52     @Test
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);
59     }
60
61     @Test
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());
66     }
67
68     @Test
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());
73     }
74
75     @Test
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()));
80     }
81
82     @Test
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()));
87     }
88
89     @Test
90     public void testIterValueIteration() {
91         assertSameIteratorObjects(prepareData().getTopLevelList().values());
92     }
93
94     @Test
95     public void testLookupValueIteration() {
96         final Map<TopLevelListKey, TopLevelList> list = prepareData().getTopLevelList();
97         // Force lookup state instantiation
98         assertFalse(list.containsKey(new TopLevelListKey("blah")));
99
100         assertSameIteratorObjects(list.values());
101     }
102
103     @Test
104     public void testIterKeysetIteration() {
105         assertSameIteratorObjects(prepareData().getTopLevelList().keySet());
106     }
107
108     @Test
109     public void testLookupKeysetIteration() {
110         final Map<TopLevelListKey, TopLevelList> list = prepareData().getTopLevelList();
111         // Force lookup state instantiation
112         assertFalse(list.containsKey(new TopLevelListKey("blah")));
113
114         assertSameIteratorObjects(list.keySet());
115     }
116
117     private static void assertSameIteratorObjects(final Collection<?> collection) {
118         final var iter1 = collection.iterator();
119         final var iter2 = collection.iterator();
120
121         while (iter1.hasNext()) {
122             // Both iterators should return same values
123             assertSame(iter1.next(), iter2.next());
124         }
125         assertFalse(iter2.hasNext());
126     }
127
128     @Test
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());
134     }
135
136     @Test
137     public void testLookupSameViews() {
138         final Map<TopLevelListKey, TopLevelList> list = prepareData().getTopLevelList();
139         // Force lookup state instantiation
140         assertFalse(list.containsKey(new TopLevelListKey("blah")));
141
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();
147
148         // .. right here ...
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()));
152
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));
158     }
159
160     @Test
161     public void testIterSameSize() {
162         final Map<TopLevelListKey, TopLevelList> list = prepareData().getTopLevelList();
163         // Force lookup state instantiation
164         assertFalse(list.containsKey(new TopLevelListKey("blah")));
165
166         assertEquals(list.size(), list.entrySet().size());
167         assertEquals(list.size(), list.keySet().size());
168         assertEquals(list.size(), list.values().size());
169     }
170
171     @Test
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());
177     }
178
179     @Test
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));
186     }
187
188     @Test
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)));
193     }
194
195     @Test
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)));
200     }
201
202     @Test
203     public void testLookupKey() {
204         final Map<TopLevelListKey, TopLevelList> list = prepareData().getTopLevelList();
205         for (TopLevelListKey key : TOP.getTopLevelList().keySet()) {
206             assertTrue(list.containsKey(key));
207         }
208
209         assertFalse(list.containsKey(new TopLevelListKey("blah")));
210     }
211
212     @Test
213     public void testLookupValue() {
214         final Map<TopLevelListKey, TopLevelList> list = prepareData().getTopLevelList();
215         for (TopLevelList val : TOP.getTopLevelList().values()) {
216             assertTrue(list.containsValue(val));
217         }
218
219         assertFalse(list.containsValue(new TopLevelListBuilder().setName("blah").build()));
220
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()))
224             .build()));
225     }
226
227     private Top prepareData() {
228         return thereAndBackAgain(InstanceIdentifier.create(Top.class), TOP);
229     }
230 }