blob: 13385f4584b5c189db8158b12838f2c7a7050253 [file] [log] [blame]
TeruU8b2d1672014-04-25 17:02:56 -07001package net.onrc.onos.apps.proxyarp;
2
3import static org.junit.Assert.assertEquals;
4import static org.junit.Assert.assertTrue;
Yuta HIGUCHI238fa2a2014-05-01 09:56:46 -07005import static org.junit.Assert.fail;
TeruU8b2d1672014-04-25 17:02:56 -07006
7import java.net.InetAddress;
8import java.net.UnknownHostException;
9import java.nio.ByteBuffer;
10import java.util.ArrayList;
11import java.util.HashMap;
12import java.util.List;
13import java.util.Map;
14
TeruU8b2d1672014-04-25 17:02:56 -070015import net.floodlightcontroller.core.IFloodlightProviderService;
16import net.floodlightcontroller.core.module.FloodlightModuleContext;
17import net.floodlightcontroller.restserver.IRestApiService;
18import net.floodlightcontroller.util.MACAddress;
19import net.onrc.onos.api.packet.IPacketService;
Yuta HIGUCHI238fa2a2014-05-01 09:56:46 -070020import net.onrc.onos.apps.proxyarp.web.ArpWebRoutable;
TeruU8b2d1672014-04-25 17:02:56 -070021import net.onrc.onos.core.datagrid.IDatagridService;
22import net.onrc.onos.core.datagrid.IEventChannel;
23import net.onrc.onos.core.datagrid.IEventChannelListener;
24import net.onrc.onos.core.devicemanager.IOnosDeviceService;
25import net.onrc.onos.core.flowprogrammer.IFlowPusherService;
26import net.onrc.onos.core.main.config.IConfigInfoService;
27import net.onrc.onos.core.packet.ARP;
28import net.onrc.onos.core.packet.Ethernet;
29import net.onrc.onos.core.packet.IPv4;
30import net.onrc.onos.core.packetservice.SinglePacketOutNotification;
31import net.onrc.onos.core.topology.Device;
32import net.onrc.onos.core.topology.INetworkGraphService;
33import net.onrc.onos.core.topology.NetworkGraph;
34import net.onrc.onos.core.topology.Port;
35import net.onrc.onos.core.topology.Switch;
36
37import org.easymock.EasyMock;
38import org.junit.After;
39import org.junit.Before;
40import org.junit.Test;
41import org.junit.runner.RunWith;
42import org.powermock.api.easymock.PowerMock;
43import org.powermock.core.classloader.annotations.PrepareForTest;
44import org.powermock.modules.junit4.PowerMockRunner;
45
46@RunWith(PowerMockRunner.class)
47@PrepareForTest({ProxyArpManager.class, ArpCache.class})
48public class ProxyArpManagerTest {
49 String defaultStrAgingMsec = "60000";
50 String defaultStrCleanupMsec = "60000";
51
52 ProxyArpManager arpManager;
53 FloodlightModuleContext context;
54 IFloodlightProviderService floodligthProviderService;
55 IConfigInfoService configInfoService;
56 IRestApiService restApiService;
57 IDatagridService datagridService;
58 IFlowPusherService flowPusherService;
59 INetworkGraphService networkGraphService;
60 IOnosDeviceService onosDeviceService;
61 IPacketService packetService;
62 Map<String, String> config;
63
64 String srcStrMac, dstStrMac, cachedStrMac1, cachedStrMac2, srcStrIp, dstStrIp, cachedStrIp1, cachedStrIp2;
65 byte[] srcByteMac, dstByteMac;
66 MACAddress dstMac, srcMac, cachedMac1, cachedMac2;
67 InetAddress srcIp, dstIp, cachedIp1, cachedIp2;
68 Long sw1Dpid;
69 Short sw1Inport, sw1Outport;
70 Short vlanId;
71 ARP arpRequest, arpReply, rarpRequest;
72 Ethernet ethArpRequest, ethArpReply, ethRarpRequest, ethArpOtherOp;
73
74 NetworkGraph ng;
75 IEventChannel eg;
76 IEventChannelListener el;
77 Device dev1;
78 Port inPort1, outPort1;
79 Switch sw1;
80 ArpCache arpCache;
81 List<String> arpCacheComparisonList;
82
83 @Before
84 public void setUp() throws Exception {
85 makeTestedObject();
86 makeMock();
87 prepareExpectForInit();
88 prepareExpectForStartUp();
89 prepareExpectForGeneral();
90 }
91
92 private void makeTestedObject() {
93 //Made tested values
94 srcStrMac = "00:00:00:00:00:01";
95 dstStrMac = "00:00:00:00:00:02";
96 cachedStrMac1 = "00:00:00:00:00:03";
97 cachedStrMac2 = "00:00:00:00:00:04";
98 srcStrIp = "192.168.0.1";
99 dstStrIp = "192.168.0.2";
100 cachedStrIp1 = "192.168.0.3";
101 cachedStrIp2 = "192.168.0.4";
102 srcByteMac = Ethernet.toMACAddress(srcStrMac);
103 dstByteMac = Ethernet.toMACAddress(dstStrMac);
104 dstMac = new MACAddress(dstByteMac);
105 srcMac = new MACAddress(srcByteMac);
106 cachedMac1 = new MACAddress(Ethernet.toMACAddress(cachedStrMac1));
107 cachedMac2 = new MACAddress(Ethernet.toMACAddress(cachedStrMac2));
108 srcIp = null;
109 dstIp = null;
110 cachedIp1 = null;
111 cachedIp2 = null;
112 try {
113 srcIp = InetAddress.getByAddress(IPv4.toIPv4AddressBytes(srcStrIp));
114 dstIp = InetAddress.getByAddress(IPv4.toIPv4AddressBytes(dstStrIp));
115 cachedIp1 = InetAddress.getByAddress(IPv4.toIPv4AddressBytes(cachedStrIp1));
116 cachedIp2 = InetAddress.getByAddress(IPv4.toIPv4AddressBytes(cachedStrIp2));
117 } catch (UnknownHostException e) {
118 e.printStackTrace();
119 }
120 sw1Dpid = 1l;
121 sw1Inport = 1;
122 sw1Outport = 2;
123 vlanId = 1;
124
125 //Made tested packets
126 arpRequest = new ARP()
127 .setHardwareType(ARP.HW_TYPE_ETHERNET)
128 .setProtocolType(ARP.PROTO_TYPE_IP)
129 .setHardwareAddressLength((byte) 6)
130 .setProtocolAddressLength((byte) 4)
131 .setOpCode(ARP.OP_REQUEST)
132 .setSenderHardwareAddress(srcByteMac)
133 .setSenderProtocolAddress(srcIp.getAddress())
134 .setTargetProtocolAddress(dstIp.getAddress())
135 .setTargetHardwareAddress(dstByteMac);
136
137 ethArpRequest = (Ethernet) new Ethernet()
138 .setSourceMACAddress(srcStrMac)
139 .setDestinationMACAddress(dstStrMac)
140 .setEtherType(Ethernet.TYPE_ARP)
141 .setVlanID((short) 0)
142 .setPayload(arpRequest);
143
144 arpReply = new ARP()
145 .setHardwareType(ARP.HW_TYPE_ETHERNET)
146 .setProtocolType(ARP.PROTO_TYPE_IP)
147 .setHardwareAddressLength((byte) 6)
148 .setProtocolAddressLength((byte) 4)
149 .setOpCode(ARP.OP_RARP_REPLY)
150 .setSenderHardwareAddress(srcByteMac)
151 .setSenderProtocolAddress(srcIp.getAddress())
152 .setTargetProtocolAddress(dstIp.getAddress())
153 .setTargetHardwareAddress(dstByteMac);
154
155 ethArpReply = (Ethernet) new Ethernet()
156 .setSourceMACAddress(srcStrMac)
157 .setDestinationMACAddress(dstStrMac)
158 .setEtherType(Ethernet.TYPE_ARP)
159 .setVlanID((short) 0)
160 .setPayload(arpReply);
161
162 rarpRequest = new ARP()
163 .setHardwareType(ARP.HW_TYPE_ETHERNET)
164 .setProtocolType(ARP.PROTO_TYPE_IP)
165 .setHardwareAddressLength((byte) 6)
166 .setProtocolAddressLength((byte) 4)
167 .setOpCode(ARP.OP_RARP_REQUEST)
168 .setSenderHardwareAddress(srcByteMac)
169 .setSenderProtocolAddress(srcIp.getAddress())
170 .setTargetProtocolAddress(dstIp.getAddress())
171 .setTargetHardwareAddress(dstByteMac);
172
173 ethRarpRequest = (Ethernet) new Ethernet()
174 .setSourceMACAddress(srcStrMac)
175 .setDestinationMACAddress(dstStrMac)
176 .setEtherType(Ethernet.TYPE_RARP)
177 .setVlanID((short) 0)
178 .setPayload(rarpRequest);
179
180 ethArpOtherOp = (Ethernet) new Ethernet()
181 .setSourceMACAddress(srcStrMac)
182 .setDestinationMACAddress(dstStrMac)
183 .setEtherType(Ethernet.TYPE_ARP)
184 .setVlanID((short) 0)
185 .setPayload(rarpRequest);
186
187 //Made tested objects
188 arpCache = new ArpCache();
Yuta HIGUCHI238fa2a2014-05-01 09:56:46 -0700189 arpCache.setArpEntryTimeoutConfig(Long.parseLong(defaultStrCleanupMsec));
TeruU8b2d1672014-04-25 17:02:56 -0700190 arpCache.update(cachedIp1, cachedMac1);
Yuta HIGUCHI238fa2a2014-05-01 09:56:46 -0700191 arpCache.update(cachedIp2, cachedMac2);
192
193 arpCacheComparisonList = new ArrayList<String>();
TeruU8b2d1672014-04-25 17:02:56 -0700194 arpCacheComparisonList.add(cachedStrIp1
195 + " => "
196 + cachedStrMac1
197 + " : VALID");
TeruU8b2d1672014-04-25 17:02:56 -0700198 arpCacheComparisonList.add(cachedStrIp2
199 + " => "
200 + cachedStrMac2
201 + " : VALID");
202
203 arpManager = new ProxyArpManager();
204 config = new HashMap<String, String>();
205 }
206
207 private void makeMock() {
208 //Mock floodlight modules
209 context = EasyMock.createMock(FloodlightModuleContext.class);
210 floodligthProviderService = EasyMock.createMock(IFloodlightProviderService.class);
211 configInfoService = EasyMock.createMock(IConfigInfoService.class);
212 restApiService = EasyMock.createMock(IRestApiService.class);
213 datagridService = EasyMock.createMock(IDatagridService.class);
214 flowPusherService = EasyMock.createMock(IFlowPusherService.class);
215 networkGraphService = EasyMock.createMock(INetworkGraphService.class);
216 onosDeviceService = EasyMock.createMock(IOnosDeviceService.class);
217 packetService = EasyMock.createMock(IPacketService.class);
218 eg = EasyMock.createMock(IEventChannel.class);
219 el = EasyMock.createMock(IEventChannelListener.class);
220
221 //Mock NetworkGraph related data
222 ng = EasyMock.createMock(NetworkGraph.class);
223 dev1 = EasyMock.createMock(Device.class);
224 inPort1 = EasyMock.createMock(Port.class);
225 outPort1 = EasyMock.createMock(Port.class);
226 sw1 = EasyMock.createMock(Switch.class);
227 }
228
229 private void prepareExpectForGeneral() {
230 EasyMock.expect(inPort1.getNumber()).andReturn((long)sw1Inport).anyTimes();
231 EasyMock.expect(outPort1.getNumber()).andReturn((long)sw1Outport).anyTimes();
232 EasyMock.expect(outPort1.getOutgoingLink()).andReturn(null).anyTimes();
233 EasyMock.expect(outPort1.getIncomingLink()).andReturn(null).anyTimes();
234 EasyMock.expect(outPort1.getSwitch()).andReturn(sw1).anyTimes();
235 EasyMock.expect(sw1.getDpid()).andReturn(sw1Dpid).anyTimes();
236 }
237
238 private void prepareExpectForInit() {
239 EasyMock.expect(context.getServiceImpl(IFloodlightProviderService.class)).andReturn(floodligthProviderService);
240 EasyMock.expect(context.getServiceImpl(IConfigInfoService.class)).andReturn(configInfoService);
241 EasyMock.expect(context.getServiceImpl(IRestApiService.class)).andReturn(restApiService);
242 EasyMock.expect(context.getServiceImpl(IDatagridService.class)).andReturn(datagridService);
243 EasyMock.expect(context.getServiceImpl(IFlowPusherService.class)).andReturn(flowPusherService);
244 EasyMock.expect(context.getServiceImpl(INetworkGraphService.class)).andReturn(networkGraphService);
245 EasyMock.expect(context.getServiceImpl(IOnosDeviceService.class)).andReturn(onosDeviceService);
246 EasyMock.expect(context.getServiceImpl(IPacketService.class)).andReturn(packetService);
247 }
248
249 private void prepareExpectForStartUp() {
250 try {
251 PowerMock.expectNew(ArpCache.class).andReturn(arpCache);
252 } catch (Exception e) {
Yuta HIGUCHI238fa2a2014-05-01 09:56:46 -0700253 fail("Exception:" + e.getMessage());
TeruU8b2d1672014-04-25 17:02:56 -0700254 }
255 PowerMock.replayAll();
256 EasyMock.expect(configInfoService.getVlan()).andReturn(vlanId);
257 restApiService.addRestletRoutable(EasyMock.isA(ArpWebRoutable.class));
258 EasyMock.expectLastCall();
259 packetService.registerPacketListener(arpManager);
260 EasyMock.expectLastCall();
261 EasyMock.expect(networkGraphService.getNetworkGraph()).andReturn(ng);
262 EasyMock.expect(datagridService.addListener((String)EasyMock.anyObject(), EasyMock.isA(IEventChannelListener.class),
263 (Class)EasyMock.anyObject(), (Class)EasyMock.anyObject())).andReturn(eg).anyTimes();
264 List<ArpCacheNotification> list = new ArrayList<ArpCacheNotification>();
265 EasyMock.expect(eg.getAllEntries()).andReturn(list);
266 }
267
268 private void prepareExpectForLearnArp() {
269 eg.addEntry(EasyMock.eq(srcIp.toString()), EasyMock.isA(ArpCacheNotification.class));
270 EasyMock.expectLastCall();
271 }
272
273 @After
274 public void tearDown() throws Exception {
Yuta HIGUCHI238fa2a2014-05-01 09:56:46 -0700275 arpCache = null;
TeruU8b2d1672014-04-25 17:02:56 -0700276 }
277
278 @Test
279 public void testConfigTimeWithNoConfig() {
280 Map<String, String> config = new HashMap<String, String>();
281 EasyMock.expect(context.getConfigParams(arpManager)).andReturn(config);
282
283 EasyMock.replay(context, floodligthProviderService, configInfoService, restApiService, datagridService, flowPusherService,
284 networkGraphService, onosDeviceService, packetService, ng, eg, el, dev1, inPort1, sw1);
285 arpManager.init(context);
286 arpManager.startUp(context);
287 assertEquals(defaultStrAgingMsec, String.valueOf(arpManager.getArpEntryTimeout()));
288 assertEquals(defaultStrCleanupMsec, String.valueOf(arpManager.getArpCleaningTimerPeriod()));
289 }
290
291 @Test
292 public void testConfigTimeWithWrongParameter() {
293 Map<String, String> config = new HashMap<String, String>();
294 String strAgingMsec = "aaaaa";
295 String strCleanupMsec = "bbbbb";
296 config.put("agingmsec", strAgingMsec);
297 config.put("cleanupmsec", strCleanupMsec);
298 EasyMock.expect(context.getConfigParams(arpManager)).andReturn(config);
299
300 EasyMock.replay(context, floodligthProviderService, configInfoService, restApiService, datagridService, flowPusherService,
301 networkGraphService, onosDeviceService, packetService, ng, eg, el, dev1, inPort1, sw1);
302 arpManager.init(context);
303 arpManager.startUp(context);
304 assertEquals(defaultStrAgingMsec, String.valueOf(arpManager.getArpEntryTimeout()));
305 assertEquals(defaultStrCleanupMsec, String.valueOf(arpManager.getArpCleaningTimerPeriod()));
306 }
307
308 @Test
309 public void testConfigTime() {
310 String strAgingMsec = "10000";
311 String strCleanupMsec = "10000";
312 config.put("agingmsec", strAgingMsec);
313 config.put("cleanupmsec", strCleanupMsec);
314 EasyMock.expect(context.getConfigParams(arpManager)).andReturn(config);
315
316 EasyMock.replay(context, floodligthProviderService, configInfoService, restApiService, datagridService, flowPusherService,
317 networkGraphService, onosDeviceService, packetService, ng, eg, el, dev1, inPort1, sw1);
318 arpManager.init(context);
319 arpManager.startUp(context);
320 assertEquals(strAgingMsec, String.valueOf(arpManager.getArpEntryTimeout()));
321 assertEquals(strCleanupMsec, String.valueOf(arpManager.getArpCleaningTimerPeriod()));
322 }
323
324 @Test
325 public void testGetMacAddress() {
326 Map<String, String> config = new HashMap<String, String>();
327 EasyMock.expect(context.getConfigParams(arpManager)).andReturn(config);
328
329 EasyMock.replay(context, floodligthProviderService, configInfoService, restApiService, datagridService, flowPusherService,
330 networkGraphService, onosDeviceService, packetService, ng, eg, el, dev1, inPort1, sw1);
331 arpManager.init(context);
332 arpManager.startUp(context);
333 MACAddress mac = arpManager.getMacAddress(cachedIp1);
334 assertEquals(cachedMac1, mac);
335 }
336
337 @Test
338 public void testGetMappings() {
339 Map<String, String> config = new HashMap<String, String>();
340 EasyMock.expect(context.getConfigParams(arpManager)).andReturn(config);
341
342 EasyMock.replay(context, floodligthProviderService, configInfoService, restApiService, datagridService, flowPusherService,
343 networkGraphService, onosDeviceService, packetService, ng, eg, el, dev1, inPort1, sw1);
344 arpManager.init(context);
345 arpManager.startUp(context);
346 List<String> list = arpManager.getMappings();
347 for(String str : list) {
348 assertTrue(arpCacheComparisonList.contains(str));
349 }
350 }
351
352 @Test
353 public void testReceivePacketWithNoArpPacket() {
354 Map<String, String> config = new HashMap<String, String>();
355 EasyMock.expect(context.getConfigParams(arpManager)).andReturn(config);
356
357 EasyMock.replay(context, floodligthProviderService, configInfoService, restApiService, datagridService, flowPusherService,
358 networkGraphService, onosDeviceService, packetService, ng, eg, el, dev1, inPort1, sw1);
359 arpManager.init(context);
360 arpManager.startUp(context);
361 arpManager.receive(sw1, inPort1, ethRarpRequest);
362 }
363
364 @Test
365 public void testReceivePacketWithOtherOpCode() {
366 Map<String, String> config = new HashMap<String, String>();
367 EasyMock.expect(context.getConfigParams(arpManager)).andReturn(config);
368
369 prepareExpectForLearnArp();
370
371 EasyMock.replay(context, floodligthProviderService, configInfoService, restApiService, datagridService, flowPusherService,
372 networkGraphService, onosDeviceService, packetService, ng, eg, el, dev1, inPort1, sw1);
373 arpManager.init(context);
374 arpManager.startUp(context);
375 arpManager.receive(sw1, inPort1, ethArpOtherOp);
376 }
377
378 @Test
379 public void testClassifyPacketToSendArpReplyNotification() {
380 Map<String, String> config = new HashMap<String, String>();
381 EasyMock.expect(context.getConfigParams(arpManager)).andReturn(config);
382
383 prepareExpectForLearnArp();
384
385 ArpReplyNotification value =
386 new ArpReplyNotification(ByteBuffer.wrap(dstIp.getAddress()).getInt(), dstMac);
387 eg.addTransientEntry(srcMac.toLong(), value);
388 EasyMock.expectLastCall();
389 EasyMock.expect(context.getServiceImpl(IDatagridService.class)).andReturn(datagridService);
390
391 EasyMock.replay(context, floodligthProviderService, configInfoService, restApiService, datagridService, flowPusherService,
392 networkGraphService, onosDeviceService, packetService, ng, eg, el, dev1, inPort1, sw1);
393 arpManager.init(context);
394 arpManager.startUp(context);
395 arpManager.receive(sw1, inPort1, ethArpReply);
396 }
397
398 @Test
399 public void testClassifyPacketToHandleArpRequest() {
400 Map<String, String> config = new HashMap<String, String>();
401 EasyMock.expect(context.getConfigParams(arpManager)).andReturn(config);
402
403 prepareExpectForLearnArp();
404
405 EasyMock.expect(configInfoService.fromExternalNetwork(EasyMock.anyLong(), EasyMock.anyShort())).andReturn(true);
406 EasyMock.expect(configInfoService.isInterfaceAddress(dstIp)).andReturn(false);
407
408 EasyMock.replay(context, floodligthProviderService, configInfoService, restApiService, datagridService, flowPusherService,
409 networkGraphService, onosDeviceService, packetService, ng, eg, el, dev1, inPort1, sw1);
410 arpManager.init(context);
411 arpManager.startUp(context);
412 arpManager.receive(sw1, inPort1, ethArpRequest);
413 }
414
415 @Test
416 public void testClassifyPacketToHandleArpRequest2() {
417 List<Port> portList = new ArrayList<Port>();
418 portList.add(outPort1);
419
420 Map<String, String> config = new HashMap<String, String>();
421 EasyMock.expect(context.getConfigParams(arpManager)).andReturn(config);
422
423 prepareExpectForLearnArp();
424
425 EasyMock.expect(configInfoService.fromExternalNetwork(EasyMock.anyLong(), EasyMock.anyShort())).andReturn(false);
426 ng.acquireReadLock();
427 EasyMock.expectLastCall();
428 EasyMock.expect(ng.getDeviceByMac(dstMac)).andReturn(dev1);
429 ng.releaseReadLock();
430 EasyMock.expectLastCall();
431 EasyMock.expect(dev1.getAttachmentPoints()).andReturn(portList);
432 eg.addTransientEntry(EasyMock.anyLong(), (SinglePacketOutNotification)EasyMock.anyObject());
433 EasyMock.expectLastCall();
434
435 EasyMock.replay(context, configInfoService, restApiService, floodligthProviderService,
436 networkGraphService, datagridService, eg, ng, dev1, inPort1, outPort1, sw1);
437 arpManager.init(context);
438 arpManager.startUp(context);
439 arpManager.receive(sw1, inPort1, ethArpRequest);
440 }
441}