a9b3b55c003029bab82504a9c01e3804b7654211
[netvirt.git] /
1 /*
2  * Copyright (c) 2016 NEC Corporation 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.netvirt.openstack.netvirt.impl;
10
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;
20
21 import java.lang.reflect.Field;
22 import java.net.InetAddress;
23 import java.util.ArrayList;
24 import java.util.List;
25
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;
50
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;
58
59 /**
60  * Unit test for {@link DistributedArpService}
61  */
62 @PrepareForTest({ServiceHelper.class, InetAddress.class, DistributedArpService.class})
63 @RunWith(PowerMockRunner.class)
64 public class DistributedArpServiceTest {
65
66     @Mock private DistributedArpService distributedArpService;
67     /**
68      * ID used for testing different scenarios.
69      */
70     private static final String ID = "45";
71     /**
72      * IP used for testing different scenarios.
73      */
74     private static final String IP = "127.0.0.1";
75     /**
76      * MALFORM_IP used for testing different scenarios.
77      */
78     private static final String MALFORM_IP = "127.0.0.1.5";
79     /**
80      * INTF_NAME used for testing different scenarios.
81      */
82     private static final String INTF_NAME = "br-int";
83     /**
84      * UUID used for testing different scenarios.
85      */
86     private static final String UUID = "7da709ff-397f-4778-a0e8-994811272fdb";
87     /**
88      * FIXED_IP_ADDRESS used for testing different scenarios.
89      */
90     private static final String FIXED_IP_ADDRESS = "192.168.1.0";
91     /**
92      * MAC_ADDRESS used for testing different scenarios.
93      */
94     private static final String MAC_ADDRESS = "00:00:5E:00:02:01";
95     /**
96      * MAC_ADDRESS_2 used for testing different scenarios.
97      */
98     private static final String MAC_ADDRESS_2 = "00:00:5E:00:02:02";
99     /**
100      * PORT_INT used for testing different scenarios.
101      */
102     private static final String PORT_INT = "port_int";
103
104     @Before
105     public void setUp() throws Exception{
106         distributedArpService = PowerMockito.spy(new DistributedArpService());
107     }
108
109     /**
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.
112      */
113     @Test
114     public void testHandlePortEvent() throws Exception {
115         NeutronPort neutronPort = PowerMockito.mock(NeutronPort.class);
116
117         // Suppress the called to these functions.
118         MemberModifier.suppress(MemberMatcher.method(DistributedArpService.class, "handleNeutronPortForArp", NeutronPort.class, Action.class));
119
120         Whitebox.invokeMethod(distributedArpService, "handlePortEvent", neutronPort, Action.ADD);
121         PowerMockito.verifyPrivate(distributedArpService, times(1)).invoke("handleNeutronPortForArp", any(NeutronPort.class), eq(Action.ADD));
122         
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));
126     }
127
128     /**
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.
131      */
132     @Test
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));
136
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));
140
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));
144     }
145
146     /**
147      * Test that checks if @{DistributedArpService#programStaticRuleStage2} is called
148      * and then checks that the arp rules are programmed by invoke arpProvider.
149      */
150     @Test
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);
158
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));
162     }
163
164     /**
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.
167      */
168     @Ignore
169     @Test
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);
195
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));
198
199         List<OvsdbTerminationPointAugmentation> ports = new ArrayList<>();
200         ports.add(mock(OvsdbTerminationPointAugmentation.class));
201         PowerMockito.when(southbound.readTerminationPointAugmentations(any(Node.class))).thenReturn(ports);
202
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));
206
207         // Case 2: Delete Action.
208         Whitebox.invokeMethod(distributedArpService, "handleNeutronPortForArp", neutronPort, Action.DELETE);
209         PowerMockito.verifyPrivate(distributedArpService, times(2)).invoke("getDatapathIdIntegrationBridge", any(Node.class));
210     }
211
212     /**
213      * Test that checks if @{DistributedArpService#getDatapathIdIntegrationBridge} is called
214      * and then checks the node integration bridge, then return its datapathID.
215      */
216     @Test
217     public void testGetDatapathIdIntegrationBridge() throws Exception {
218         Southbound southbound = mock(Southbound.class);
219         ConfigurationService configurationService = mock(ConfigurationService.class);
220
221         MemberModifier.field(DistributedArpService.class, "southbound").set(distributedArpService, southbound);
222         MemberModifier.field(DistributedArpService.class, "configurationService").set(distributedArpService, configurationService);
223
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);
227
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)));
230     }
231
232     /**
233      * Test that checks if @{DistributedArpService#processInterfaceEvent} is called
234      * and then checks that the event is processing.
235      */
236     @Test
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);
244
245         // Mock variables
246         NodeId nodeId = mock(NodeId.class);
247         when(nodeId.getValue()).thenReturn(ID);
248         Node node = mock(Node.class);
249         when(node.getNodeId()).thenReturn(nodeId);
250
251         OvsdbTerminationPointAugmentation intf = mock(OvsdbTerminationPointAugmentation.class);
252         when(intf.getName()).thenReturn(INTF_NAME);
253
254         when(tenantNetworkManager.getTenantPort(intf)).thenReturn(neutronPort);
255
256         //Case 1: Add Action.
257         distributedArpService.processInterfaceEvent(node, intf, neutronNetwork, Action.ADD);
258         Mockito.verify(distributedArpService, times(1)).handlePortEvent(neutronPort, Action.ADD);
259
260         //Case 2: Delete Action.
261         distributedArpService.processInterfaceEvent(node, intf, neutronNetwork, Action.DELETE);
262         Mockito.verify(distributedArpService, times(1)).handlePortEvent(neutronPort, Action.DELETE);
263     }
264
265     /**
266      * Test that checks if @{DistributedArpService#setDependencies} is called
267      * and then checks the object instances.
268      */
269     @Test
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);
276
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);
282
283         distributedArpService.setDependencies(mock(ServiceReference.class));
284
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);
290     }
291
292     /**
293      * Test that checks if @{DistributedArpService#setDependencies} is called
294      * and then checks the object instances.
295      */
296     @Test
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);
301
302         INeutronPortCRUD iNeutronPortCRUD = mock(INeutronPortCRUD.class);
303         distributedArpService.setDependencies(iNeutronPortCRUD);
304         assertEquals("Error, did not return the correct object", getField("neutronPortCache"), iNeutronPortCRUD);
305
306         ArpProvider arpProvider = mock(ArpProvider.class);
307         distributedArpService.setDependencies(arpProvider);
308         assertEquals("Error, did not return the correct object", getField("arpProvider"), arpProvider);
309     }
310
311
312     private Object getField(String fieldName) throws Exception {
313         Field field = DistributedArpService.class.getDeclaredField(fieldName);
314         field.setAccessible(true);
315         return field.get(distributedArpService);
316     }
317
318 }