2 * Copyright (c) 2015 Inocybe Technologies and others. All rights reserved.
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
9 package org.opendaylight.ovsdb.southbound;
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;
22 import com.google.common.base.Optional;
23 import com.google.common.util.concurrent.CheckedFuture;
24 import java.net.InetAddress;
25 import java.util.Arrays;
26 import java.util.List;
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.clustering.Entity;
39 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
40 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
41 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
42 import org.opendaylight.ovsdb.lib.OvsdbClient;
43 import org.opendaylight.ovsdb.lib.OvsdbConnection;
44 import org.opendaylight.ovsdb.lib.impl.OvsdbConnectionService;
45 import org.opendaylight.ovsdb.southbound.reconciliation.ReconciliationManager;
46 import org.opendaylight.ovsdb.southbound.transactions.md.TransactionCommand;
47 import org.opendaylight.ovsdb.southbound.transactions.md.TransactionInvoker;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAttributes;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
53 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
54 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
55 import org.powermock.api.mockito.PowerMockito;
56 import org.powermock.api.support.membermodification.MemberMatcher;
57 import org.powermock.api.support.membermodification.MemberModifier;
58 import org.powermock.core.classloader.annotations.PrepareForTest;
59 import org.powermock.modules.junit4.PowerMockRunner;
60 import org.powermock.reflect.Whitebox;
62 @RunWith(PowerMockRunner.class)
63 @PrepareForTest({ SouthboundMapper.class, OvsdbConnectionManager.class, OvsdbConnectionService.class,
64 InstanceIdentifier.class, SouthboundUtil.class, Optional.class })
65 public class OvsdbConnectionManagerTest {
67 @Mock private OvsdbConnectionManager ovsdbConnManager;
68 @Mock private DataBroker db;
69 @Mock private TransactionInvoker txInvoker;
70 @Mock private EntityOwnershipService entityOwnershipService;
71 @Mock private OvsdbConnection ovsdbConnection;
72 @Mock private OvsdbClient externalClient;
73 @Mock private ReconciliationManager reconciliationManager;
74 private Map<ConnectionInfo,OvsdbConnectionInstance> clients;
75 private Map<ConnectionInfo,InstanceIdentifier<Node>> instanceIdentifiers;
76 private Map<Entity, OvsdbConnectionInstance> entityConnectionMap;
78 @Mock private InstanceIdentifier<Node> iid;
81 public void setUp() throws Exception {
82 ovsdbConnManager = PowerMockito.mock(OvsdbConnectionManager.class, Mockito.CALLS_REAL_METHODS);
83 field(OvsdbConnectionManager.class, "db").set(ovsdbConnManager, db);
84 field(OvsdbConnectionManager.class, "txInvoker").set(ovsdbConnManager, txInvoker);
85 field(OvsdbConnectionManager.class, "entityOwnershipService").set(ovsdbConnManager, entityOwnershipService);
86 field(OvsdbConnectionManager.class, "reconciliationManager").set(ovsdbConnManager, reconciliationManager);
87 field(OvsdbConnectionManager.class, "ovsdbConnection").set(ovsdbConnManager, ovsdbConnection);
88 entityConnectionMap = new ConcurrentHashMap<>();
90 externalClient = mock(OvsdbClient.class, Mockito.RETURNS_DEEP_STUBS);
91 when(externalClient.getConnectionInfo().getRemoteAddress()).thenReturn(mock(InetAddress.class));
92 when(externalClient.getConnectionInfo().getRemotePort()).thenReturn(8080);
93 when(externalClient.getConnectionInfo().getLocalAddress()).thenReturn(mock(InetAddress.class));
94 when(externalClient.getConnectionInfo().getLocalPort()).thenReturn(8080);
95 List<String> databases = Arrays.asList("Open_vSwitch");
96 when(externalClient.getDatabases().get(1000, TimeUnit.MILLISECONDS)).thenReturn(databases);
98 PowerMockito.mockStatic(SouthboundUtil.class);
99 when(SouthboundUtil.connectionInfoToString(any(ConnectionInfo.class))).thenReturn("192.18.120.31:8080");
103 public void testConnected() throws Exception {
104 OvsdbConnectionInstance client = mock(OvsdbConnectionInstance.class);
105 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "connectedButCallBacksNotRegistered",
107 when(ovsdbConnManager.connectedButCallBacksNotRegistered(any(OvsdbClient.class))).thenReturn(client);
108 doNothing().when(client).registerCallbacks(any());
110 //TODO: Write unit tests for EntityOwnershipService
111 InstanceIdentifier<Node> iid = mock(InstanceIdentifier.class);
112 when(client.getInstanceIdentifier()).thenReturn(iid);
113 field(OvsdbConnectionManager.class, "entityConnectionMap").set(ovsdbConnManager, entityConnectionMap);
114 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getEntityFromConnectionInstance",
115 OvsdbConnectionInstance.class));
117 //TODO: Write unit tests for entity ownership service related code.
118 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "registerEntityForOwnership",
119 OvsdbConnectionInstance.class));
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));
127 ovsdbConnManager.connected(externalClient);
130 @SuppressWarnings("unchecked")
132 public void testConnectedButCallBacksNotRegistered() throws Exception {
133 ConnectionInfo key = mock(ConnectionInfo.class);
135 PowerMockito.mockStatic(SouthboundMapper.class);
136 when(SouthboundMapper.createConnectionInfo(any(OvsdbClient.class))).thenReturn(key);
138 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getInstanceIdentifier", ConnectionInfo.class));
139 InstanceIdentifier<Node> iid = mock(InstanceIdentifier.class);
140 when(ovsdbConnManager.getInstanceIdentifier(key)).thenReturn(iid);
142 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getConnectionInstance", ConnectionInfo.class));
143 when(ovsdbConnManager.getConnectionInstance(key)).thenReturn(null);
145 OvsdbConnectionInstance client = mock(OvsdbConnectionInstance.class);
146 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "putConnectionInstance", ConnectionInfo.class,
147 OvsdbConnectionInstance.class));
148 doNothing().when(client).createTransactInvokers();
149 PowerMockito.whenNew(OvsdbConnectionInstance.class).withArguments(any(ConnectionInfo.class),
150 any(OvsdbClient.class), any(TransactionInvoker.class), any(InstanceIdentifier.class))
153 assertEquals("Error, did not receive correct OvsdbConnectionInstance object", client,
154 ovsdbConnManager.connectedButCallBacksNotRegistered(externalClient));
158 public void testDisconnected() throws Exception {
159 ConnectionInfo key = mock(ConnectionInfo.class);
160 PowerMockito.mockStatic(SouthboundMapper.class);
161 when(SouthboundMapper.createConnectionInfo(any(OvsdbClient.class))).thenReturn(key);
163 OvsdbConnectionInstance ovsdbConnectionInstance = mock(OvsdbConnectionInstance.class);
164 clients = new ConcurrentHashMap<>();
165 clients.put(key, ovsdbConnectionInstance);
166 MemberModifier.field(OvsdbConnectionManager.class, "clients").set(ovsdbConnManager, clients);
168 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getConnectionInstance", ConnectionInfo.class));
169 when(ovsdbConnManager.getConnectionInstance(any(ConnectionInfo.class))).thenReturn(ovsdbConnectionInstance);
170 doNothing().when(txInvoker).invoke(any(TransactionCommand.class));
172 when(SouthboundMapper.suppressLocalIpPort(any(ConnectionInfo.class))).thenReturn(key);
174 // TODO: Write unit tests for EntityOwnershipService
175 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "unregisterEntityForOwnership",
176 OvsdbConnectionInstance.class));
177 instanceIdentifiers = new ConcurrentHashMap<>();
178 field(OvsdbConnectionManager.class, "instanceIdentifiers").set(ovsdbConnManager, instanceIdentifiers);
180 MemberModifier.suppress(MemberMatcher.method(OvsdbConnectionManager.class, "reconcileConnection",
181 InstanceIdentifier.class, OvsdbNodeAugmentation.class));
182 ReadOnlyTransaction tx = mock(ReadOnlyTransaction.class);
183 when(db.newReadOnlyTransaction()).thenReturn(tx);
184 when(tx.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class)))
185 .thenReturn(mock(CheckedFuture.class));
186 when(ovsdbConnectionInstance.getInstanceIdentifier()).thenReturn(mock(InstanceIdentifier.class));
187 ovsdbConnManager.disconnected(externalClient);
188 Map<ConnectionInfo, OvsdbConnectionInstance> testClients = Whitebox.getInternalState(ovsdbConnManager,
190 assertEquals("Error, size of the hashmap is incorrect", 0, testClients.size());
194 public void testDisconnect() throws Exception {
195 OvsdbNodeAugmentation ovsdbNode = mock(OvsdbNodeAugmentation.class);
196 ConnectionInfo connectionInfo = mock(ConnectionInfo.class);
197 when(ovsdbNode.getConnectionInfo()).thenReturn(connectionInfo);
198 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getConnectionInstance", ConnectionInfo.class));
199 OvsdbConnectionInstance ovsdbConnectionInstance = mock(OvsdbConnectionInstance.class);
200 when(ovsdbConnManager.getConnectionInstance(any(ConnectionInfo.class))).thenReturn(ovsdbConnectionInstance);
201 when(ovsdbConnectionInstance.getInstanceIdentifier()).thenReturn(mock(InstanceIdentifier.class));
203 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "removeInstanceIdentifier", ConnectionInfo.class));
205 // TODO: Write unit tests for entity ownership service related code.
206 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "unregisterEntityForOwnership",
207 OvsdbConnectionInstance.class));
208 ovsdbConnManager.disconnect(ovsdbNode);
209 verify(ovsdbConnectionInstance).disconnect();
214 public void testInit() {
215 mock(ConnectionInfo.class);
216 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getConnectionInstance", ConnectionInfo.class));
217 OvsdbConnectionInstance ovsdbConnectionInstance = mock(OvsdbConnectionInstance.class);
218 when(ovsdbConnManager.getConnectionInstance(any(ConnectionInfo.class))).thenReturn(ovsdbConnectionInstance);
221 // ovsdbConnectionManager.init(key);
222 verify(ovsdbConnectionInstance).registerCallbacks(any());
226 public void testClose() throws Exception {
227 ConnectionInfo key1 = mock(ConnectionInfo.class);
228 ConnectionInfo key2 = mock(ConnectionInfo.class);
229 OvsdbConnectionInstance ovsdbConnectionInstance1 = mock(OvsdbConnectionInstance.class);
230 OvsdbConnectionInstance ovsdbConnectionInstance2 = mock(OvsdbConnectionInstance.class);
231 clients = new ConcurrentHashMap<>();
232 clients.put(key1, ovsdbConnectionInstance1);
233 clients.put(key2, ovsdbConnectionInstance2);
234 MemberModifier.field(OvsdbConnectionManager.class, "clients").set(ovsdbConnManager, clients);
235 ovsdbConnManager.close();
236 verify(ovsdbConnectionInstance1).disconnect();
237 verify(ovsdbConnectionInstance2).disconnect();
241 public void testPutAndGetConnectionInstance() throws Exception {
242 ConnectionInfo key = mock(ConnectionInfo.class);
243 ConnectionInfo connectionInfo = mock(ConnectionInfo.class);
244 PowerMockito.mockStatic(SouthboundMapper.class);
245 when(SouthboundMapper.suppressLocalIpPort(key)).thenReturn(connectionInfo);
247 clients = new ConcurrentHashMap<>();
248 MemberModifier.field(OvsdbConnectionManager.class, "clients").set(ovsdbConnManager, clients);
250 // Test putConnectionInstance()
251 OvsdbConnectionInstance instance = mock(OvsdbConnectionInstance.class);
252 Whitebox.invokeMethod(ovsdbConnManager, "putConnectionInstance", key, instance);
253 Map<ConnectionInfo, OvsdbConnectionInstance> testClients = Whitebox.getInternalState(ovsdbConnManager,
255 assertEquals("Error, size of the hashmap is incorrect", 1, testClients.size());
257 // Test getConnectionInstance(ConnectionInfo key)
258 assertEquals("Error, returned incorrect OvsdbConnectionInstance object", instance,
259 ovsdbConnManager.getConnectionInstance(key));
263 @SuppressWarnings("unchecked")
264 public void testPutandGetInstanceIdentifier() throws Exception {
265 ConnectionInfo key = mock(ConnectionInfo.class);
266 ConnectionInfo connectionInfo = mock(ConnectionInfo.class);
267 PowerMockito.mockStatic(SouthboundMapper.class);
268 when(SouthboundMapper.suppressLocalIpPort(key)).thenReturn(connectionInfo);
270 instanceIdentifiers = new ConcurrentHashMap<>();
271 field(OvsdbConnectionManager.class, "instanceIdentifiers").set(ovsdbConnManager, instanceIdentifiers);
273 //Test putInstanceIdentifier()
274 Whitebox.invokeMethod(ovsdbConnManager, "putInstanceIdentifier", key, iid);
275 Map<ConnectionInfo, OvsdbConnectionInstance> testIids = Whitebox.getInternalState(ovsdbConnManager,
276 "instanceIdentifiers");
277 assertEquals("Error, size of the hashmap is incorrect", 1, testIids.size());
279 //Test getInstanceIdentifier()
280 assertEquals("Error returning correct InstanceIdentifier object", iid,
281 ovsdbConnManager.getInstanceIdentifier(key));
283 //Test removeInstanceIdentifier()
284 Whitebox.invokeMethod(ovsdbConnManager, "removeInstanceIdentifier", key);
285 Map<ConnectionInfo, OvsdbConnectionInstance> testRemoveIids = Whitebox.getInternalState(ovsdbConnManager,
286 "instanceIdentifiers");
287 assertEquals("Error, size of the hashmap is incorrect", 0, testRemoveIids.size());
291 public void testGetClient() {
292 OvsdbConnectionInstance ovsdbClient = mock(OvsdbConnectionInstance.class);
293 OvsdbClient client = mock(OvsdbClient.class);
294 when(ovsdbClient.getOvsdbClient()).thenReturn(client);
296 //Test getClient(ConnectionInfo connectionInfo)
297 ConnectionInfo key = mock(ConnectionInfo.class);
298 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getConnectionInstance", ConnectionInfo.class));
299 when(ovsdbConnManager.getConnectionInstance(key)).thenReturn((OvsdbConnectionInstance)ovsdbClient);
300 assertEquals("Error getting correct OvsdbClient object", ovsdbClient.getOvsdbClient(),
301 ovsdbConnManager.getClient(key));
303 //Test getClient(OvsdbBridgeAttributes mn)
304 OvsdbBridgeAttributes mn = mock(OvsdbBridgeAttributes.class);
305 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getConnectionInstance",
306 OvsdbBridgeAttributes.class));
307 when(ovsdbConnManager.getConnectionInstance(mn)).thenReturn((OvsdbConnectionInstance)ovsdbClient);
308 assertEquals("Error getting correct OvsdbClient object", ovsdbClient.getOvsdbClient(),
309 ovsdbConnManager.getClient(mn));
311 //Test getClient(Node node)
312 Node node = mock(Node.class);
313 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getConnectionInstance", Node.class));
314 when(ovsdbConnManager.getConnectionInstance(node)).thenReturn((OvsdbConnectionInstance)ovsdbClient);
315 assertEquals("Error getting correct OvsdbClient object", ovsdbClient.getOvsdbClient(),
316 ovsdbConnManager.getClient(node));
319 @SuppressWarnings("unchecked")
321 public void testConnect() throws Exception {
322 OvsdbNodeAugmentation ovsdbNode = mock(OvsdbNodeAugmentation.class);
323 ConnectionInfo connectionInfo = mock(ConnectionInfo.class);
324 when(ovsdbNode.getConnectionInfo()).thenReturn(connectionInfo);
325 IpAddress ipAddr = mock(IpAddress.class);
326 when(connectionInfo.getRemoteIp()).thenReturn(ipAddr);
328 PowerMockito.mockStatic(SouthboundMapper.class);
329 InetAddress ip = mock(InetAddress.class);
330 when(SouthboundMapper.createInetAddress(any(IpAddress.class))).thenReturn(ip);
332 PowerMockito.mockStatic(OvsdbConnectionService.class);
333 when(OvsdbConnectionService.getService()).thenReturn(ovsdbConnection);
334 PortNumber port = mock(PortNumber.class);
335 when(connectionInfo.getRemotePort()).thenReturn(port);
336 when(port.getValue()).thenReturn(8080);
337 OvsdbClient client = mock(OvsdbClient.class);
338 when(ovsdbConnection.connect(any(InetAddress.class), anyInt())).thenReturn(client);
340 //client not null case
341 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "putInstanceIdentifier", ConnectionInfo.class,
342 InstanceIdentifier.class));
343 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "connectedButCallBacksNotRegistered",
346 PowerMockito.doNothing().when(ovsdbConnManager, "putInstanceIdentifier", any(ConnectionInfo.class),
347 any(InstanceIdentifier.class));
349 OvsdbConnectionInstance ovsdbConnectionInstance = mock(OvsdbConnectionInstance.class);
350 when(ovsdbConnManager.connectedButCallBacksNotRegistered(any(OvsdbClient.class)))
351 .thenReturn(ovsdbConnectionInstance);
353 InstanceIdentifier<Node> iid = mock(InstanceIdentifier.class);
354 when(ovsdbConnectionInstance.getInstanceIdentifier()).thenReturn(iid);
355 field(OvsdbConnectionManager.class, "entityConnectionMap").set(ovsdbConnManager, entityConnectionMap);
356 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "getEntityFromConnectionInstance",
357 OvsdbConnectionInstance.class));
358 //TODO: Write unit tests for entity ownership service related code.
359 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "registerEntityForOwnership",
360 OvsdbConnectionInstance.class));
361 assertEquals("ERROR", client, ovsdbConnManager.connect(PowerMockito.mock(InstanceIdentifier.class), ovsdbNode));
365 public void testHandleOwnershipChanged() throws Exception {
366 Entity entity = new Entity("entityType", "entityName");
367 ConnectionInfo key = mock(ConnectionInfo.class);
369 OvsdbConnectionInstance ovsdbConnInstance = new OvsdbConnectionInstance(key, externalClient, txInvoker, iid);
370 entityConnectionMap.put(entity, ovsdbConnInstance);
372 field(OvsdbConnectionManager.class, "entityConnectionMap").set(ovsdbConnManager, entityConnectionMap);
373 suppress(MemberMatcher.method(OvsdbConnectionManager.class, "putConnectionInstance", ConnectionInfo.class,
374 OvsdbConnectionInstance.class));
375 EntityOwnershipChange ownershipChange = new EntityOwnershipChange(entity, true, false, false);
376 Whitebox.invokeMethod(ovsdbConnManager, "handleOwnershipChanged", ownershipChange);
377 PowerMockito.verifyPrivate(ovsdbConnManager, times(1)).invoke("putConnectionInstance", key, ovsdbConnInstance);