blob: 0b9defbf836b27615cc9f9e05128e456d1a4f4f6 [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/**
Patrick Liuab1e6062014-05-05 11:12:13 -070044 * Unit tests for the Device Manager module (OnosDeviceManger).
45 * These test cases check the result of add/delete device and
46 * verify the result of processPacketIn through inject faked packets
47 * floodLightProvider, datagridService, networkGraphService,
48 * controllerRegistryService, eventChannel are mocked out.
49 */
50public class OnosDeviceManagerTest extends FloodlightTestCase {
51 private IPacket pkt0, pkt1, pkt2, pkt3, pkt4;
52 private IOFSwitch sw1;
53 private long sw1Dpid;
54 private short sw1DevPort;
55 private OnosDeviceManager odm;
56 private OFPacketIn pktIn;
57 private FloodlightModuleContext modContext;
58 private ITopologyService networkGraphService;
59 private IEventChannel<Long, OnosDevice> eventChannel;
60 private IFloodlightProviderService floodLightProvider;
61 private Date lastSeenTimestamp;
62
63 @Override
64 @Before
Ray Milkeyff735142014-05-22 19:06:02 -070065 @SuppressWarnings("unchecked")
Patrick Liuab1e6062014-05-05 11:12:13 -070066 public void setUp() throws Exception {
67 super.setUp();
68 MockTopology topology = new MockTopology();
69 IDatagridService datagridService;
70 IControllerRegistryService controllerRegistryService;
71
72 topology.createSampleTopology1();
73 modContext = new FloodlightModuleContext();
74
75 floodLightProvider = createMock(IFloodlightProviderService.class);
76 datagridService = createMock(IDatagridService.class);
77 networkGraphService = createMock(ITopologyService.class);
78 controllerRegistryService = createMock(IControllerRegistryService.class);
79 eventChannel = createMock(IEventChannel.class);
80 expect(networkGraphService.getTopology()).andReturn(topology).anyTimes();
81 networkGraphService.registerTopologyListener(anyObject(ITopologyListener.class));
82 expectLastCall();
83
84 expect(datagridService.createChannel("onos.device", Long.class, OnosDevice.class))
85 .andReturn(eventChannel).once();
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -070086 expect(topology.getOutgoingLink(1L, 100L)).andReturn(null).anyTimes();
Patrick Liuab1e6062014-05-05 11:12:13 -070087 expect(datagridService.addListener(
88 eq("onos.device"),
89 anyObject(IEventChannelListener.class),
90 eq(Long.class),
91 eq(OnosDevice.class)))
92 .andReturn(eventChannel).once();
93
94 replay(datagridService);
95 replay(networkGraphService);
96 replay(controllerRegistryService);
97
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -070098 modContext.addService(IDatagridService.class, datagridService);
99 modContext.addService(ITopologyService.class, networkGraphService);
Patrick Liuab1e6062014-05-05 11:12:13 -0700100 modContext.addService(IFloodlightProviderService.class, floodLightProvider);
101 modContext.getServiceImpl(IFloodlightProviderService.class);
102 sw1Dpid = 1L;
103 sw1 = createMockSwitch(sw1Dpid);
104 replay(sw1);
105
106 sw1DevPort = 100;
107
108 odm = new OnosDeviceManager();
109 /*
Jonathan Hart7ab71612014-05-27 13:37:31 -0700110 * Broadcast source address
Patrick Liuab1e6062014-05-05 11:12:13 -0700111 */
112 this.pkt0 = new Ethernet()
Jonathan Hart7ab71612014-05-27 13:37:31 -0700113 .setDestinationMACAddress("00:44:33:22:11:33")
114 .setSourceMACAddress("FF:FF:FF:FF:FF:FF")
Patrick Liuab1e6062014-05-05 11:12:13 -0700115 .setEtherType(Ethernet.TYPE_IPV4)
116 .setPayload(
117 new IPv4()
118 .setTtl((byte) 128)
119 .setSourceAddress("192.168.10.1")
120 .setDestinationAddress("192.168.255.255")
121 .setPayload(new UDP()
122 .setSourcePort((short) 5000)
123 .setDestinationPort((short) 5001)
124 .setPayload(new Data(new byte[]{0x01}))));
125 /*
126 * Normal IPv4 packet
127 */
128 this.pkt1 = new Ethernet()
129 .setDestinationMACAddress("00:11:22:33:44:55")
130 .setSourceMACAddress("00:44:33:22:11:00")
131 .setEtherType(Ethernet.TYPE_IPV4)
132 .setPayload(
133 new IPv4()
134 .setTtl((byte) 128)
135 .setSourceAddress("192.168.1.1")
136 .setDestinationAddress("192.168.1.2")
137 .setPayload(new UDP()
138 .setSourcePort((short) 5000)
139 .setDestinationPort((short) 5001)
140 .setPayload(new Data(new byte[]{0x01}))));
141 /*
142 * Same MAC header as pkt1,but not IP address set
143 */
144 this.pkt2 = new Ethernet()
145 .setSourceMACAddress("00:44:33:22:11:01")
146 .setDestinationMACAddress("00:11:22:33:44:55")
147 .setEtherType(Ethernet.TYPE_IPV4)
148 .setPayload(
149 new IPv4()
150 .setTtl((byte) 128)
151 .setPayload(new UDP()
152 .setSourcePort((short) 5000)
153 .setDestinationPort((short) 5001)
154 .setPayload(new Data(new byte[]{0x01}))));
155 /*
156 * DHCP packet
157 */
158 this.pkt3 = new Ethernet()
159 .setSourceMACAddress("00:44:33:22:11:01")
160 .setDestinationMACAddress("00:11:22:33:44:55")
161 .setEtherType(Ethernet.TYPE_IPV4)
162 .setPayload(
163 new IPv4()
164 .setTtl((byte) 128)
165 .setSourceAddress("192.168.1.1")
166 .setDestinationAddress("192.168.1.2")
167 .setPayload(new UDP()
168 .setSourcePort((short) 5000)
169 .setDestinationPort((short) 5001)
170 .setChecksum((short) 0)
171 .setPayload(
172 new DHCP()
173 .setOpCode(DHCP.OPCODE_REPLY)
174 .setHardwareType(DHCP.HWTYPE_ETHERNET)
175 .setHardwareAddressLength((byte) 6)
176 .setHops((byte) 0)
177 .setTransactionId(0x00003d1d)
178 .setSeconds((short) 0)
179 .setFlags((short) 0)
180 .setClientIPAddress(0)
181 .setYourIPAddress(0)
182 .setServerIPAddress(0)
183 .setGatewayIPAddress(0))));
184 /*
185 * ARP packet
186 */
187 this.pkt4 = new Ethernet()
188 .setSourceMACAddress("00:44:33:22:11:01")
189 .setDestinationMACAddress("00:11:22:33:44:55")
190 .setEtherType(Ethernet.TYPE_ARP)
191 .setPayload(
192 new ARP()
193 .setHardwareType(ARP.HW_TYPE_ETHERNET)
194 .setProtocolType(ARP.PROTO_TYPE_IP)
195 .setHardwareAddressLength((byte) 6)
196 .setProtocolAddressLength((byte) 4)
197 .setOpCode(ARP.OP_REPLY)
198 .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
199 .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
200 .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
201 .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
202
203
204 this.pktIn = new OFPacketIn()
205 .setInPort(sw1DevPort);
206
207 lastSeenTimestamp = new Date(1);
208
209 odm.init(modContext);
210 odm.startUp(modContext);
211 }
212
213 @Override
214 @After
215 public void tearDown() throws Exception {
216 }
217
218 public IOFSwitch createMockSwitch(Long id) {
219 IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
220 expect(mockSwitch.getId()).andReturn(id).anyTimes();
221 return mockSwitch;
222 }
223
224 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700225 * Test set operation on lastSeenTimstamp field in OnosDevice.
Patrick Liuab1e6062014-05-05 11:12:13 -0700226 */
227 @Test
228 public void testSetLastSeenTimestamp() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700229 Ethernet eth = (Ethernet) pkt1;
Patrick Liuab1e6062014-05-05 11:12:13 -0700230 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
231
232 floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
233 srcDevice.setLastSeenTimestamp(lastSeenTimestamp);
234 assertEquals(lastSeenTimestamp, srcDevice.getLastSeenTimestamp());
235 }
236 /**
237 * test the functionality to get the source device from Packet header
238 * information.
239 */
240 @Test
241 public void testGetSourceDeviceFromPacket() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700242 byte[] address = new byte[] {0x00, 0x44, 0x33, 0x22, 0x11, 0x01};
Patrick Liuab1e6062014-05-05 11:12:13 -0700243 MACAddress srcMac = new MACAddress(address);
Patrick Liuab1e6062014-05-05 11:12:13 -0700244 OnosDevice dev1 = new OnosDevice(srcMac,
245 null,
Patrick Liuab1e6062014-05-05 11:12:13 -0700246 sw1Dpid,
247 sw1DevPort,
248 null);
249
250 /*
251 * test DHCP packet case
252 */
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700253 Ethernet eth = (Ethernet) pkt3;
Patrick Liuab1e6062014-05-05 11:12:13 -0700254 OnosDevice dev2 = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
255 assertEquals(dev1, dev2);
256
257 /*
258 * test ARP packet case
259 */
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700260 eth = (Ethernet) pkt4;
Patrick Liuab1e6062014-05-05 11:12:13 -0700261 dev2 = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
262 assertEquals(dev1, dev2);
263 }
264
265 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700266 * This test will invoke addOnosDevice to add a new device through Packet pkt1.
Patrick Liuab1e6062014-05-05 11:12:13 -0700267 */
268 @Test
269 public void testProcessPacketInAddNewDevice() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700270 Ethernet eth = (Ethernet) pkt1;
Patrick Liuab1e6062014-05-05 11:12:13 -0700271 Long longmac = eth.getSourceMAC().toLong();
272 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
273
274 floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
275 EasyMock.expectLastCall();
276 eventChannel.addEntry(longmac, srcDevice);
277 EasyMock.expectLastCall();
278 floodLightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
279 EasyMock.expectLastCall();
280 replay(floodLightProvider, eventChannel);
281
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700282 Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet) pkt1);
Patrick Liuab1e6062014-05-05 11:12:13 -0700283 assertEquals(Command.CONTINUE, cmd);
284
285 verify(eventChannel);
286 }
287
288 /**
289 * This test will test return Command.STOP path in processPacketIn method
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700290 * by injecting a broadcast packet.
Patrick Liuab1e6062014-05-05 11:12:13 -0700291 */
292 @Test
293 public void testProcessPacketInStop() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700294 Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet) pkt0);
Patrick Liuab1e6062014-05-05 11:12:13 -0700295 assertEquals(Command.STOP, cmd);
296 }
297
298 /**
299 * This tests same packet received case.
300 */
301 @Test
302 public void testProcessPacketInSamePacket() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700303 Ethernet eth = (Ethernet) pkt2;
Patrick Liuab1e6062014-05-05 11:12:13 -0700304 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
305 odm.entryAdded(srcDevice);
306 srcDevice.setLastSeenTimestamp(lastSeenTimestamp);
307
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700308 Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet) pkt2);
Patrick Liuab1e6062014-05-05 11:12:13 -0700309 assertEquals(Command.CONTINUE, cmd);
310 assertTrue(lastSeenTimestamp.before(srcDevice.getLastSeenTimestamp()));
311 }
312
313 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700314 * This tests the packet with the same MAC but the second one without IP address.
Patrick Liuab1e6062014-05-05 11:12:13 -0700315 */
316 @Test
317 public void testProcessPacketInNoIpAddress() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700318 Ethernet eth = (Ethernet) pkt3;
Patrick Liuab1e6062014-05-05 11:12:13 -0700319 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
320 odm.entryAdded(srcDevice);
321 srcDevice.setLastSeenTimestamp(lastSeenTimestamp);
322
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700323 Command cmd = odm.processPacketIn(sw1, pktIn, (Ethernet) pkt2);
Patrick Liuab1e6062014-05-05 11:12:13 -0700324 assertEquals(Command.CONTINUE, cmd);
325 assertTrue(lastSeenTimestamp.before(srcDevice.getLastSeenTimestamp()));
326 }
327
328 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700329 * Test add a device from the information from packet.
Patrick Liuab1e6062014-05-05 11:12:13 -0700330 */
331 @Test
332 public void testAddOnosDevice() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700333 Ethernet eth = (Ethernet) pkt1;
Patrick Liuab1e6062014-05-05 11:12:13 -0700334 Long longmac = eth.getSourceMAC().toLong();
335 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
336
337 floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
338 EasyMock.expectLastCall();
339 eventChannel.addEntry(longmac, srcDevice);
340 EasyMock.expectLastCall();
341 floodLightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
342 EasyMock.expectLastCall();
343 replay(floodLightProvider, eventChannel);
344
345 odm.addOnosDevice(longmac, srcDevice);
346
347 verify(eventChannel);
348 }
349
350 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700351 * Test delete a device.
Patrick Liuab1e6062014-05-05 11:12:13 -0700352 */
353 @Test
354 public void testDeleteOnosDevice() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700355 Ethernet eth = (Ethernet) pkt1;
Patrick Liuab1e6062014-05-05 11:12:13 -0700356 Long longmac = eth.getSourceMAC().toLong();
357 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
358
359 floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
360 EasyMock.expectLastCall();
361 eventChannel.removeEntry(longmac);
362 EasyMock.expectLastCall();
363 floodLightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
364 EasyMock.expectLastCall();
365 replay(floodLightProvider, eventChannel);
366
367 odm.deleteOnosDevice(srcDevice);
368
369 verify(eventChannel);
370 }
371
372 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700373 * Test delete a device by using its source mac address.
Patrick Liuab1e6062014-05-05 11:12:13 -0700374 */
375 @Test
376 public void testDeleteOnosDeviceByMac() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700377 Ethernet eth = (Ethernet) pkt1;
Patrick Liuab1e6062014-05-05 11:12:13 -0700378 MACAddress mac = eth.getSourceMAC();
379 Long longmac = mac.toLong();
380 OnosDevice srcDevice = odm.getSourceDeviceFromPacket(eth, sw1Dpid, sw1DevPort);
381
382 floodLightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(OnosDeviceManager.class));
383 EasyMock.expectLastCall();
384 eventChannel.removeEntry(longmac);
385 EasyMock.expectLastCall();
386 floodLightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
387 EasyMock.expectLastCall();
388 replay(floodLightProvider, eventChannel);
389
390 odm.entryAdded(srcDevice);
391 odm.deleteOnosDeviceByMac(mac);
392 verify(eventChannel);
393 }
394}