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.ovsdb.openstack.netvirt.impl;
11 import static org.junit.Assert.assertEquals;
12 import static org.mockito.Matchers.any;
13 import static org.mockito.Matchers.anyLong;
14 import static org.mockito.Matchers.anyString;
15 import static org.mockito.Matchers.eq;
16 import static org.mockito.Mockito.mock;
17 import static org.mockito.Mockito.times;
18 import static org.mockito.Mockito.when;
20 import java.lang.reflect.Field;
21 import java.net.InetAddress;
22 import java.util.ArrayList;
23 import java.util.List;
25 import org.junit.Before;
26 import org.junit.Test;
27 import org.junit.runner.RunWith;
28 import org.mockito.Mock;
29 import org.mockito.Mockito;
30 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
31 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
32 import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
33 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronNetworkCRUD;
34 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
35 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
36 import org.opendaylight.ovsdb.openstack.netvirt.api.ArpProvider;
37 import org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService;
38 import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
39 import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
40 import org.opendaylight.ovsdb.openstack.netvirt.api.Status;
41 import org.opendaylight.ovsdb.openstack.netvirt.api.StatusCode;
42 import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
43 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
49 import org.osgi.framework.ServiceReference;
50 import org.powermock.api.mockito.PowerMockito;
51 import org.powermock.api.support.membermodification.MemberMatcher;
52 import org.powermock.api.support.membermodification.MemberModifier;
53 import org.powermock.core.classloader.annotations.PrepareForTest;
54 import org.powermock.modules.junit4.PowerMockRunner;
55 import org.powermock.reflect.Whitebox;
58 * Unit test for {@link DistributedArpService}
60 @PrepareForTest({ServiceHelper.class, InetAddress.class, DistributedArpService.class})
61 @RunWith(PowerMockRunner.class)
62 public class DistributedArpServiceTest {
64 @Mock private DistributedArpService distributedArpService;
66 * ID used for testing different scenarios.
68 private static final String ID = "45";
70 * IP used for testing different scenarios.
72 private static final String IP = "127.0.0.1";
74 * MALFORM_IP used for testing different scenarios.
76 private static final String MALFORM_IP = "127.0.0.1.5";
78 * INTF_NAME used for testing different scenarios.
80 private static final String INTF_NAME = "br-int";
82 * UUID used for testing different scenarios.
84 private static final String UUID = "7da709ff-397f-4778-a0e8-994811272fdb";
86 * FIXED_IP_ADDRESS used for testing different scenarios.
88 private static final String FIXED_IP_ADDRESS = "192.168.1.0";
90 * MAC_ADDRESS used for testing different scenarios.
92 private static final String MAC_ADDRESS = "00:00:5E:00:02:01";
94 * MAC_ADDRESS_2 used for testing different scenarios.
96 private static final String MAC_ADDRESS_2 = "00:00:5E:00:02:02";
98 * PORT_INT used for testing different scenarios.
100 private static final String PORT_INT = "port_int";
103 public void setUp() throws Exception{
104 distributedArpService = PowerMockito.spy(new DistributedArpService());
108 * Test that checks if @{DistributedArpService#handlePortEvent} is called
109 * and then checks that the port event process to write arp rules for neutron ports based on action.
112 public void testHandlePortEvent() throws Exception {
113 NeutronPort neutronPortOne = PowerMockito.mock(NeutronPort.class);
114 NeutronPort neutronPortTwo = PowerMockito.mock(NeutronPort.class);
115 List<NeutronPort> list_neutronPort = new ArrayList<>();
116 list_neutronPort.add(neutronPortOne);
117 list_neutronPort.add(neutronPortTwo);
118 INeutronPortCRUD neutronPortCache = PowerMockito.mock(INeutronPortCRUD.class);
119 MemberModifier.field(DistributedArpService.class, "neutronPortCache").set(distributedArpService, neutronPortCache);
120 PowerMockito.when(neutronPortCache, "getAllPorts").thenReturn(list_neutronPort);
122 // Suppress the called to these functions.
123 MemberModifier.suppress(MemberMatcher.method(DistributedArpService.class, "handleNeutronPortForArp", NeutronPort.class, Action.class));
125 //Case 1: Delete Action.
126 Whitebox.invokeMethod(distributedArpService, "handlePortEvent", neutronPortOne, Action.DELETE);
127 PowerMockito.verifyPrivate(distributedArpService, times(1)).invoke("handleNeutronPortForArp", any(NeutronPort.class), eq(Action.DELETE));
129 //Case 2: Add Action.
130 Whitebox.invokeMethod(distributedArpService, "handlePortEvent", neutronPortOne, Action.ADD);
131 PowerMockito.verifyPrivate(distributedArpService, times(2)).invoke("handleNeutronPortForArp", any(NeutronPort.class), eq(Action.ADD));
135 * Test that checks if @{DistributedArpService#programStaticRuleStage1} is called
136 * and then checks that the arp rules are added/removed based on neutron port event.
139 public void testProgramStaticRuleStage1() throws Exception {
140 MemberModifier.suppress(MemberMatcher.method(DistributedArpService.class, "programStaticRuleStage2", Long.class, String.class, String.class, String.class, Action.class));
141 PowerMockito.when(distributedArpService, "programStaticRuleStage2", anyLong(), anyString(), anyString(), anyString(), any(Action.class)).thenReturn(new Status(StatusCode.SUCCESS));
143 //Case 1: Add Action.
144 Whitebox.invokeMethod(distributedArpService, "programStaticRuleStage1", Long.valueOf(12), PORT_INT, MAC_ADDRESS, IP, Action.ADD);
145 PowerMockito.verifyPrivate(distributedArpService, times(1)).invoke("programStaticRuleStage2", anyLong(), anyString(), anyString(), anyString(), eq(Action.ADD));
147 //Case 2: Delete Action.
148 Whitebox.invokeMethod(distributedArpService, "programStaticRuleStage1", Long.valueOf(12), PORT_INT, MAC_ADDRESS, IP, Action.DELETE);
149 PowerMockito.verifyPrivate(distributedArpService, times(1)).invoke("programStaticRuleStage2", anyLong(), anyString(), anyString(), anyString(), eq(Action.DELETE));
153 * Test that checks if @{DistributedArpService#programStaticRuleStage2} is called
154 * and then checks that the arp rules are programmed by invoke arpProvider.
157 public void testProgramStaticRuleStage2() throws Exception {
158 //Case 1: StatusCode BADREQUEST.
159 assertEquals("Error, this not return the correct status code", new Status(StatusCode.BADREQUEST), Whitebox.invokeMethod(distributedArpService, "programStaticRuleStage2", Long.valueOf(45), PORT_INT, MAC_ADDRESS, MALFORM_IP, Action.ADD));
160 PowerMockito.mockStatic(InetAddress.class);
161 InetAddress inetAddress = mock(InetAddress.class);
162 PowerMockito.when(InetAddress.getByName(anyString())).thenReturn(inetAddress);
164 //Case 2: StatusCode SUCCESS.
165 assertEquals("Error, this not return the correct status code", new Status(StatusCode.SUCCESS), Whitebox.invokeMethod(distributedArpService, "programStaticRuleStage2", Long.valueOf(45), PORT_INT, MAC_ADDRESS, IP, Action.DELETE));
169 * Test that checks if @{DistributedArpService#handleNeutornPortForArp} is called
170 * and then checks that the arp rules are written based on event for neutron port.
173 public void testHandleNeutornPortForArp() throws Exception {
174 Neutron_IPs neutronIp = mock(Neutron_IPs.class);
175 when(neutronIp.getIpAddress()).thenReturn(FIXED_IP_ADDRESS);
176 List<Neutron_IPs> neutronIps = new ArrayList<>();
177 neutronIps.add(neutronIp);
178 NeutronPort neutronPort = mock(NeutronPort.class);
179 when(neutronPort.getNetworkUUID()).thenReturn(UUID);
180 when(neutronPort.getMacAddress()).thenReturn(MAC_ADDRESS_2);
181 when(neutronPort.getFixedIPs()).thenReturn(neutronIps);
182 NeutronNetwork neutronNetwork = mock(NeutronNetwork.class);
183 when(neutronNetwork.getProviderSegmentationID()).thenReturn(ID);
184 List<Node> nodes = new ArrayList<>();
185 nodes.add(mock(Node.class));
186 TenantNetworkManager tenantNetworkManager = mock(TenantNetworkManager.class);
187 MemberModifier.field(DistributedArpService.class, "tenantNetworkManager").set(distributedArpService, tenantNetworkManager);
188 when(tenantNetworkManager.isTenantNetworkPresentInNode(any(Node.class), eq(ID))).thenReturn(true);
189 PowerMockito.doReturn(15L).when(distributedArpService, "getDatapathIdIntegrationBridge", any(Node.class));
190 INeutronNetworkCRUD neutronNetworkCache = mock(INeutronNetworkCRUD.class);
191 when(neutronNetworkCache.getNetwork(anyString())).thenReturn(neutronNetwork);
192 MemberModifier.field(DistributedArpService.class, "neutronNetworkCache").set(distributedArpService, neutronNetworkCache);
193 NodeCacheManager nodeCacheManager = mock(NodeCacheManager.class);
194 when(nodeCacheManager.getBridgeNodes()).thenReturn(nodes);
195 MemberModifier.field(DistributedArpService.class, "nodeCacheManager").set(distributedArpService, nodeCacheManager);
196 MemberModifier.field(DistributedArpService.class, "flgDistributedARPEnabled").set(distributedArpService, true);
198 // Suppress the called to these functions.
199 MemberModifier.suppress(MemberMatcher.method(DistributedArpService.class, "programStaticRuleStage1", Long.class, String.class, String.class, String.class, Action.class));
201 //Case 1: Add Action.
202 Whitebox.invokeMethod(distributedArpService, "handleNeutronPortForArp", neutronPort, Action.ADD);
203 PowerMockito.verifyPrivate(distributedArpService, times(1)).invoke("getDatapathIdIntegrationBridge", any(Node.class));
204 Mockito.verify(distributedArpService, times(1)).programStaticRuleStage1(anyLong(), anyString(), anyString(), anyString(), eq(Action.ADD));
206 //Case 2: Delete Action.
207 Whitebox.invokeMethod(distributedArpService, "handleNeutronPortForArp", neutronPort, Action.DELETE);
208 PowerMockito.verifyPrivate(distributedArpService, times(2)).invoke("getDatapathIdIntegrationBridge", any(Node.class));
209 Mockito.verify(distributedArpService, times(1)).programStaticRuleStage1(anyLong(), anyString(), anyString(), anyString(), eq(Action.DELETE));
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);
311 private Object getField(String fieldName) throws Exception {
312 Field field = DistributedArpService.class.getDeclaredField(fieldName);
313 field.setAccessible(true);
314 return field.get(distributedArpService);