blob: 2eb83d4afa7d151e68dfe07f9cfc91e673bd9377 [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();
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -070088 expect(topology.getOutgoingLink(1L, 100L)).andReturn(null).anyTimes();
Patrick Liuab1e6062014-05-05 11:12:13 -070089 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
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700100 modContext.addService(IDatagridService.class, datagridService);
101 modContext.addService(ITopologyService.class, networkGraphService);
Patrick Liuab1e6062014-05-05 11:12:13 -0700102 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 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700227 * Test set operation on lastSeenTimstamp field in OnosDevice.
Patrick Liuab1e6062014-05-05 11:12:13 -0700228 */
229 @Test
230 public void testSetLastSeenTimestamp() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700231 Ethernet eth = (Ethernet) pkt1;
Patrick Liuab1e6062014-05-05 11:12:13 -0700232 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() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700244 byte[] address = new byte[] {0x00, 0x44, 0x33, 0x22, 0x11, 0x01};
Patrick Liuab1e6062014-05-05 11:12:13 -0700245 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 */
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700255 Ethernet eth = (Ethernet) pkt3;
Patrick Liuab1e6062014-05-05 11:12:13 -0700256 OnosDevice dev2 = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
257 assertEquals(dev1, dev2);
258
259 /*
260 * test ARP packet case
261 */
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700262 eth = (Ethernet) pkt4;
Patrick Liuab1e6062014-05-05 11:12:13 -0700263 dev2 = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
264 assertEquals(dev1, dev2);
265 }
266
267 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700268 * This test will invoke addOnosDevice to add a new device through Packet pkt1.
Patrick Liuab1e6062014-05-05 11:12:13 -0700269 */
270 @Test
271 public void testProcessPacketInAddNewDevice() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700272 Ethernet eth = (Ethernet) pkt1;
Patrick Liuab1e6062014-05-05 11:12:13 -0700273 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
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700284 Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet) pkt1);
Patrick Liuab1e6062014-05-05 11:12:13 -0700285 assertEquals(Command.CONTINUE, cmd);
286
287 verify(eventChannel);
288 }
289
290 /**
291 * This test will test return Command.STOP path in processPacketIn method
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700292 * by injecting a broadcast packet.
Patrick Liuab1e6062014-05-05 11:12:13 -0700293 */
294 @Test
295 public void testProcessPacketInStop() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700296 Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet) pkt0);
Patrick Liuab1e6062014-05-05 11:12:13 -0700297 assertEquals(Command.STOP, cmd);
298 }
299
300 /**
301 * This tests same packet received case.
302 */
303 @Test
304 public void testProcessPacketInSamePacket() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700305 Ethernet eth = (Ethernet) pkt2;
Patrick Liuab1e6062014-05-05 11:12:13 -0700306 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
307 odm.entryAdded(srcDevice);
308 srcDevice.setLastSeenTimestamp(lastSeenTimestamp);
309
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700310 Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet) pkt2);
Patrick Liuab1e6062014-05-05 11:12:13 -0700311 assertEquals(Command.CONTINUE, cmd);
312 assertTrue(lastSeenTimestamp.before(srcDevice.getLastSeenTimestamp()));
313 }
314
315 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700316 * This tests the packet with the same MAC but the second one without IP address.
Patrick Liuab1e6062014-05-05 11:12:13 -0700317 */
318 @Test
319 public void testProcessPacketInNoIpAddress() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700320 Ethernet eth = (Ethernet) pkt3;
Patrick Liuab1e6062014-05-05 11:12:13 -0700321 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
322 odm.entryAdded(srcDevice);
323 srcDevice.setLastSeenTimestamp(lastSeenTimestamp);
324
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700325 Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet) pkt2);
Patrick Liuab1e6062014-05-05 11:12:13 -0700326 assertEquals(Command.CONTINUE, cmd);
327 assertTrue(lastSeenTimestamp.before(srcDevice.getLastSeenTimestamp()));
328 }
329
330 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700331 * Test add a device from the information from packet.
Patrick Liuab1e6062014-05-05 11:12:13 -0700332 */
333 @Test
334 public void testAddOnosDevice() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700335 Ethernet eth = (Ethernet) pkt1;
Patrick Liuab1e6062014-05-05 11:12:13 -0700336 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 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700353 * Test delete a device.
Patrick Liuab1e6062014-05-05 11:12:13 -0700354 */
355 @Test
356 public void testDeleteOnosDevice() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700357 Ethernet eth = (Ethernet) pkt1;
Patrick Liuab1e6062014-05-05 11:12:13 -0700358 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 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700375 * Test delete a device by using its source mac address.
Patrick Liuab1e6062014-05-05 11:12:13 -0700376 */
377 @Test
378 public void testDeleteOnosDeviceByMac() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700379 Ethernet eth = (Ethernet) pkt1;
Patrick Liuab1e6062014-05-05 11:12:13 -0700380 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}