blob: dd104e284ad676e186c74184ffe5ed375a8c80ef [file] [log] [blame]
Patrick Liuab1e6062014-05-05 11:12:13 -07001package net.onrc.onos.core.devicemanager;
2
3import static org.easymock.EasyMock.anyObject;
4import static org.easymock.EasyMock.createMock;
5import static org.easymock.EasyMock.createNiceMock;
6import static org.easymock.EasyMock.eq;
7import static org.easymock.EasyMock.expect;
8import static org.easymock.EasyMock.expectLastCall;
9import static org.easymock.EasyMock.replay;
10import static org.easymock.EasyMock.verify;
11
12import java.util.Date;
13
14import net.floodlightcontroller.core.IFloodlightProviderService;
15import net.floodlightcontroller.core.IListener.Command;
16import net.floodlightcontroller.core.IOFSwitch;
17import net.floodlightcontroller.core.IUpdate;
18import net.floodlightcontroller.core.module.FloodlightModuleContext;
19import net.floodlightcontroller.test.FloodlightTestCase;
20import net.floodlightcontroller.util.MACAddress;
21import 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.intent.MockTopology;
25import net.onrc.onos.core.packet.ARP;
26import net.onrc.onos.core.packet.DHCP;
27import net.onrc.onos.core.packet.Data;
28import net.onrc.onos.core.packet.Ethernet;
29import net.onrc.onos.core.packet.IPacket;
30import net.onrc.onos.core.packet.IPv4;
31import net.onrc.onos.core.packet.UDP;
32import net.onrc.onos.core.registry.IControllerRegistryService;
33import net.onrc.onos.core.topology.ITopologyListener;
34import net.onrc.onos.core.topology.ITopologyService;
35
36import org.easymock.EasyMock;
37import org.junit.After;
38import org.junit.Before;
39import org.junit.Test;
40import org.openflow.protocol.OFPacketIn;
41import org.openflow.protocol.OFType;
42
43/**
44 * @author patrick.liu@huawei.com
45 * <p/>
46 * Unit tests for the Device Manager module (OnosDeviceManger).
47 * These test cases check the result of add/delete device and
48 * verify the result of processPacketIn through inject faked packets
49 * floodLightProvider, datagridService, networkGraphService,
50 * controllerRegistryService, eventChannel are mocked out.
51 */
52public class OnosDeviceManagerTest extends FloodlightTestCase {
53 private IPacket pkt0, pkt1, pkt2, pkt3, pkt4;
54 private IOFSwitch sw1;
55 private long sw1Dpid;
56 private short sw1DevPort;
57 private OnosDeviceManager odm;
58 private OFPacketIn pktIn;
59 private FloodlightModuleContext modContext;
60 private ITopologyService networkGraphService;
61 private IEventChannel<Long, OnosDevice> eventChannel;
62 private IFloodlightProviderService floodLightProvider;
63 private Date lastSeenTimestamp;
64
65 @Override
66 @Before
67 public void setUp() throws Exception {
68 super.setUp();
69 MockTopology topology = new MockTopology();
70 IDatagridService datagridService;
71 IControllerRegistryService controllerRegistryService;
72
73 topology.createSampleTopology1();
74 modContext = new FloodlightModuleContext();
75
76 floodLightProvider = createMock(IFloodlightProviderService.class);
77 datagridService = createMock(IDatagridService.class);
78 networkGraphService = createMock(ITopologyService.class);
79 controllerRegistryService = createMock(IControllerRegistryService.class);
80 eventChannel = createMock(IEventChannel.class);
81 expect(networkGraphService.getTopology()).andReturn(topology).anyTimes();
82 networkGraphService.registerTopologyListener(anyObject(ITopologyListener.class));
83 expectLastCall();
84
85 expect(datagridService.createChannel("onos.device", Long.class, OnosDevice.class))
86 .andReturn(eventChannel).once();
87 expect(topology.getOutgoingLink((long)1,(long)100)).andReturn(null).anyTimes();
88 expect(datagridService.addListener(
89 eq("onos.device"),
90 anyObject(IEventChannelListener.class),
91 eq(Long.class),
92 eq(OnosDevice.class)))
93 .andReturn(eventChannel).once();
94
95 replay(datagridService);
96 replay(networkGraphService);
97 replay(controllerRegistryService);
98
99 modContext.addService(IDatagridService.class,datagridService);
100 modContext.addService(ITopologyService.class,networkGraphService);
101 modContext.addService(IFloodlightProviderService.class, floodLightProvider);
102 modContext.getServiceImpl(IFloodlightProviderService.class);
103 sw1Dpid = 1L;
104 sw1 = createMockSwitch(sw1Dpid);
105 replay(sw1);
106
107 sw1DevPort = 100;
108
109 odm = new OnosDeviceManager();
110 /*
111 * Broadcast address
112 */
113 this.pkt0 = new Ethernet()
114 .setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
115 .setSourceMACAddress("00:44:33:22:11:33")
116 .setEtherType(Ethernet.TYPE_IPV4)
117 .setPayload(
118 new IPv4()
119 .setTtl((byte) 128)
120 .setSourceAddress("192.168.10.1")
121 .setDestinationAddress("192.168.255.255")
122 .setPayload(new UDP()
123 .setSourcePort((short) 5000)
124 .setDestinationPort((short) 5001)
125 .setPayload(new Data(new byte[]{0x01}))));
126 /*
127 * Normal IPv4 packet
128 */
129 this.pkt1 = new Ethernet()
130 .setDestinationMACAddress("00:11:22:33:44:55")
131 .setSourceMACAddress("00:44:33:22:11:00")
132 .setEtherType(Ethernet.TYPE_IPV4)
133 .setPayload(
134 new IPv4()
135 .setTtl((byte) 128)
136 .setSourceAddress("192.168.1.1")
137 .setDestinationAddress("192.168.1.2")
138 .setPayload(new UDP()
139 .setSourcePort((short) 5000)
140 .setDestinationPort((short) 5001)
141 .setPayload(new Data(new byte[]{0x01}))));
142 /*
143 * Same MAC header as pkt1,but not IP address set
144 */
145 this.pkt2 = new Ethernet()
146 .setSourceMACAddress("00:44:33:22:11:01")
147 .setDestinationMACAddress("00:11:22:33:44:55")
148 .setEtherType(Ethernet.TYPE_IPV4)
149 .setPayload(
150 new IPv4()
151 .setTtl((byte) 128)
152 .setPayload(new UDP()
153 .setSourcePort((short) 5000)
154 .setDestinationPort((short) 5001)
155 .setPayload(new Data(new byte[]{0x01}))));
156 /*
157 * DHCP packet
158 */
159 this.pkt3 = new Ethernet()
160 .setSourceMACAddress("00:44:33:22:11:01")
161 .setDestinationMACAddress("00:11:22:33:44:55")
162 .setEtherType(Ethernet.TYPE_IPV4)
163 .setPayload(
164 new IPv4()
165 .setTtl((byte) 128)
166 .setSourceAddress("192.168.1.1")
167 .setDestinationAddress("192.168.1.2")
168 .setPayload(new UDP()
169 .setSourcePort((short) 5000)
170 .setDestinationPort((short) 5001)
171 .setChecksum((short) 0)
172 .setPayload(
173 new DHCP()
174 .setOpCode(DHCP.OPCODE_REPLY)
175 .setHardwareType(DHCP.HWTYPE_ETHERNET)
176 .setHardwareAddressLength((byte) 6)
177 .setHops((byte) 0)
178 .setTransactionId(0x00003d1d)
179 .setSeconds((short) 0)
180 .setFlags((short) 0)
181 .setClientIPAddress(0)
182 .setYourIPAddress(0)
183 .setServerIPAddress(0)
184 .setGatewayIPAddress(0))));
185 /*
186 * ARP packet
187 */
188 this.pkt4 = new Ethernet()
189 .setSourceMACAddress("00:44:33:22:11:01")
190 .setDestinationMACAddress("00:11:22:33:44:55")
191 .setEtherType(Ethernet.TYPE_ARP)
192 .setPayload(
193 new ARP()
194 .setHardwareType(ARP.HW_TYPE_ETHERNET)
195 .setProtocolType(ARP.PROTO_TYPE_IP)
196 .setHardwareAddressLength((byte) 6)
197 .setProtocolAddressLength((byte) 4)
198 .setOpCode(ARP.OP_REPLY)
199 .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
200 .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
201 .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
202 .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
203
204
205 this.pktIn = new OFPacketIn()
206 .setInPort(sw1DevPort);
207
208 lastSeenTimestamp = new Date(1);
209
210 odm.init(modContext);
211 odm.startUp(modContext);
212 }
213
214 @Override
215 @After
216 public void tearDown() throws Exception {
217 }
218
219 public IOFSwitch createMockSwitch(Long id) {
220 IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
221 expect(mockSwitch.getId()).andReturn(id).anyTimes();
222 return mockSwitch;
223 }
224
225 /**
226 * Test set operation on lastSeenTimstamp field in OnosDevice
227 */
228 @Test
229 public void testSetLastSeenTimestamp() {
230 Ethernet eth = (Ethernet)pkt1;
231 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
232
233 floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
234 srcDevice.setLastSeenTimestamp(lastSeenTimestamp);
235 assertEquals(lastSeenTimestamp, srcDevice.getLastSeenTimestamp());
236 }
237 /**
238 * test the functionality to get the source device from Packet header
239 * information.
240 */
241 @Test
242 public void testGetSourceDeviceFromPacket() {
243 byte[] address = new byte[] {0x00,0x44,0x33,0x22,0x11,0x01};
244 MACAddress srcMac = new MACAddress(address);
245 IPv4 v4Pkt = new IPv4()
246 .setSourceAddress("192.168.1.1")
247 .setDestinationAddress("192.168.1.2");
248 OnosDevice dev1 = new OnosDevice(srcMac,
249 null,
250 v4Pkt.getSourceAddress(),
251 sw1Dpid,
252 sw1DevPort,
253 null);
254
255 /*
256 * test DHCP packet case
257 */
258 Ethernet eth = (Ethernet)pkt3;
259 OnosDevice dev2 = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
260 assertEquals(dev1, dev2);
261
262 /*
263 * test ARP packet case
264 */
265 eth = (Ethernet)pkt4;
266 dev2 = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
267 assertEquals(dev1, dev2);
268 }
269
270 /**
271 * This test will invoke addOnosDevice to add a new device through Packet pkt1
272 */
273 @Test
274 public void testProcessPacketInAddNewDevice() {
275 Ethernet eth = (Ethernet)pkt1;
276 Long longmac = eth.getSourceMAC().toLong();
277 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
278
279 floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
280 EasyMock.expectLastCall();
281 eventChannel.addEntry(longmac, srcDevice);
282 EasyMock.expectLastCall();
283 floodLightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
284 EasyMock.expectLastCall();
285 replay(floodLightProvider, eventChannel);
286
287 Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet)pkt1);
288 assertEquals(Command.CONTINUE, cmd);
289
290 verify(eventChannel);
291 }
292
293 /**
294 * This test will test return Command.STOP path in processPacketIn method
295 * by injecting a broadcast packet
296 */
297 @Test
298 public void testProcessPacketInStop() {
299 Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet)pkt0);
300 assertEquals(Command.STOP, cmd);
301 }
302
303 /**
304 * This tests same packet received case.
305 */
306 @Test
307 public void testProcessPacketInSamePacket() {
308 Ethernet eth = (Ethernet)pkt2;
309 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
310 odm.entryAdded(srcDevice);
311 srcDevice.setLastSeenTimestamp(lastSeenTimestamp);
312
313 Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet)pkt2);
314 assertEquals(Command.CONTINUE, cmd);
315 assertTrue(lastSeenTimestamp.before(srcDevice.getLastSeenTimestamp()));
316 }
317
318 /**
319 * This tests the packet with the same MAC but the second one without IP address
320 */
321 @Test
322 public void testProcessPacketInNoIpAddress() {
323 Ethernet eth = (Ethernet)pkt3;
324 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
325 odm.entryAdded(srcDevice);
326 srcDevice.setLastSeenTimestamp(lastSeenTimestamp);
327
328 Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet)pkt2);
329 assertEquals(Command.CONTINUE, cmd);
330 assertTrue(lastSeenTimestamp.before(srcDevice.getLastSeenTimestamp()));
331 }
332
333 /**
334 * Test add a device from the information from packet
335 */
336 @Test
337 public void testAddOnosDevice() {
338 Ethernet eth = (Ethernet)pkt1;
339 Long longmac = eth.getSourceMAC().toLong();
340 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
341
342 floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
343 EasyMock.expectLastCall();
344 eventChannel.addEntry(longmac, srcDevice);
345 EasyMock.expectLastCall();
346 floodLightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
347 EasyMock.expectLastCall();
348 replay(floodLightProvider, eventChannel);
349
350 odm.addOnosDevice(longmac, srcDevice);
351
352 verify(eventChannel);
353 }
354
355 /**
356 * Test delete a device
357 */
358 @Test
359 public void testDeleteOnosDevice() {
360 Ethernet eth = (Ethernet)pkt1;
361 Long longmac = eth.getSourceMAC().toLong();
362 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
363
364 floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
365 EasyMock.expectLastCall();
366 eventChannel.removeEntry(longmac);
367 EasyMock.expectLastCall();
368 floodLightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
369 EasyMock.expectLastCall();
370 replay(floodLightProvider, eventChannel);
371
372 odm.deleteOnosDevice(srcDevice);
373
374 verify(eventChannel);
375 }
376
377 /**
378 * Test delete a device by using its source mac address
379 */
380 @Test
381 public void testDeleteOnosDeviceByMac() {
382 Ethernet eth = (Ethernet)pkt1;
383 MACAddress mac = eth.getSourceMAC();
384 Long longmac = mac.toLong();
385 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
386
387 floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
388 EasyMock.expectLastCall();
389 eventChannel.removeEntry(longmac);
390 EasyMock.expectLastCall();
391 floodLightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
392 EasyMock.expectLastCall();
393 replay(floodLightProvider, eventChannel);
394
395 odm.entryAdded(srcDevice);
396 odm.deleteOnosDeviceByMac(mac);
397 verify(eventChannel);
398 }
399}