Fix deprecation warnings around addAugmentation()
[ovsdb.git] / southbound / southbound-impl / src / test / java / org / opendaylight / ovsdb / southbound / OvsdbConnectionManagerTest.java
1 /*
2  * Copyright © 2015, 2017 Inocybe Technologies 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.southbound;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.mockito.ArgumentMatchers.any;
13 import static org.mockito.ArgumentMatchers.anyInt;
14 import static org.mockito.Mockito.doNothing;
15 import static org.mockito.Mockito.doReturn;
16 import static org.mockito.Mockito.mock;
17 import static org.mockito.Mockito.verify;
18 import static org.mockito.Mockito.when;
19 import static org.powermock.api.support.membermodification.MemberMatcher.field;
20 import static org.powermock.api.support.membermodification.MemberModifier.suppress;
21
22 import com.google.common.util.concurrent.FluentFuture;
23 import com.google.common.util.concurrent.Futures;
24 import java.net.InetAddress;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.Map;
28 import java.util.Optional;
29 import java.util.concurrent.ConcurrentHashMap;
30 import org.junit.Before;
31 import org.junit.Ignore;
32 import org.junit.Test;
33 import org.junit.runner.RunWith;
34 import org.mockito.Mock;
35 import org.mockito.Mockito;
36 import org.opendaylight.mdsal.binding.api.DataBroker;
37 import org.opendaylight.mdsal.binding.api.ReadTransaction;
38 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
39 import org.opendaylight.mdsal.eos.binding.api.Entity;
40 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipChange;
41 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
42 import org.opendaylight.mdsal.eos.common.api.EntityOwnershipChangeState;
43 import org.opendaylight.ovsdb.lib.OvsdbClient;
44 import org.opendaylight.ovsdb.lib.OvsdbConnection;
45 import org.opendaylight.ovsdb.lib.OvsdbConnectionInfo;
46 import org.opendaylight.ovsdb.lib.impl.OvsdbConnectionService;
47 import org.opendaylight.ovsdb.southbound.reconciliation.ReconciliationManager;
48 import org.opendaylight.ovsdb.southbound.transactions.md.TransactionCommand;
49 import org.opendaylight.ovsdb.southbound.transactions.md.TransactionInvoker;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAttributes;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
55 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
56 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
57 import org.opendaylight.yangtools.yang.common.Uint16;
58 import org.powermock.api.mockito.PowerMockito;
59 import org.powermock.api.support.membermodification.MemberMatcher;
60 import org.powermock.api.support.membermodification.MemberModifier;
61 import org.powermock.core.classloader.annotations.PrepareForTest;
62 import org.powermock.modules.junit4.PowerMockRunner;
63 import org.powermock.reflect.Whitebox;
64
65 @RunWith(PowerMockRunner.class)
66 @PrepareForTest({ SouthboundMapper.class, OvsdbConnectionManager.class, OvsdbConnectionService.class,
67         InstanceIdentifier.class, SouthboundUtil.class, Optional.class })
68 public class OvsdbConnectionManagerTest {
69
70     @Mock private OvsdbConnectionManager ovsdbConnManager;
71     @Mock private DataBroker db;
72     @Mock private TransactionInvoker txInvoker;
73     @Mock private EntityOwnershipService entityOwnershipService;
74     @Mock private OvsdbConnection ovsdbConnection;
75     @Mock private OvsdbClient externalClient;
76     @Mock private ReconciliationManager reconciliationManager;
77     private Map<ConnectionInfo,OvsdbConnectionInstance> clients;
78     private Map<ConnectionInfo,InstanceIdentifier<Node>> instanceIdentifiers;
79     private Map<Entity, OvsdbConnectionInstance> entityConnectionMap;
80
81     @Mock private InstanceIdentifier<Node> iid;
82
83     @Before
84     public void setUp() throws Exception {
85         ovsdbConnManager = PowerMockito.mock(OvsdbConnectionManager.class, Mockito.CALLS_REAL_METHODS);
86         field(OvsdbConnectionManager.class, "db").set(ovsdbConnManager, db);
87         field(OvsdbConnectionManager.class, "txInvoker").set(ovsdbConnManager, txInvoker);
88         field(OvsdbConnectionManager.class, "entityOwnershipService").set(ovsdbConnManager, entityOwnershipService);
89         field(OvsdbConnectionManager.class, "reconciliationManager").set(ovsdbConnManager, reconciliationManager);
90         field(OvsdbConnectionManager.class, "ovsdbConnection").set(ovsdbConnManager, ovsdbConnection);
91         field(OvsdbConnectionManager.class, "alreadyProcessedClients").set(ovsdbConnManager, new HashMap<>());
92         entityConnectionMap = new ConcurrentHashMap<>();
93
94         OvsdbConnectionInfo info = mock(OvsdbConnectionInfo.class);
95         doReturn(mock(InetAddress.class)).when(info).getRemoteAddress();
96         doReturn(8080).when(info).getRemotePort();
97         doReturn(mock(InetAddress.class)).when(info).getLocalAddress();
98         doReturn(8080).when(info).getLocalPort();
99
100         externalClient = mock(OvsdbClient.class, Mockito.RETURNS_DEEP_STUBS);
101         doReturn(info).when(externalClient).getConnectionInfo();
102         doReturn(Futures.immediateFuture(Collections.singletonList("Open_vSwitch"))).when(externalClient)
103             .getDatabases();
104
105         PowerMockito.mockStatic(SouthboundUtil.class);
106         when(SouthboundUtil.connectionInfoToString(any(ConnectionInfo.class))).thenReturn("192.18.120.31:8080");
107     }
108
109     @Test
110     public void testConnected() throws Exception {
111         OvsdbConnectionInstance client = mock(OvsdbConnectionInstance.class);
112         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "connectedButCallBacksNotRegistered",
113                 OvsdbClient.class));
114         when(ovsdbConnManager.connectedButCallBacksNotRegistered(any(OvsdbClient.class))).thenReturn(client);
115         doNothing().when(client).registerCallbacks(any());
116
117         //TODO: Write unit tests for EntityOwnershipService
118         when(client.getInstanceIdentifier()).thenReturn(mock(InstanceIdentifier.class));
119         field(OvsdbConnectionManager.class, "entityConnectionMap").set(ovsdbConnManager, entityConnectionMap);
120         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getEntityFromConnectionInstance",
121                 OvsdbConnectionInstance.class));
122
123         //TODO: Write unit tests for entity ownership service related code.
124         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "registerEntityForOwnership",
125                 OvsdbConnectionInstance.class));
126
127         ReadTransaction tx = mock(ReadTransaction.class);
128         when(db.newReadOnlyTransaction()).thenReturn(tx);
129         when(tx.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class)))
130                 .thenReturn(mock(FluentFuture.class));
131         when(client.getInstanceIdentifier()).thenReturn(mock(InstanceIdentifier.class));
132
133         ovsdbConnManager.connected(externalClient);
134     }
135
136     @SuppressWarnings("unchecked")
137     @Test
138     public void testConnectedButCallBacksNotRegistered() throws Exception {
139         ConnectionInfo key = mock(ConnectionInfo.class);
140
141         PowerMockito.mockStatic(SouthboundMapper.class);
142         when(SouthboundMapper.createConnectionInfo(any(OvsdbClient.class))).thenReturn(key);
143
144         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getInstanceIdentifier", ConnectionInfo.class));
145         when(ovsdbConnManager.getInstanceIdentifier(key)).thenReturn(mock(InstanceIdentifier.class));
146
147         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getConnectionInstance", ConnectionInfo.class));
148         when(ovsdbConnManager.getConnectionInstance(key)).thenReturn(null);
149
150         OvsdbConnectionInstance client = mock(OvsdbConnectionInstance.class);
151         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "putConnectionInstance", ConnectionInfo.class,
152                 OvsdbConnectionInstance.class));
153         doNothing().when(client).createTransactInvokers();
154         PowerMockito.whenNew(OvsdbConnectionInstance.class).withArguments(any(ConnectionInfo.class),
155                 any(OvsdbClient.class), any(TransactionInvoker.class), any(InstanceIdentifier.class))
156                 .thenReturn(client);
157
158         assertEquals("Error, did not receive correct OvsdbConnectionInstance object", client,
159                 ovsdbConnManager.connectedButCallBacksNotRegistered(externalClient));
160     }
161
162     @Test
163     public void testDisconnected() throws Exception {
164         ConnectionInfo key = mock(ConnectionInfo.class);
165         PowerMockito.mockStatic(SouthboundMapper.class);
166         when(SouthboundMapper.createConnectionInfo(any(OvsdbClient.class))).thenReturn(key);
167
168         OvsdbConnectionInstance ovsdbConnectionInstance = mock(OvsdbConnectionInstance.class);
169         clients = new ConcurrentHashMap<>();
170         clients.put(key, ovsdbConnectionInstance);
171         MemberModifier.field(OvsdbConnectionManager.class, "clients").set(ovsdbConnManager, clients);
172
173         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getConnectionInstance", ConnectionInfo.class));
174         when(ovsdbConnManager.getConnectionInstance(any(ConnectionInfo.class))).thenReturn(ovsdbConnectionInstance);
175         doNothing().when(txInvoker).invoke(any(TransactionCommand.class));
176
177         when(SouthboundMapper.suppressLocalIpPort(any(ConnectionInfo.class))).thenReturn(key);
178
179         // TODO: Write unit tests for EntityOwnershipService
180         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "unregisterEntityForOwnership",
181                 OvsdbConnectionInstance.class));
182         instanceIdentifiers = new ConcurrentHashMap<>();
183         field(OvsdbConnectionManager.class, "instanceIdentifiers").set(ovsdbConnManager, instanceIdentifiers);
184         field(OvsdbConnectionManager.class, "nodeIdVsConnectionInstance").set(ovsdbConnManager, new HashMap<>());
185
186         MemberModifier.suppress(MemberMatcher.method(OvsdbConnectionManager.class, "reconcileConnection",
187                 InstanceIdentifier.class, OvsdbNodeAugmentation.class));
188         ReadTransaction tx = mock(ReadTransaction.class);
189         when(db.newReadOnlyTransaction()).thenReturn(tx);
190         when(tx.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class)))
191                 .thenReturn(mock(FluentFuture.class));
192         when(tx.exists(any(LogicalDatastoreType.class), any(InstanceIdentifier.class)))
193             .thenReturn(mock(FluentFuture.class));
194         when(ovsdbConnectionInstance.getInstanceIdentifier()).thenReturn(mock(InstanceIdentifier.class));
195         ovsdbConnManager.disconnected(externalClient);
196         Map<ConnectionInfo, OvsdbConnectionInstance> testClients = Whitebox.getInternalState(ovsdbConnManager,
197                 "clients");
198         assertEquals("Error, size of the hashmap is incorrect", 0, testClients.size());
199     }
200
201     @Test
202     public void testDisconnect() throws Exception {
203         OvsdbNodeAugmentation ovsdbNode = mock(OvsdbNodeAugmentation.class);
204         ConnectionInfo connectionInfo = mock(ConnectionInfo.class);
205         when(ovsdbNode.getConnectionInfo()).thenReturn(connectionInfo);
206         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getConnectionInstance", ConnectionInfo.class));
207         OvsdbConnectionInstance ovsdbConnectionInstance = mock(OvsdbConnectionInstance.class);
208         when(ovsdbConnManager.getConnectionInstance(any(ConnectionInfo.class))).thenReturn(ovsdbConnectionInstance);
209         when(ovsdbConnectionInstance.getInstanceIdentifier()).thenReturn(mock(InstanceIdentifier.class));
210
211         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "removeInstanceIdentifier", ConnectionInfo.class));
212
213         // TODO: Write unit tests for entity ownership service related code.
214         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "unregisterEntityForOwnership",
215                 OvsdbConnectionInstance.class));
216         ovsdbConnManager.disconnect(ovsdbNode);
217         verify(ovsdbConnectionInstance).disconnect();
218     }
219
220     @Test
221     @Ignore
222     public void testInit() {
223         mock(ConnectionInfo.class);
224         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getConnectionInstance", ConnectionInfo.class));
225         OvsdbConnectionInstance ovsdbConnectionInstance = mock(OvsdbConnectionInstance.class);
226         when(ovsdbConnManager.getConnectionInstance(any(ConnectionInfo.class))).thenReturn(ovsdbConnectionInstance);
227
228         // client not null
229         // ovsdbConnectionManager.init(key);
230         verify(ovsdbConnectionInstance).registerCallbacks(any());
231     }
232
233     @Test
234     public void testClose() throws Exception {
235         ConnectionInfo key1 = mock(ConnectionInfo.class);
236         ConnectionInfo key2 = mock(ConnectionInfo.class);
237         OvsdbConnectionInstance ovsdbConnectionInstance1 = mock(OvsdbConnectionInstance.class);
238         OvsdbConnectionInstance ovsdbConnectionInstance2 = mock(OvsdbConnectionInstance.class);
239         clients = new ConcurrentHashMap<>();
240         clients.put(key1, ovsdbConnectionInstance1);
241         clients.put(key2, ovsdbConnectionInstance2);
242         MemberModifier.field(OvsdbConnectionManager.class, "clients").set(ovsdbConnManager, clients);
243         ovsdbConnManager.close();
244         verify(ovsdbConnectionInstance1).disconnect();
245         verify(ovsdbConnectionInstance2).disconnect();
246     }
247
248     @Test
249     public void testPutAndGetConnectionInstance() throws Exception {
250         ConnectionInfo key = mock(ConnectionInfo.class);
251         ConnectionInfo connectionInfo = mock(ConnectionInfo.class);
252         PowerMockito.mockStatic(SouthboundMapper.class);
253         when(SouthboundMapper.suppressLocalIpPort(key)).thenReturn(connectionInfo);
254
255         clients = new ConcurrentHashMap<>();
256         MemberModifier.field(OvsdbConnectionManager.class, "clients").set(ovsdbConnManager, clients);
257
258         // Test putConnectionInstance()
259         OvsdbConnectionInstance instance = mock(OvsdbConnectionInstance.class);
260         Whitebox.invokeMethod(ovsdbConnManager, "putConnectionInstance", key, instance);
261         Map<ConnectionInfo, OvsdbConnectionInstance> testClients = Whitebox.getInternalState(ovsdbConnManager,
262                 "clients");
263         assertEquals("Error, size of the hashmap is incorrect", 1, testClients.size());
264
265         // Test getConnectionInstance(ConnectionInfo key)
266         assertEquals("Error, returned incorrect OvsdbConnectionInstance object", instance,
267                 ovsdbConnManager.getConnectionInstance(key));
268     }
269
270     @Test
271     public void testPutandGetInstanceIdentifier() throws Exception {
272         ConnectionInfo key = mock(ConnectionInfo.class);
273         ConnectionInfo connectionInfo = mock(ConnectionInfo.class);
274         PowerMockito.mockStatic(SouthboundMapper.class);
275         when(SouthboundMapper.suppressLocalIpPort(key)).thenReturn(connectionInfo);
276
277         instanceIdentifiers = new ConcurrentHashMap<>();
278         field(OvsdbConnectionManager.class, "instanceIdentifiers").set(ovsdbConnManager, instanceIdentifiers);
279
280         //Test putInstanceIdentifier()
281         Whitebox.invokeMethod(ovsdbConnManager, "putInstanceIdentifier", key, iid);
282         Map<ConnectionInfo, OvsdbConnectionInstance> testIids = Whitebox.getInternalState(ovsdbConnManager,
283                 "instanceIdentifiers");
284         assertEquals("Error, size of the hashmap is incorrect", 1, testIids.size());
285
286         //Test getInstanceIdentifier()
287         assertEquals("Error returning correct InstanceIdentifier object", iid,
288                 ovsdbConnManager.getInstanceIdentifier(key));
289
290         //Test removeInstanceIdentifier()
291         Whitebox.invokeMethod(ovsdbConnManager, "removeInstanceIdentifier", key);
292         Map<ConnectionInfo, OvsdbConnectionInstance> testRemoveIids = Whitebox.getInternalState(ovsdbConnManager,
293                 "instanceIdentifiers");
294         assertEquals("Error, size of the hashmap is incorrect", 0, testRemoveIids.size());
295     }
296
297     @Test
298     public void testGetClient() {
299         OvsdbConnectionInstance ovsdbClient = mock(OvsdbConnectionInstance.class);
300         OvsdbClient client = mock(OvsdbClient.class);
301         when(ovsdbClient.getOvsdbClient()).thenReturn(client);
302
303         //Test getClient(ConnectionInfo connectionInfo)
304         ConnectionInfo key = mock(ConnectionInfo.class);
305         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getConnectionInstance", ConnectionInfo.class));
306         when(ovsdbConnManager.getConnectionInstance(key)).thenReturn(ovsdbClient);
307         assertEquals("Error getting correct OvsdbClient object", ovsdbClient.getOvsdbClient(),
308                 ovsdbConnManager.getClient(key));
309
310         //Test getClient(OvsdbBridgeAttributes mn)
311         OvsdbBridgeAttributes mn = mock(OvsdbBridgeAttributes.class);
312         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getConnectionInstance",
313                 OvsdbBridgeAttributes.class));
314         when(ovsdbConnManager.getConnectionInstance(mn)).thenReturn(ovsdbClient);
315         assertEquals("Error getting correct OvsdbClient object", ovsdbClient.getOvsdbClient(),
316                 ovsdbConnManager.getClient(mn));
317
318         //Test getClient(Node node)
319         Node node = mock(Node.class);
320         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getConnectionInstance", Node.class));
321         when(ovsdbConnManager.getConnectionInstance(node)).thenReturn(ovsdbClient);
322         assertEquals("Error getting correct OvsdbClient object", ovsdbClient.getOvsdbClient(),
323                 ovsdbConnManager.getClient(node));
324     }
325
326     @SuppressWarnings("unchecked")
327     @Test
328     public void testConnect() throws Exception {
329         OvsdbNodeAugmentation ovsdbNode = mock(OvsdbNodeAugmentation.class);
330         ConnectionInfo connectionInfo = mock(ConnectionInfo.class);
331         when(ovsdbNode.getConnectionInfo()).thenReturn(connectionInfo);
332         IpAddress ipAddr = mock(IpAddress.class);
333         when(connectionInfo.getRemoteIp()).thenReturn(ipAddr);
334
335         PowerMockito.mockStatic(SouthboundMapper.class);
336         InetAddress ip = mock(InetAddress.class);
337         when(SouthboundMapper.createInetAddress(any(IpAddress.class))).thenReturn(ip);
338
339         PowerMockito.mockStatic(OvsdbConnectionService.class);
340 //        when(OvsdbConnectionService.getService()).thenReturn(ovsdbConnection);
341         PortNumber port = mock(PortNumber.class);
342         when(connectionInfo.getRemotePort()).thenReturn(port);
343         when(port.getValue()).thenReturn(Uint16.valueOf(8080));
344         OvsdbClient client = mock(OvsdbClient.class);
345         when(ovsdbConnection.connect(any(InetAddress.class), anyInt())).thenReturn(client);
346
347         //client not null case
348         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "putInstanceIdentifier", ConnectionInfo.class,
349                 InstanceIdentifier.class));
350         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "connectedButCallBacksNotRegistered",
351                 OvsdbClient.class));
352
353         doNothing().when(ovsdbConnManager).putInstanceIdentifier(any(ConnectionInfo.class),
354             any(InstanceIdentifier.class));
355
356         OvsdbConnectionInstance ovsdbConnectionInstance = mock(OvsdbConnectionInstance.class);
357         when(ovsdbConnManager.connectedButCallBacksNotRegistered(any(OvsdbClient.class)))
358                 .thenReturn(ovsdbConnectionInstance);
359
360         when(ovsdbConnectionInstance.getInstanceIdentifier()).thenReturn(mock(InstanceIdentifier.class));
361         field(OvsdbConnectionManager.class, "entityConnectionMap").set(ovsdbConnManager, entityConnectionMap);
362         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getEntityFromConnectionInstance",
363                 OvsdbConnectionInstance.class));
364         //TODO: Write unit tests for entity ownership service related code.
365         suppress(MemberMatcher.method(OvsdbConnectionManager.class, "registerEntityForOwnership",
366                 OvsdbConnectionInstance.class));
367         assertEquals("ERROR", client, ovsdbConnManager.connect(PowerMockito.mock(InstanceIdentifier.class), ovsdbNode));
368     }
369
370     @Test
371     public void testHandleOwnershipChanged() throws Exception {
372         Entity entity = new Entity("entityType", "entityName");
373         ConnectionInfo key = mock(ConnectionInfo.class);
374
375         OvsdbConnectionInstance ovsdbConnInstance = new OvsdbConnectionInstance(key, externalClient, txInvoker, iid);
376         entityConnectionMap.put(entity, ovsdbConnInstance);
377
378         field(OvsdbConnectionManager.class, "entityConnectionMap").set(ovsdbConnManager, entityConnectionMap);
379         doNothing().when(ovsdbConnManager).putConnectionInstance(any(ConnectionInfo.class),
380             any(OvsdbConnectionInstance.class));
381         EntityOwnershipChange ownershipChange = new EntityOwnershipChange(entity,
382                 EntityOwnershipChangeState.from(true, false, false));
383         Whitebox.invokeMethod(ovsdbConnManager, "handleOwnershipChanged", ownershipChange);
384         verify(ovsdbConnManager).putConnectionInstance(key, ovsdbConnInstance);
385     }
386 }