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