2 * Copyright (c) 2015 Inocybe 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.openstack.netvirt.impl;
11 import static org.junit.Assert.assertEquals;
12 import static org.mockito.Matchers.any;
13 import static org.mockito.Matchers.anyString;
14 import static org.mockito.Matchers.same;
15 import static org.mockito.Mockito.mock;
16 import static org.mockito.Mockito.when;
18 import java.lang.reflect.Field;
19 import java.util.ArrayList;
20 import java.util.HashSet;
21 import java.util.List;
24 import java.util.concurrent.ConcurrentMap;
26 import org.junit.Before;
27 import org.junit.Test;
28 import org.junit.runner.RunWith;
29 import org.mockito.InjectMocks;
30 import org.mockito.Mock;
31 import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
32 import org.opendaylight.neutron.spi.INeutronPortCRUD;
33 import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
34 import org.opendaylight.neutron.spi.NeutronFloatingIP;
35 import org.opendaylight.neutron.spi.NeutronNetwork;
36 import org.opendaylight.neutron.spi.NeutronPort;
37 import org.opendaylight.neutron.spi.NeutronRouter;
38 import org.opendaylight.neutron.spi.NeutronRouter_Interface;
39 import org.opendaylight.neutron.spi.NeutronSubnet;
40 import org.opendaylight.neutron.spi.Neutron_IPs;
41 import org.opendaylight.ovsdb.lib.notation.Column;
42 import org.opendaylight.ovsdb.lib.notation.Row;
43 import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
44 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
45 import org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService;
46 import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
47 import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
48 import org.opendaylight.ovsdb.plugin.api.OvsdbConnectionService;
49 import org.opendaylight.ovsdb.plugin.api.Status;
50 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
51 import org.opendaylight.ovsdb.utils.config.ConfigProperties;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
54 import org.powermock.api.mockito.PowerMockito;
55 import org.powermock.core.classloader.annotations.PrepareForTest;
56 import org.powermock.modules.junit4.PowerMockRunner;
59 * Unit test for {@link NeutronL3Adapter}
61 @PrepareForTest(ConfigProperties.class)
62 @RunWith(PowerMockRunner.class)
63 public class NeutronL3AdapterTest {
65 @InjectMocks NeutronL3Adapter neutronL3Adapter;
67 @Mock private ConfigurationService configurationService;
68 @Mock private TenantNetworkManager tenantNetworkManager;
69 @Mock private OvsdbConfigurationService ovsdbConfigurationService;
70 @Mock private OvsdbConnectionService connectionService;
71 @Mock private INeutronNetworkCRUD neutronNetworkCache;
72 @Mock private INeutronSubnetCRUD neutronSubnetCache;
73 @Mock private INeutronPortCRUD neutronPortCache;
74 @Mock NeutronPort neutronPort;
76 private Set<String> inboundIpRewriteCache;
77 private Set<String> outboundIpRewriteCache;
78 private Set<String> inboundIpRewriteExclusionCache;
79 private Set<String> outboundIpRewriteExclusionCache;
80 private Set<String> routerInterfacesCache;
81 private Set<String> staticArpEntryCache;
82 private Set<String> l3ForwardingCache;
83 private Set<String> defaultRouteCache;
84 private Map<String, String> networkIdToRouterMacCache;
85 private Map<String, NeutronRouter_Interface> subnetIdToRouterInterfaceCache;
87 private static final String HOST_ADDRESS = "127.0.0.1";
90 public void setUp() throws Exception{
91 PowerMockito.mockStatic(ConfigProperties.class);
92 PowerMockito.when(ConfigProperties.getProperty(neutronL3Adapter.getClass(), "ovsdb.l3.fwd.enabled")).thenReturn("yes");
94 neutronL3Adapter.init();
96 this.getNeutronL3AdapterFields();
100 private void getNeutronL3AdapterFields() throws Exception{
101 inboundIpRewriteCache = (Set<String>) getNeutronL3AdapterField("inboundIpRewriteCache");
102 outboundIpRewriteCache = (Set<String>) getNeutronL3AdapterField("outboundIpRewriteCache");
103 inboundIpRewriteExclusionCache = (Set<String>) getNeutronL3AdapterField("inboundIpRewriteExclusionCache");
104 outboundIpRewriteExclusionCache = (Set<String>) getNeutronL3AdapterField("outboundIpRewriteExclusionCache");
105 routerInterfacesCache = (Set<String>) getNeutronL3AdapterField("routerInterfacesCache");
106 staticArpEntryCache = (Set<String>) getNeutronL3AdapterField("staticArpEntryCache");
107 l3ForwardingCache = (Set<String>) getNeutronL3AdapterField("l3ForwardingCache");
108 defaultRouteCache = (Set<String>) getNeutronL3AdapterField("defaultRouteCache");
109 networkIdToRouterMacCache = (Map<String, String>) getNeutronL3AdapterField("networkIdToRouterMacCache");
110 subnetIdToRouterInterfaceCache = (Map<String, NeutronRouter_Interface>) getNeutronL3AdapterField("subnetIdToRouterInterfaceCache");
113 private Object getNeutronL3AdapterField(String fieldName) throws Exception {
114 Field fieldObject = NeutronL3Adapter.class.getDeclaredField(fieldName);
115 fieldObject.setAccessible(true);
116 return fieldObject.get(neutronL3Adapter);
119 private void setUpVar(){
120 Neutron_IPs neutronIP = mock(Neutron_IPs.class);
121 NeutronRouter neutronRouter = mock(NeutronRouter.class);
123 NeutronSubnet neutronSubnet = mock(NeutronSubnet.class);
124 NeutronNetwork neutronNetwork = mock(NeutronNetwork.class);
125 Node node = mock(Node.class);
126 NodeId nodeID = mock(NodeId.class);
127 Row row = mock(Row.class);
128 Bridge bridge = mock(Bridge.class);
129 Status status = mock(Status.class);
131 List<Neutron_IPs> list_neutronIP = new ArrayList<Neutron_IPs>();
132 list_neutronIP.add(neutronIP);
134 List<NeutronPort> list_neutronPort = new ArrayList<>();
135 list_neutronPort.add(neutronPort);
137 List<Node> list_nodes = new ArrayList<Node>();
138 list_nodes.add(node);
140 ConcurrentMap<String, Row> rowMap = mock(ConcurrentMap.class);
141 rowMap.put("key", row);
143 Column<GenericTableSchema, Set<String>> bridgeColumnIds = mock(Column.class);
144 Set<String> dpids = new HashSet();
147 when(neutronPort.getFixedIPs()).thenReturn(list_neutronIP);
148 when(neutronPort.getPortUUID()).thenReturn("portUUID");
149 when(neutronPort.getTenantID()).thenReturn("tenantID");
150 when(neutronPort.getNetworkUUID()).thenReturn("networkUUID");
151 when(neutronPort.getMacAddress()).thenReturn("macAddress1").thenReturn("macAddress2");
153 when(neutronIP.getSubnetUUID()).thenReturn("subnetUUID");
154 when(neutronIP.getIpAddress()).thenReturn(HOST_ADDRESS);
156 when(neutronPortCache.getAllPorts()).thenReturn(list_neutronPort);
157 when(neutronPortCache.getPort(anyString())).thenReturn(neutronPort);
159 when(neutronSubnetCache.getSubnet(anyString())).thenReturn(neutronSubnet);
161 when(neutronSubnet.getNetworkUUID()).thenReturn("networkUUID");
163 when(neutronNetworkCache.getNetwork(anyString())).thenReturn(neutronNetwork);
165 when(neutronNetwork.getRouterExternal()).thenReturn(false); // default true
166 when(neutronNetwork.getProviderSegmentationID()).thenReturn("providerSegmentationId1","providerSegmentationId2", "providerSegmentationId3");
167 when(neutronNetwork.getTenantID()).thenReturn("tenantId");
168 when(neutronNetwork.getNetworkUUID()).thenReturn("networkUUID");
170 when(neutronSubnet.getGatewayIP()).thenReturn("gatewayIp");
171 when(neutronSubnet.getCidr()).thenReturn(HOST_ADDRESS + "/32");
172 when(neutronSubnet.getSubnetUUID()).thenReturn("subnetUUID");
174 when(tenantNetworkManager.isTenantNetworkPresentInNode(any(Node.class), anyString())).thenReturn(false);
175 when(tenantNetworkManager.isTenantNetworkPresentInNode(any(Node.class), anyString())).thenReturn(true);
177 when(node.getId()).thenReturn(nodeID);
179 when(nodeID.getValue()).thenReturn("nodeId");
181 when(status.isSuccess()).thenReturn(true);
183 when(connectionService.getNodes()).thenReturn(list_nodes);
185 when(configurationService.getDefaultGatewayMacAddress(any(Node.class))).thenReturn("defaultGatewayMacAddress");
186 when(configurationService.getIntegrationBridgeName()).thenReturn("brName");
188 when(ovsdbConfigurationService.getRows(any(Node.class), anyString())).thenReturn(rowMap);
189 when(ovsdbConfigurationService.getTypedRow(any(Node.class), same(Bridge.class), any(Row.class))).thenReturn(bridge);
190 when(ovsdbConfigurationService.getRow(any(Node.class), anyString(), anyString())).thenReturn(row);
192 when(bridge.getName()).thenReturn("brName");
193 when(bridge.getDatapathIdColumn()).thenReturn(bridgeColumnIds);
195 when(bridgeColumnIds.getData()).thenReturn(dpids);
200 * Test method {@link NeutronL3Adapter#handleNeutronPortEvent(NeutronPort, Action)}
201 * Device owner = network:router_interface
204 public void testHandleNeutronPortEvent1() {
205 when(neutronPort.getDeviceOwner()).thenReturn("network:router_interface");
207 neutronL3Adapter.handleNeutronPortEvent(neutronPort, Action.ADD);
208 // Affected by the add
209 assertEquals("Error, did not return the correct networkIdToRouterMacCache size", 1, networkIdToRouterMacCache.size());
210 assertEquals("Error, did not return the correct subnetIdToRouterInterfaceCache size", 1, subnetIdToRouterInterfaceCache.size());
211 assertEquals("Error, did not return the correct routerInterfacesCache size", 2, routerInterfacesCache.size());
212 assertEquals("Error, did not return the correct staticArpEntryCache size", 2, staticArpEntryCache.size());
213 assertEquals("Error, did not return the correct inboundIpRewriteExclusionCache size", 1, inboundIpRewriteExclusionCache.size());
214 assertEquals("Error, did not return the correct outboundIpRewriteExclusionCache size", 1, outboundIpRewriteExclusionCache.size());
215 assertEquals("Error, did not return the correct l3ForwardingCache size", 1, l3ForwardingCache.size());
217 assertEquals("Error, did not return the correct inboundIpRewriteCache size", 0, inboundIpRewriteCache.size());
218 assertEquals("Error, did not return the correct outboundIpRewriteCache size", 0, outboundIpRewriteCache.size());
219 assertEquals("Error, did not return the correct defaultRouteCache size", 0, defaultRouteCache.size());
221 neutronL3Adapter.handleNeutronPortEvent(neutronPort, Action.DELETE);
222 // Affected by the delete
223 assertEquals("Error, did not return the correct networkIdToRouterMacCache size", 0, networkIdToRouterMacCache.size());
224 assertEquals("Error, did not return the correct subnetIdToRouterInterfaceCache size", 0, subnetIdToRouterInterfaceCache.size());
225 assertEquals("Error, did not return the correct staticArpEntryCache size", 1, staticArpEntryCache.size());
227 assertEquals("Error, did not return the correct routerInterfacesCache size", 2, routerInterfacesCache.size());
228 assertEquals("Error, did not return the correct inboundIpRewriteExclusionCache size", 1, inboundIpRewriteExclusionCache.size());
229 assertEquals("Error, did not return the correct outboundIpRewriteExclusionCache size", 1, outboundIpRewriteExclusionCache.size());
230 assertEquals("Error, did not return the correct l3ForwardingCache size", 1, l3ForwardingCache.size());
231 assertEquals("Error, did not return the correct inboundIpRewriteCache size", 0, inboundIpRewriteCache.size());
232 assertEquals("Error, did not return the correct outboundIpRewriteCache size", 0, outboundIpRewriteCache.size());
233 assertEquals("Error, did not return the correct defaultRouteCache size", 0, defaultRouteCache.size());
237 * Test method {@link NeutronL3Adapter#handleNeutronPortEvent(NeutronPort, Action)}
241 public void testHandleNeutronPortEvent2() {
242 when(neutronPort.getDeviceOwner()).thenReturn("");
244 // populate subnetIdToRouterInterfaceCache to pass the
245 // if (neutronRouterInterface != null)
246 NeutronRouter_Interface neutronRouterInterface = mock(NeutronRouter_Interface.class);
247 when(neutronRouterInterface.getPortUUID()).thenReturn("portUUID");
248 when(neutronRouterInterface.getSubnetUUID()).thenReturn("subnetUUID");
249 subnetIdToRouterInterfaceCache.put("subnetUUID", neutronRouterInterface);
251 /* device owner = "" */
252 neutronL3Adapter.handleNeutronPortEvent(neutronPort, Action.ADD);
253 // Affected by the add
254 assertEquals("Error, did not return the correct routerInterfacesCache size", 2, routerInterfacesCache.size());
255 assertEquals("Error, did not return the correct staticArpEntryCache size", 2, staticArpEntryCache.size());
256 assertEquals("Error, did not return the correct inboundIpRewriteExclusionCache size", 1, inboundIpRewriteExclusionCache.size());
257 assertEquals("Error, did not return the correct outboundIpRewriteExclusionCache size", 1, outboundIpRewriteExclusionCache.size());
258 assertEquals("Error, did not return the correct l3ForwardingCache size", 1, l3ForwardingCache.size());
259 assertEquals("Error, did not return the correct networkIdToRouterMacCache size", 1, networkIdToRouterMacCache.size());
261 assertEquals("Error, did not return the correct subnetIdToRouterInterfaceCache size", 1, subnetIdToRouterInterfaceCache.size());
263 assertEquals("Error, did not return the correct inboundIpRewriteCache size", 0, inboundIpRewriteCache.size());
264 assertEquals("Error, did not return the correct outboundIpRewriteCache size", 0, outboundIpRewriteCache.size());
265 assertEquals("Error, did not return the correct defaultRouteCache size", 0, defaultRouteCache.size());
267 neutronL3Adapter.handleNeutronPortEvent(neutronPort, Action.DELETE);
268 // Affected by the delete
269 assertEquals("Error, did not return the correct staticArpEntryCache size", 1, staticArpEntryCache.size());
270 assertEquals("Error, did not return the correct l3ForwardingCache size", 0, l3ForwardingCache.size());
272 assertEquals("Error, did not return the correct routerInterfacesCache size", 2, routerInterfacesCache.size());
273 assertEquals("Error, did not return the correct inboundIpRewriteExclusionCache size", 1, inboundIpRewriteExclusionCache.size());
274 assertEquals("Error, did not return the correct outboundIpRewriteExclusionCache size", 1, outboundIpRewriteExclusionCache.size());
275 assertEquals("Error, did not return the correct networkIdToRouterMacCache size", 1, networkIdToRouterMacCache.size());
276 assertEquals("Error, did not return the correct inboundIpRewriteCache size", 0, inboundIpRewriteCache.size());
277 assertEquals("Error, did not return the correct outboundIpRewriteCache size", 0, outboundIpRewriteCache.size());
278 assertEquals("Error, did not return the correct defaultRouteCache size", 0, defaultRouteCache.size());
280 assertEquals("Error, did not return the correct subnetIdToRouterInterfaceCache size", 1, subnetIdToRouterInterfaceCache.size());
284 * Test method {@link NeutronL3Adapter#handleNeutronFloatingIPEvent(NeutronFloatingIP, Action)}
287 public void testandleNeutronFloatingIPEvent() throws Exception{
288 NeutronFloatingIP neutronFloatingIP = mock(NeutronFloatingIP.class);
289 when(neutronFloatingIP.getFixedIPAddress()).thenReturn(HOST_ADDRESS);
290 when(neutronFloatingIP.getFloatingIPAddress()).thenReturn(HOST_ADDRESS);
291 when(neutronFloatingIP.getFloatingNetworkUUID()).thenReturn("floatingNetworkUUID");
293 networkIdToRouterMacCache.put("floatingNetworkUUID", "routerMacAddress");
295 neutronL3Adapter.handleNeutronFloatingIPEvent(neutronFloatingIP, Action.ADD);
297 assertEquals("Error, did not return the correct networkIdToRouterMacCache size", 1, networkIdToRouterMacCache.size());
298 // Affected by the add
299 assertEquals("Error, did not return the correct inboundIpRewriteCache size", 1, inboundIpRewriteCache.size());
300 assertEquals("Error, did not return the correct outboundIpRewriteCache size", 1, outboundIpRewriteCache.size());
301 assertEquals("Error, did not return the correct staticArpEntryCache size", 1, staticArpEntryCache.size());
303 assertEquals("Error, did not return the correct routerInterfacesCache size", 0, routerInterfacesCache.size());
304 assertEquals("Error, did not return the correct inboundIpRewriteExclusionCache size", 0, inboundIpRewriteExclusionCache.size());
305 assertEquals("Error, did not return the correct outboundIpRewriteExclusionCache size", 0, outboundIpRewriteExclusionCache.size());
306 assertEquals("Error, did not return the correct subnetIdToRouterInterfaceCache size", 0, subnetIdToRouterInterfaceCache.size());
307 assertEquals("Error, did not return the correct l3ForwardingCache size", 0, l3ForwardingCache.size());
308 assertEquals("Error, did not return the correct defaultRouteCache size", 0, defaultRouteCache.size());
310 neutronL3Adapter.handleNeutronFloatingIPEvent(neutronFloatingIP, Action.DELETE);
312 assertEquals("Error, did not return the correct networkIdToRouterMacCache size", 1, networkIdToRouterMacCache.size());
313 assertEquals("Error, did not return the correct inboundIpRewriteCache size", 1, inboundIpRewriteCache.size());
314 assertEquals("Error, did not return the correct outboundIpRewriteCache size", 1, outboundIpRewriteCache.size());
315 assertEquals("Error, did not return the correct staticArpEntryCache size", 1, staticArpEntryCache.size());
316 assertEquals("Error, did not return the correct routerInterfacesCache size", 0, routerInterfacesCache.size());
317 assertEquals("Error, did not return the correct inboundIpRewriteExclusionCache size", 0, inboundIpRewriteExclusionCache.size());
318 assertEquals("Error, did not return the correct outboundIpRewriteExclusionCache size", 0, outboundIpRewriteExclusionCache.size());
319 assertEquals("Error, did not return the correct subnetIdToRouterInterfaceCache size", 0, subnetIdToRouterInterfaceCache.size());
320 assertEquals("Error, did not return the correct l3ForwardingCache size", 0, l3ForwardingCache.size());
321 assertEquals("Error, did not return the correct defaultRouteCache size", 0, defaultRouteCache.size());