Fix checkstyle violations in hwvtepsouthbound-impl
[ovsdb.git] / hwvtepsouthbound / hwvtepsouthbound-impl / src / test / java / org / opendaylight / ovsdb / hwvtepsouthbound / HwvtepDataChangeListenerTest.java
1 /*
2  * Copyright (c) 2016, 2017 Ericsson India Global Services Pvt Ltd. 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
9 package org.opendaylight.ovsdb.hwvtepsouthbound;
10
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertTrue;
13 import static org.mockito.Matchers.any;
14 import static org.mockito.Mockito.times;
15 import static org.mockito.Mockito.verify;
16 import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
17 import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
18
19 import com.google.common.collect.Lists;
20 import java.lang.reflect.Field;
21 import java.lang.reflect.Modifier;
22 import java.util.Iterator;
23 import java.util.List;
24 import org.apache.commons.lang3.reflect.FieldUtils;
25 import org.junit.After;
26 import org.junit.Before;
27 import org.junit.Test;
28 import org.junit.runner.RunWith;
29 import org.mockito.Matchers;
30 import org.mockito.Mockito;
31 import org.opendaylight.ovsdb.hwvtepsouthbound.transact.DependencyQueue;
32 import org.opendaylight.ovsdb.lib.operations.Operations;
33 import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
34 import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
35 import org.opendaylight.ovsdb.schema.hardwarevtep.McastMacsRemote;
36 import org.opendaylight.ovsdb.schema.hardwarevtep.UcastMacsRemote;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
40 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
41 import org.opendaylight.yangtools.yang.binding.DataObject;
42 import org.powermock.api.mockito.PowerMockito;
43 import org.powermock.core.classloader.annotations.PrepareForTest;
44 import org.powermock.modules.junit4.PowerMockRunner;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 /**
49  * Unit tests for the data-tree change listener.
50  */
51 @RunWith(PowerMockRunner.class)
52 @PrepareForTest({HwvtepConnectionInstance.class, HwvtepConnectionManager.class, Operations.class})
53 public class HwvtepDataChangeListenerTest extends DataChangeListenerTestBase {
54
55     static Logger LOG = LoggerFactory.getLogger(HwvtepDataChangeListenerTest.class);
56
57     String[][] ucastMacs = new String[][]{
58             {"20:00:00:00:00:01", "11.10.10.1", "192.168.122.20", "ls0"},
59             {"20:00:00:00:00:02", "11.10.10.2", "192.168.122.20", "ls0"},
60             {"20:00:00:00:00:03", "11.10.10.3", "192.168.122.30", "ls1"},
61             {"20:00:00:00:00:04", "11.10.10.4", "192.168.122.30", "ls1"}
62     };
63
64     String[][] logicalSwitches = new String[][]{
65             {"ls0", "100"},
66             {"ls1", "200"},
67     };
68
69     String[][] terminationPoints = new String[][]{
70             {"192.168.122.10"},
71             {"192.168.122.20"},
72             {"192.168.122.30"},
73             {"192.168.122.40"}
74     };
75
76     String[][] mcastMacs = new String[][]{
77             {"FF:FF:FF:FF:FF:FF", "ls0", "192.168.122.20", "192.168.122.30"},
78             {"FF:FF:FF:FF:FF:FF", "ls1", "192.168.122.10", "192.168.122.30"}
79     };
80
81     String[][] mcastMac2 = new String[][]{
82             {"FF:FF:FF:FF:FF:FF", "ls0", "192.168.122.20", "192.168.122.10"},
83             {"FF:FF:FF:FF:FF:FF", "ls1", "192.168.122.10", "192.168.122.20"}
84     };
85
86     String[][] mcastMac3WithZeroLocators = new String[][]{
87             {"FF:FF:FF:FF:FF:FF", "ls0"},
88             {"FF:FF:FF:FF:FF:FF", "ls1"}
89     };
90
91     HwvtepOperationalDataChangeListener opDataChangeListener;
92
93     @Before
94     public void setupListener() throws Exception {
95         setFinalStatic(DependencyQueue.class, "EXECUTOR_SERVICE", PowerMockito.mock(SameThreadScheduledExecutor.class,
96                 Mockito.CALLS_REAL_METHODS));
97         opDataChangeListener = new HwvtepOperationalDataChangeListener(dataBroker, hwvtepConnectionManager,
98                 connectionInstance);
99     }
100
101     @After
102     public void cleanupListener() throws Exception {
103         opDataChangeListener.close();
104     }
105
106     @Override
107     void setFinalStatic(Class cls, String fieldName, Object newValue) throws Exception {
108         Field[] fields = FieldUtils.getAllFields(cls);
109         for (Field field : fields) {
110             if (fieldName.equals(field.getName())) {
111                 field.setAccessible(true);
112                 Field modifiersField = Field.class.getDeclaredField("modifiers");
113                 modifiersField.setAccessible(true);
114                 modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
115                 field.set(null, newValue);
116                 break;
117             }
118         }
119     }
120
121     @Test
122     public <T extends DataObject> void testLogicalSwitchAdd() throws Exception {
123         addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
124         verifyThatLogicalSwitchCreated();
125     }
126
127     @Test
128     public <T extends DataObject> void testLogicalSwitchDelete() throws Exception {
129         addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
130         addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
131         resetOperations();
132         deleteData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
133         verify(Operations.op,  times(10)).delete(any());
134     }
135
136     @Test
137     public <T extends DataObject> void testUcastMacAdd() throws Exception {
138         addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
139         addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
140         resetOperations();
141         addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
142         addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs);
143         //4 ucast macs + 2 termination points
144         verify(Operations.op,  times(6)).insert(any(UcastMacsRemote.class));
145         //TODO add finer grained validation
146     }
147
148     @Test
149     public <T extends DataObject> void testUcastMacAddWithoutConfigTep() throws Exception {
150         addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
151         addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
152         resetOperations();
153         addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs);
154         //4 ucast macs + 2 termination points
155         verify(Operations.op,  times(6)).insert(any(UcastMacsRemote.class));
156         //TODO add finer grained validation
157     }
158
159     @Test
160     public <T extends DataObject> void testUcastMacDelete() throws Exception {
161         addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
162         addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
163         addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
164         addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs);
165         addData(OPERATIONAL, RemoteUcastMacs.class, ucastMacs);
166         addData(OPERATIONAL, TerminationPoint.class, terminationPoints);
167
168         resetOperations();
169         deleteData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs);
170         verify(Operations.op,  times(4)).delete(any());
171         //TODO add finer grained validation
172     }
173
174     @Test
175     public <T extends DataObject> void testMcastMacAdd() throws Exception {
176         addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
177         addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
178         resetOperations();
179         addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
180         addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs);
181         //2 mcast macs + 2 locator sets + 3 termination points
182         verify(Operations.op,  times(7)).insert(Matchers.<McastMacsRemote>any());
183     }
184
185     @Test
186     public <T extends DataObject> void testMcastMacAddWithoutConfigTep() throws Exception {
187         addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
188         addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
189         resetOperations();
190         addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs);
191         //2 mcast macs + 2 locator sets + 3 termination points
192         verify(Operations.op,  times(7)).insert(Matchers.<McastMacsRemote>any());
193     }
194
195     @Test
196     public <T extends DataObject> void testMcastMacDelete() throws Exception {
197         addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
198         addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
199         addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
200         addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs);
201         addData(OPERATIONAL, TerminationPoint.class, terminationPoints);
202         addData(OPERATIONAL, RemoteMcastMacs.class, mcastMacs);
203
204         resetOperations();
205         deleteData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs);
206         verify(Operations.op,  times(2)).delete(Matchers.any());
207     }
208
209     @Test
210     public <T extends DataObject> void testAddMacs() throws Exception {
211         addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
212         addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
213         resetOperations();
214         addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
215         addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs);
216         verify(Operations.op,  times(6)).insert(any(UcastMacsRemote.class));
217
218         addData(OPERATIONAL, TerminationPoint.class, terminationPoints);
219         addData(OPERATIONAL, RemoteUcastMacs.class, ucastMacs);
220         resetOperations();
221         addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs);
222         //2 mcast mac + 2 locator sets ( termination point already added )
223         verify(Operations.op,  times(4)).insert(Matchers.<McastMacsRemote>any());
224     }
225
226     @Test
227     public <T extends DataObject> void testUpdateMacs() throws Exception {
228         addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
229         addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
230         resetOperations();
231         addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
232         addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs);
233         verify(Operations.op,  times(6)).insert(any(UcastMacsRemote.class));
234
235         addData(OPERATIONAL, TerminationPoint.class, terminationPoints);
236         addData(OPERATIONAL, RemoteUcastMacs.class, ucastMacs);
237         resetOperations();
238         addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs);
239         verify(Operations.op,  times(4)).insert(Matchers.<McastMacsRemote>any());
240         addData(OPERATIONAL, RemoteMcastMacs.class, mcastMacs);
241
242         resetOperations();
243         addData(CONFIGURATION, RemoteMcastMacs.class, mcastMac2);
244         verify(Operations.op,  times(2)).insert(Matchers.<McastMacsRemote>any());
245         verify(Operations.op,  times(2)).update(Matchers.<McastMacsRemote>any());
246         verify(Operations.op,  times(0)).delete(Matchers.any());
247     }
248
249     @Test
250     public <T extends DataObject> void testUpdateMacsWithZeroLocators() throws Exception {
251         addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
252         addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
253         resetOperations();
254         addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
255         addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs);
256         verify(Operations.op,  times(6)).insert(any(UcastMacsRemote.class));
257
258         addData(OPERATIONAL, TerminationPoint.class, terminationPoints);
259         addData(OPERATIONAL, RemoteUcastMacs.class, ucastMacs);
260         resetOperations();
261         addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs);
262         verify(Operations.op,  times(4)).insert(Matchers.<McastMacsRemote>any());
263         addData(OPERATIONAL, RemoteMcastMacs.class, mcastMacs);
264
265         resetOperations();
266         addData(CONFIGURATION, RemoteMcastMacs.class, mcastMac3WithZeroLocators);
267         verify(Operations.op,  times(2)).delete(Matchers.any());
268     }
269
270     @Test
271     public <T extends DataObject> void testBackToBackMacsUpdate() throws Exception {
272         addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
273         addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
274         resetOperations();
275         addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
276         addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs);
277         verify(Operations.op,  times(6)).insert(any(UcastMacsRemote.class));
278
279         resetOperations();
280         addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs);
281         //2 mcast mac + 2 locator sets ( termination point already added )
282         verify(Operations.op,  times(0)).insert(Matchers.<McastMacsRemote>any());
283         resetOperations();
284         addData(OPERATIONAL, TerminationPoint.class, terminationPoints);
285         addData(OPERATIONAL, RemoteUcastMacs.class, ucastMacs);
286         connectionInstance.getDeviceInfo().onOperDataAvailable();
287         //2 mcast mac + 2 locator sets ( termination point already added )
288         verify(Operations.op,  times(4)).insert(Matchers.<McastMacsRemote>any());
289
290         resetOperations();
291         addData(CONFIGURATION, RemoteMcastMacs.class, mcastMac2);
292         verify(Operations.op,  times(0)).insert(Matchers.<McastMacsRemote>any());
293         addData(OPERATIONAL, RemoteMcastMacs.class, mcastMacs);
294         connectionInstance.getDeviceInfo().onOperDataAvailable();
295         verify(Operations.op,  times(2)).insert(Matchers.<McastMacsRemote>any());
296         verify(Operations.op,  times(2)).update(Matchers.<McastMacsRemote>any());
297     }
298
299     private void verifyThatLogicalSwitchCreated() {
300         //The transactions could be firing in two different mdsal updates intermittently
301         //verify(ovsdbClient, times(1)).transact(any(DatabaseSchema.class), any(List.class));
302         verify(Operations.op, times(2)).insert(any(LogicalSwitch.class));
303
304         assertNotNull(insertOpCapture.getAllValues());
305         assertTrue(insertOpCapture.getAllValues().size() == 2);
306
307         List<String> expected = Lists.newArrayList("ls0", "ls1");
308         Iterator<TypedBaseTable> it = insertOpCapture.getAllValues().iterator();
309         while (it.hasNext()) {
310             TypedBaseTable table = it.next();
311             assertTrue(table instanceof LogicalSwitch);
312             LogicalSwitch ls = (LogicalSwitch)table;
313             assertTrue(expected.contains(ls.getName()));
314             expected.remove(ls.getName());
315             it.next();
316         }
317     }
318 }