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