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