2 * Copyright (c) 2016 NEC Corporation 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.netvirt.openstack.netvirt.impl;
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertTrue;
13 import static org.mockito.Matchers.any;
14 import static org.mockito.Matchers.anyLong;
15 import static org.mockito.Matchers.anyString;
16 import static org.mockito.Matchers.eq;
17 import static org.mockito.Mockito.mock;
18 import static org.mockito.Mockito.times;
19 import static org.mockito.Mockito.when;
21 import java.lang.reflect.Field;
22 import java.net.InetAddress;
23 import java.util.ArrayList;
24 import java.util.List;
26 import org.junit.Before;
27 import org.junit.Ignore;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 import org.mockito.Mock;
31 import org.mockito.Mockito;
32 import org.opendaylight.netvirt.openstack.netvirt.api.Action;
33 import org.opendaylight.netvirt.openstack.netvirt.api.ArpProvider;
34 import org.opendaylight.netvirt.openstack.netvirt.api.ConfigurationService;
35 import org.opendaylight.netvirt.openstack.netvirt.api.NodeCacheManager;
36 import org.opendaylight.netvirt.openstack.netvirt.api.Status;
37 import org.opendaylight.netvirt.openstack.netvirt.api.StatusCode;
38 import org.opendaylight.netvirt.openstack.netvirt.api.TenantNetworkManager;
39 import org.opendaylight.netvirt.openstack.netvirt.translator.crud.INeutronNetworkCRUD;
40 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronNetwork;
41 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronPort;
42 import org.opendaylight.netvirt.openstack.netvirt.translator.Neutron_IPs;
43 import org.opendaylight.netvirt.openstack.netvirt.translator.crud.INeutronPortCRUD;
44 import org.opendaylight.netvirt.openstack.netvirt.api.Southbound;
45 import org.opendaylight.netvirt.utils.servicehelper.ServiceHelper;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
51 import org.osgi.framework.ServiceReference;
52 import org.powermock.api.mockito.PowerMockito;
53 import org.powermock.api.support.membermodification.MemberMatcher;
54 import org.powermock.api.support.membermodification.MemberModifier;
55 import org.powermock.core.classloader.annotations.PrepareForTest;
56 import org.powermock.modules.junit4.PowerMockRunner;
57 import org.powermock.reflect.Whitebox;
60 * Unit test for {@link DistributedArpService}
62 @PrepareForTest({ServiceHelper.class, InetAddress.class, DistributedArpService.class})
63 @RunWith(PowerMockRunner.class)
64 public class DistributedArpServiceTest {
66 @Mock private DistributedArpService distributedArpService;
68 * ID used for testing different scenarios.
70 private static final String ID = "45";
72 * IP used for testing different scenarios.
74 private static final String IP = "127.0.0.1";
76 * MALFORM_IP used for testing different scenarios.
78 private static final String MALFORM_IP = "127.0.0.1.5";
80 * INTF_NAME used for testing different scenarios.
82 private static final String INTF_NAME = "br-int";
84 * UUID used for testing different scenarios.
86 private static final String UUID = "7da709ff-397f-4778-a0e8-994811272fdb";
88 * FIXED_IP_ADDRESS used for testing different scenarios.
90 private static final String FIXED_IP_ADDRESS = "192.168.1.0";
92 * MAC_ADDRESS used for testing different scenarios.
94 private static final String MAC_ADDRESS = "00:00:5E:00:02:01";
96 * MAC_ADDRESS_2 used for testing different scenarios.
98 private static final String MAC_ADDRESS_2 = "00:00:5E:00:02:02";
100 * PORT_INT used for testing different scenarios.
102 private static final String PORT_INT = "port_int";
105 public void setUp() throws Exception{
106 distributedArpService = PowerMockito.spy(new DistributedArpService());
110 * Test that checks if @{DistributedArpService#handlePortEvent} is called
111 * and then checks that the port event process to write arp rules for neutron ports based on action.
114 public void testHandlePortEvent() throws Exception {
115 NeutronPort neutronPort = PowerMockito.mock(NeutronPort.class);
117 // Suppress the called to these functions.
118 MemberModifier.suppress(MemberMatcher.method(DistributedArpService.class, "handleNeutronPortForArp", NeutronPort.class, Action.class));
120 Whitebox.invokeMethod(distributedArpService, "handlePortEvent", neutronPort, Action.ADD);
121 PowerMockito.verifyPrivate(distributedArpService, times(1)).invoke("handleNeutronPortForArp", any(NeutronPort.class), eq(Action.ADD));
123 //Case 1: Delete Action.
124 Whitebox.invokeMethod(distributedArpService, "handlePortEvent", neutronPort, Action.DELETE);
125 PowerMockito.verifyPrivate(distributedArpService, times(1)).invoke("handleNeutronPortForArp", any(NeutronPort.class), eq(Action.DELETE));
129 * Test that checks if @{DistributedArpService#programStaticRuleStage1} is called
130 * and then checks that the arp rules are added/removed based on neutron port event.
133 public void testProgramStaticRuleStage1() throws Exception {
134 MemberModifier.suppress(MemberMatcher.method(DistributedArpService.class, "programStaticRuleStage2", Long.class, String.class, String.class, String.class, Action.class));
135 PowerMockito.when(distributedArpService, "programStaticRuleStage2", anyLong(), anyString(), anyString(), anyString(), any(Action.class)).thenReturn(new Status(StatusCode.SUCCESS));
137 //Case 1: Add Action.
138 Whitebox.invokeMethod(distributedArpService, "programStaticRuleStage1", 12L, PORT_INT, MAC_ADDRESS, IP, Action.ADD);
139 PowerMockito.verifyPrivate(distributedArpService, times(1)).invoke("programStaticRuleStage2", anyLong(), anyString(), anyString(), anyString(), eq(Action.ADD));
141 //Case 2: Delete Action.
142 Whitebox.invokeMethod(distributedArpService, "programStaticRuleStage1", 12L, PORT_INT, MAC_ADDRESS, IP, Action.DELETE);
143 PowerMockito.verifyPrivate(distributedArpService, times(1)).invoke("programStaticRuleStage2", anyLong(), anyString(), anyString(), anyString(), eq(Action.DELETE));
147 * Test that checks if @{DistributedArpService#programStaticRuleStage2} is called
148 * and then checks that the arp rules are programmed by invoke arpProvider.
151 public void testProgramStaticRuleStage2() throws Exception {
152 //Case 1: StatusCode BADREQUEST.
153 assertEquals("Error, this not return the correct status code", new Status(StatusCode.BADREQUEST), Whitebox.invokeMethod(distributedArpService, "programStaticRuleStage2",
154 45L, PORT_INT, MAC_ADDRESS, MALFORM_IP, Action.ADD));
155 PowerMockito.mockStatic(InetAddress.class);
156 InetAddress inetAddress = mock(InetAddress.class);
157 PowerMockito.when(InetAddress.getByName(anyString())).thenReturn(inetAddress);
159 //Case 2: StatusCode SUCCESS.
160 assertEquals("Error, this not return the correct status code", new Status(StatusCode.SUCCESS), Whitebox.invokeMethod(distributedArpService, "programStaticRuleStage2",
161 45L, PORT_INT, MAC_ADDRESS, IP, Action.DELETE));
165 * Test that checks if @{DistributedArpService#handleNeutornPortForArp} is called
166 * and then checks that the arp rules are written based on event for neutron port.
170 public void testHandleNeutornPortForArp() throws Exception {
171 Southbound southbound = mock(Southbound.class);
172 Neutron_IPs neutronIp = mock(Neutron_IPs.class);
173 when(neutronIp.getIpAddress()).thenReturn(FIXED_IP_ADDRESS);
174 List<Neutron_IPs> neutronIps = new ArrayList<>();
175 neutronIps.add(neutronIp);
176 NeutronPort neutronPort = mock(NeutronPort.class);
177 when(neutronPort.getNetworkUUID()).thenReturn(UUID);
178 when(neutronPort.getMacAddress()).thenReturn(MAC_ADDRESS_2);
179 when(neutronPort.getFixedIPs()).thenReturn(neutronIps);
180 NeutronNetwork neutronNetwork = mock(NeutronNetwork.class);
181 when(neutronNetwork.getProviderSegmentationID()).thenReturn(ID);
182 List<Node> nodes = new ArrayList<>();
183 nodes.add(mock(Node.class));
184 TenantNetworkManager tenantNetworkManager = mock(TenantNetworkManager.class);
185 MemberModifier.field(DistributedArpService.class, "tenantNetworkManager").set(distributedArpService, tenantNetworkManager);
186 when(tenantNetworkManager.isTenantNetworkPresentInNode(any(Node.class), eq(ID))).thenReturn(true);
187 PowerMockito.doReturn(15L).when(distributedArpService, "getDatapathIdIntegrationBridge", any(Node.class));
188 INeutronNetworkCRUD neutronNetworkCache = mock(INeutronNetworkCRUD.class);
189 when(neutronNetworkCache.getNetwork(anyString())).thenReturn(neutronNetwork);
190 MemberModifier.field(DistributedArpService.class, "neutronNetworkCache").set(distributedArpService, neutronNetworkCache);
191 NodeCacheManager nodeCacheManager = mock(NodeCacheManager.class);
192 when(nodeCacheManager.getBridgeNodes()).thenReturn(nodes);
193 MemberModifier.field(DistributedArpService.class, "nodeCacheManager").set(distributedArpService, nodeCacheManager);
194 MemberModifier.field(DistributedArpService.class, "flgDistributedARPEnabled").set(distributedArpService, true);
196 // Suppress the called to these functions.
197 MemberModifier.suppress(MemberMatcher.method(DistributedArpService.class, "programStaticRuleStage1", Long.class, String.class, String.class, String.class, Action.class));
199 List<OvsdbTerminationPointAugmentation> ports = new ArrayList<>();
200 ports.add(mock(OvsdbTerminationPointAugmentation.class));
201 PowerMockito.when(southbound.readTerminationPointAugmentations(any(Node.class))).thenReturn(ports);
203 PowerMockito.doReturn(true).when(distributedArpService, "getNeutronPortsForNode", any(Node.class), any(List.class), anyString());
204 Whitebox.invokeMethod(distributedArpService, "handleNeutronPortForArp", neutronPort, Action.ADD);
205 PowerMockito.verifyPrivate(distributedArpService, times(1)).invoke("getDatapathIdIntegrationBridge", any(Node.class));
207 // Case 2: Delete Action.
208 Whitebox.invokeMethod(distributedArpService, "handleNeutronPortForArp", neutronPort, Action.DELETE);
209 PowerMockito.verifyPrivate(distributedArpService, times(2)).invoke("getDatapathIdIntegrationBridge", any(Node.class));
213 * Test that checks if @{DistributedArpService#getDatapathIdIntegrationBridge} is called
214 * and then checks the node integration bridge, then return its datapathID.
217 public void testGetDatapathIdIntegrationBridge() throws Exception {
218 Southbound southbound = mock(Southbound.class);
219 ConfigurationService configurationService = mock(ConfigurationService.class);
221 MemberModifier.field(DistributedArpService.class, "southbound").set(distributedArpService, southbound);
222 MemberModifier.field(DistributedArpService.class, "configurationService").set(distributedArpService, configurationService);
224 PowerMockito.when(southbound.getBridge(any(Node.class), anyString())).thenReturn(mock(OvsdbBridgeAugmentation.class));
225 PowerMockito.when(configurationService.getIntegrationBridgeName()).thenReturn("");
226 PowerMockito.when(southbound.getDataPathId(any(Node.class))).thenReturn(45L);
228 //Assert check for correct Dp Id.
229 assertEquals("Error, did not return the correct Dpid", 45, (long)Whitebox.invokeMethod(distributedArpService, "getDatapathIdIntegrationBridge", mock(Node.class)));
233 * Test that checks if @{DistributedArpService#processInterfaceEvent} is called
234 * and then checks that the event is processing.
237 public void testProcessInterfaceEvent() throws Exception {
238 NeutronPort neutronPort = mock(NeutronPort.class);
239 NeutronNetwork neutronNetwork = mock(NeutronNetwork.class);
240 PowerMockito.doNothing().when(distributedArpService).handlePortEvent(any(NeutronPort.class), any(Action.class));
241 // init instance variables.
242 TenantNetworkManager tenantNetworkManager = mock(TenantNetworkManager.class);
243 MemberModifier.field(DistributedArpService.class, "tenantNetworkManager").set(distributedArpService , tenantNetworkManager);
246 NodeId nodeId = mock(NodeId.class);
247 when(nodeId.getValue()).thenReturn(ID);
248 Node node = mock(Node.class);
249 when(node.getNodeId()).thenReturn(nodeId);
251 OvsdbTerminationPointAugmentation intf = mock(OvsdbTerminationPointAugmentation.class);
252 when(intf.getName()).thenReturn(INTF_NAME);
254 when(tenantNetworkManager.getTenantPort(intf)).thenReturn(neutronPort);
256 //Case 1: Add Action.
257 distributedArpService.processInterfaceEvent(node, intf, neutronNetwork, Action.ADD);
258 Mockito.verify(distributedArpService, times(1)).handlePortEvent(neutronPort, Action.ADD);
260 //Case 2: Delete Action.
261 distributedArpService.processInterfaceEvent(node, intf, neutronNetwork, Action.DELETE);
262 Mockito.verify(distributedArpService, times(1)).handlePortEvent(neutronPort, Action.DELETE);
266 * Test that checks if @{DistributedArpService#setDependencies} is called
267 * and then checks the object instances.
270 public void testSetDependencies() throws Exception {
271 TenantNetworkManager tenantNetworkManager = mock(TenantNetworkManager.class);
272 ConfigurationService configurationService = mock(ConfigurationService.class);
273 ArpProvider arpProvider = mock(ArpProvider.class);
274 NodeCacheManager nodeCacheManager = mock(NodeCacheManager.class);
275 Southbound southbound = mock(Southbound.class);
277 ServiceHelper.overrideGlobalInstance(TenantNetworkManager.class, tenantNetworkManager);
278 ServiceHelper.overrideGlobalInstance(ConfigurationService.class, configurationService);
279 ServiceHelper.overrideGlobalInstance(ArpProvider.class, arpProvider);
280 ServiceHelper.overrideGlobalInstance(NodeCacheManager.class, nodeCacheManager);
281 ServiceHelper.overrideGlobalInstance(Southbound.class, southbound);
283 distributedArpService.setDependencies(mock(ServiceReference.class));
285 assertEquals("Error, did not return the correct object", getField("tenantNetworkManager"), tenantNetworkManager);
286 assertEquals("Error, did not return the correct object", getField("configurationService"), configurationService);
287 assertEquals("Error, did not return the correct object", getField("arpProvider"), arpProvider);
288 assertEquals("Error, did not return the correct object", getField("nodeCacheManager"), nodeCacheManager);
289 assertEquals("Error, did not return the correct object", getField("southbound"), southbound);
293 * Test that checks if @{DistributedArpService#setDependencies} is called
294 * and then checks the object instances.
297 public void testSetDependenciesObject() throws Exception{
298 INeutronNetworkCRUD iNeutronNetworkCRUD = mock(INeutronNetworkCRUD.class);
299 distributedArpService.setDependencies(iNeutronNetworkCRUD);
300 assertEquals("Error, did not return the correct object", getField("neutronNetworkCache"), iNeutronNetworkCRUD);
302 INeutronPortCRUD iNeutronPortCRUD = mock(INeutronPortCRUD.class);
303 distributedArpService.setDependencies(iNeutronPortCRUD);
304 assertEquals("Error, did not return the correct object", getField("neutronPortCache"), iNeutronPortCRUD);
306 ArpProvider arpProvider = mock(ArpProvider.class);
307 distributedArpService.setDependencies(arpProvider);
308 assertEquals("Error, did not return the correct object", getField("arpProvider"), arpProvider);
312 private Object getField(String fieldName) throws Exception {
313 Field field = DistributedArpService.class.getDeclaredField(fieldName);
314 field.setAccessible(true);
315 return field.get(distributedArpService);