blob: 256eb379f8b2c54cf84d1acb8ce454368d21bdf8 [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);
Patrick Liuab1e6062014-05-05 11:12:13 -0700246 OnosDevice dev1 = new OnosDevice(srcMac,
247 null,
Patrick Liuab1e6062014-05-05 11:12:13 -0700248 sw1Dpid,
249 sw1DevPort,
250 null);
251
252 /*
253 * test DHCP packet case
254 */
255 Ethernet eth = (Ethernet)pkt3;
256 OnosDevice dev2 = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
257 assertEquals(dev1, dev2);
258
259 /*
260 * test ARP packet case
261 */
262 eth = (Ethernet)pkt4;
263 dev2 = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
264 assertEquals(dev1, dev2);
265 }
266
267 /**
268 * This test will invoke addOnosDevice to add a new device through Packet pkt1
269 */
270 @Test
271 public void testProcessPacketInAddNewDevice() {
272 Ethernet eth = (Ethernet)pkt1;
273 Long longmac = eth.getSourceMAC().toLong();
274 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
275
276 floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
277 EasyMock.expectLastCall();
278 eventChannel.addEntry(longmac, srcDevice);
279 EasyMock.expectLastCall();
280 floodLightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
281 EasyMock.expectLastCall();
282 replay(floodLightProvider, eventChannel);
283
284 Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet)pkt1);
285 assertEquals(Command.CONTINUE, cmd);
286
287 verify(eventChannel);
288 }
289
290 /**
291 * This test will test return Command.STOP path in processPacketIn method
292 * by injecting a broadcast packet
293 */
294 @Test
295 public void testProcessPacketInStop() {
296 Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet)pkt0);
297 assertEquals(Command.STOP, cmd);
298 }
299
300 /**
301 * This tests same packet received case.
302 */
303 @Test
304 public void testProcessPacketInSamePacket() {
305 Ethernet eth = (Ethernet)pkt2;
306 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
307 odm.entryAdded(srcDevice);
308 srcDevice.setLastSeenTimestamp(lastSeenTimestamp);
309
310 Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet)pkt2);
311 assertEquals(Command.CONTINUE, cmd);
312 assertTrue(lastSeenTimestamp.before(srcDevice.getLastSeenTimestamp()));
313 }
314
315 /**
316 * This tests the packet with the same MAC but the second one without IP address
317 */
318 @Test
319 public void testProcessPacketInNoIpAddress() {
320 Ethernet eth = (Ethernet)pkt3;
321 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
322 odm.entryAdded(srcDevice);
323 srcDevice.setLastSeenTimestamp(lastSeenTimestamp);
324
325 Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet)pkt2);
326 assertEquals(Command.CONTINUE, cmd);
327 assertTrue(lastSeenTimestamp.before(srcDevice.getLastSeenTimestamp()));
328 }
329
330 /**
331 * Test add a device from the information from packet
332 */
333 @Test
334 public void testAddOnosDevice() {
335 Ethernet eth = (Ethernet)pkt1;
336 Long longmac = eth.getSourceMAC().toLong();
337 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
338
339 floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
340 EasyMock.expectLastCall();
341 eventChannel.addEntry(longmac, srcDevice);
342 EasyMock.expectLastCall();
343 floodLightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
344 EasyMock.expectLastCall();
345 replay(floodLightProvider, eventChannel);
346
347 odm.addOnosDevice(longmac, srcDevice);
348
349 verify(eventChannel);
350 }
351
352 /**
353 * Test delete a device
354 */
355 @Test
356 public void testDeleteOnosDevice() {
357 Ethernet eth = (Ethernet)pkt1;
358 Long longmac = eth.getSourceMAC().toLong();
359 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
360
361 floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
362 EasyMock.expectLastCall();
363 eventChannel.removeEntry(longmac);
364 EasyMock.expectLastCall();
365 floodLightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
366 EasyMock.expectLastCall();
367 replay(floodLightProvider, eventChannel);
368
369 odm.deleteOnosDevice(srcDevice);
370
371 verify(eventChannel);
372 }
373
374 /**
375 * Test delete a device by using its source mac address
376 */
377 @Test
378 public void testDeleteOnosDeviceByMac() {
379 Ethernet eth = (Ethernet)pkt1;
380 MACAddress mac = eth.getSourceMAC();
381 Long longmac = mac.toLong();
382 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
383
384 floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
385 EasyMock.expectLastCall();
386 eventChannel.removeEntry(longmac);
387 EasyMock.expectLastCall();
388 floodLightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
389 EasyMock.expectLastCall();
390 replay(floodLightProvider, eventChannel);
391
392 odm.entryAdded(srcDevice);
393 odm.deleteOnosDeviceByMac(mac);
394 verify(eventChannel);
395 }
396}