blob: b37efe33d4a3121afa12149ffd280be2ce209eb4 [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001/**
2 * Copyright 2011, Big Switch Networks, Inc.
3 * Originally created by David Erickson, Stanford University
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
6 * not use this file except in compliance with the License. You may obtain
7 * a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations
15 * under the License.
16 **/
17
18package net.floodlightcontroller.devicemanager.internal;
19
20
Jonathan Hart2fa28062013-11-25 20:16:28 -080021import static org.easymock.EasyMock.anyLong;
22import static org.easymock.EasyMock.anyShort;
23import static org.easymock.EasyMock.createMock;
24import static org.easymock.EasyMock.createStrictMock;
25import static org.easymock.EasyMock.expect;
26import static org.easymock.EasyMock.expectLastCall;
27import static org.easymock.EasyMock.isA;
28import static org.easymock.EasyMock.replay;
29import static org.easymock.EasyMock.reset;
30import static org.easymock.EasyMock.verify;
31import static org.junit.Assert.assertArrayEquals;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080032
33import java.util.ArrayList;
34import java.util.Arrays;
35import java.util.Calendar;
36import java.util.Collection;
37import java.util.Date;
38import java.util.EnumSet;
39import java.util.HashMap;
40import java.util.Iterator;
41import java.util.Map;
42import java.util.concurrent.ConcurrentHashMap;
43
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080044import net.floodlightcontroller.core.IFloodlightProviderService;
45import net.floodlightcontroller.core.IOFSwitch;
46import net.floodlightcontroller.core.module.FloodlightModuleContext;
47import net.floodlightcontroller.core.test.MockFloodlightProvider;
48import net.floodlightcontroller.core.test.MockThreadPoolService;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080049import net.floodlightcontroller.devicemanager.IDevice;
Jonathan Hart2fa28062013-11-25 20:16:28 -080050import net.floodlightcontroller.devicemanager.IDeviceListener;
51import net.floodlightcontroller.devicemanager.IDeviceService;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080052import net.floodlightcontroller.devicemanager.IEntityClass;
53import net.floodlightcontroller.devicemanager.IEntityClassifierService;
54import net.floodlightcontroller.devicemanager.SwitchPort;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080055import net.floodlightcontroller.devicemanager.SwitchPort.ErrorStatus;
56import net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl.ClassState;
57import net.floodlightcontroller.devicemanager.test.MockEntityClassifier;
58import net.floodlightcontroller.devicemanager.test.MockEntityClassifierMac;
59import net.floodlightcontroller.devicemanager.test.MockFlexEntityClassifier;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080060import net.floodlightcontroller.packet.ARP;
61import net.floodlightcontroller.packet.Ethernet;
62import net.floodlightcontroller.packet.IPacket;
63import net.floodlightcontroller.packet.IPv4;
64import net.floodlightcontroller.restserver.IRestApiService;
65import net.floodlightcontroller.restserver.RestApiServer;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080066import net.floodlightcontroller.test.FloodlightTestCase;
67import net.floodlightcontroller.threadpool.IThreadPoolService;
68import net.floodlightcontroller.topology.ITopologyService;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080069
70import org.easymock.EasyMock;
71import org.junit.Before;
Jonathan Harta117cfc2013-11-19 17:11:29 -080072import org.junit.Ignore;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080073import org.junit.Test;
74import org.openflow.protocol.OFPacketIn;
Jonathan Hart2fa28062013-11-25 20:16:28 -080075import org.openflow.protocol.OFPacketIn.OFPacketInReason;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080076import org.openflow.protocol.OFPhysicalPort;
77import org.openflow.protocol.OFType;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080078import org.openflow.util.HexString;
79import org.slf4j.Logger;
80import org.slf4j.LoggerFactory;
81
Jonathan Harta117cfc2013-11-19 17:11:29 -080082@Ignore //TODO broken 11/19/13, should fix
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080083public class DeviceManagerImplTest extends FloodlightTestCase {
84
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070085 protected final static Logger logger =
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080086 LoggerFactory.getLogger(DeviceManagerImplTest.class);
87
88 protected OFPacketIn packetIn_1, packetIn_2, packetIn_3;
89 protected IPacket testARPReplyPacket_1, testARPReplyPacket_2,
90 testARPReplyPacket_3;
91 protected IPacket testARPReqPacket_1, testARPReqPacket_2;
92 protected byte[] testARPReplyPacket_1_Srld, testARPReplyPacket_2_Srld;
93 private byte[] testARPReplyPacket_3_Serialized;
94 MockFloodlightProvider mockFloodlightProvider;
95 DeviceManagerImpl deviceManager;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080096
97 private IOFSwitch makeSwitchMock(long id) {
98 IOFSwitch mockSwitch = createMock(IOFSwitch.class);
99 expect(mockSwitch.getId()).andReturn(id).anyTimes();
100 expect(mockSwitch.getStringId()).
101 andReturn(HexString.toHexString(id, 6)).anyTimes();
102 expect(mockSwitch.getPort(anyShort())).
103 andReturn(new OFPhysicalPort()).anyTimes();
104 expect(mockSwitch.portEnabled(isA(OFPhysicalPort.class))).
105 andReturn(true).anyTimes();
106 return mockSwitch;
107 }
108
109 @Before
110 public void setUp() throws Exception {
111 super.setUp();
112
113 FloodlightModuleContext fmc = new FloodlightModuleContext();
114 RestApiServer restApi = new RestApiServer();
115 MockThreadPoolService tp = new MockThreadPoolService();
116 ITopologyService topology = createMock(ITopologyService.class);
117 fmc.addService(IThreadPoolService.class, tp);
118 mockFloodlightProvider = getMockFloodlightProvider();
119 deviceManager = new DeviceManagerImpl();
mininet73e7fb72013-12-03 14:25:53 -0800120
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800121 DefaultEntityClassifier entityClassifier = new DefaultEntityClassifier();
122 fmc.addService(IDeviceService.class, deviceManager);
Jonathan Hart2fa28062013-11-25 20:16:28 -0800123 //storageSource = new MemoryStorageSource();
124 //fmc.addService(IStorageSourceService.class, storageSource);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800125 fmc.addService(IFloodlightProviderService.class, mockFloodlightProvider);
126 fmc.addService(IRestApiService.class, restApi);
mininet73e7fb72013-12-03 14:25:53 -0800127
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800128 fmc.addService(IEntityClassifierService.class, entityClassifier);
129 fmc.addService(ITopologyService.class, topology);
130 tp.init(fmc);
131 restApi.init(fmc);
Jonathan Hart2fa28062013-11-25 20:16:28 -0800132 //storageSource.init(fmc);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800133 deviceManager.init(fmc);
mininet73e7fb72013-12-03 14:25:53 -0800134
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800135 entityClassifier.init(fmc);
Jonathan Hart2fa28062013-11-25 20:16:28 -0800136 //storageSource.startUp(fmc);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800137 deviceManager.startUp(fmc);
mininet73e7fb72013-12-03 14:25:53 -0800138
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800139 tp.startUp(fmc);
140 entityClassifier.startUp(fmc);
141
142 reset(topology);
143 topology.addListener(deviceManager);
144 expectLastCall().anyTimes();
145 replay(topology);
146
147 IOFSwitch mockSwitch1 = makeSwitchMock(1L);
148 IOFSwitch mockSwitch10 = makeSwitchMock(10L);
149 IOFSwitch mockSwitch5 = makeSwitchMock(5L);
150 IOFSwitch mockSwitch50 = makeSwitchMock(50L);
151 Map<Long, IOFSwitch> switches = new HashMap<Long,IOFSwitch>();
152 switches.put(1L, mockSwitch1);
153 switches.put(10L, mockSwitch10);
154 switches.put(5L, mockSwitch5);
155 switches.put(50L, mockSwitch50);
156 mockFloodlightProvider.setSwitches(switches);
157
158 replay(mockSwitch1, mockSwitch5, mockSwitch10, mockSwitch50);
159
160 // Build our test packet
161 this.testARPReplyPacket_1 = new Ethernet()
162 .setSourceMACAddress("00:44:33:22:11:01")
163 .setDestinationMACAddress("00:11:22:33:44:55")
164 .setEtherType(Ethernet.TYPE_ARP)
165 .setVlanID((short)5)
166 .setPayload(
167 new ARP()
168 .setHardwareType(ARP.HW_TYPE_ETHERNET)
169 .setProtocolType(ARP.PROTO_TYPE_IP)
170 .setHardwareAddressLength((byte) 6)
171 .setProtocolAddressLength((byte) 4)
172 .setOpCode(ARP.OP_REPLY)
173 .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
174 .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
175 .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
176 .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
177 this.testARPReplyPacket_1_Srld = testARPReplyPacket_1.serialize();
178
179 // Another test packet with a different source IP
180 this.testARPReplyPacket_2 = new Ethernet()
181 .setSourceMACAddress("00:44:33:22:11:01")
182 .setDestinationMACAddress("00:11:22:33:44:55")
183 .setEtherType(Ethernet.TYPE_ARP)
184 .setPayload(
185 new ARP()
186 .setHardwareType(ARP.HW_TYPE_ETHERNET)
187 .setProtocolType(ARP.PROTO_TYPE_IP)
188 .setHardwareAddressLength((byte) 6)
189 .setProtocolAddressLength((byte) 4)
190 .setOpCode(ARP.OP_REPLY)
191 .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
192 .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
193 .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
194 .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
195 this.testARPReplyPacket_2_Srld = testARPReplyPacket_2.serialize();
196
197 this.testARPReplyPacket_3 = new Ethernet()
198 .setSourceMACAddress("00:44:33:22:11:01")
199 .setDestinationMACAddress("00:11:22:33:44:55")
200 .setEtherType(Ethernet.TYPE_ARP)
201 .setPayload(
202 new ARP()
203 .setHardwareType(ARP.HW_TYPE_ETHERNET)
204 .setProtocolType(ARP.PROTO_TYPE_IP)
205 .setHardwareAddressLength((byte) 6)
206 .setProtocolAddressLength((byte) 4)
207 .setOpCode(ARP.OP_REPLY)
208 .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
209 .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.3"))
210 .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
211 .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
212 this.testARPReplyPacket_3_Serialized = testARPReplyPacket_3.serialize();
213
214 // Build the PacketIn
215 this.packetIn_1 = ((OFPacketIn) mockFloodlightProvider.
216 getOFMessageFactory().getMessage(OFType.PACKET_IN))
217 .setBufferId(-1)
218 .setInPort((short) 1)
219 .setPacketData(this.testARPReplyPacket_1_Srld)
220 .setReason(OFPacketInReason.NO_MATCH)
221 .setTotalLength((short) this.testARPReplyPacket_1_Srld.length);
222
223 // Build the PacketIn
224 this.packetIn_2 = ((OFPacketIn) mockFloodlightProvider.
225 getOFMessageFactory().getMessage(OFType.PACKET_IN))
226 .setBufferId(-1)
227 .setInPort((short) 1)
228 .setPacketData(this.testARPReplyPacket_2_Srld)
229 .setReason(OFPacketInReason.NO_MATCH)
230 .setTotalLength((short) this.testARPReplyPacket_2_Srld.length);
231
232 // Build the PacketIn
233 this.packetIn_3 = ((OFPacketIn) mockFloodlightProvider.
234 getOFMessageFactory().getMessage(OFType.PACKET_IN))
235 .setBufferId(-1)
236 .setInPort((short) 1)
237 .setPacketData(this.testARPReplyPacket_3_Serialized)
238 .setReason(OFPacketInReason.NO_MATCH)
239 .setTotalLength((short) this.testARPReplyPacket_3_Serialized.length);
240 }
241
242
243
244
245
246 @Test
247 public void testLastSeen() throws Exception {
248 Calendar c = Calendar.getInstance();
249 Date d1 = c.getTime();
250 Entity entity1 = new Entity(1L, null, null, null, null, d1);
251 c.add(Calendar.SECOND, 1);
252 Entity entity2 = new Entity(1L, null, 1, null, null, c.getTime());
253
254 IDevice d = deviceManager.learnDeviceByEntity(entity2);
255 assertEquals(c.getTime(), d.getLastSeen());
256 d = deviceManager.learnDeviceByEntity(entity1);
257 assertEquals(c.getTime(), d.getLastSeen());
258
259 deviceManager.startUp(null);
260 d = deviceManager.learnDeviceByEntity(entity1);
261 assertEquals(d1, d.getLastSeen());
262 d = deviceManager.learnDeviceByEntity(entity2);
263 assertEquals(c.getTime(), d.getLastSeen());
264 }
265
266 @Test
267 public void testEntityLearning() throws Exception {
268 IDeviceListener mockListener =
269 createStrictMock(IDeviceListener.class);
270
271 deviceManager.addListener(mockListener);
272 deviceManager.entityClassifier= new MockEntityClassifier();
273 deviceManager.startUp(null);
274
275 ITopologyService mockTopology = createMock(ITopologyService.class);
276 expect(mockTopology.getL2DomainId(anyLong())).
277 andReturn(1L).anyTimes();
278 expect(mockTopology.isBroadcastDomainPort(anyLong(), anyShort())).
279 andReturn(false).anyTimes();
280
281 expect(mockTopology.isAttachmentPointPort(anyLong(),
282 anyShort())).andReturn(true).anyTimes();
283 expect(mockTopology.isConsistent(10L, (short)1, 10L, (short)1)).
284 andReturn(true).anyTimes();
285 expect(mockTopology.isConsistent(1L, (short)1, 1L, (short)1)).
286 andReturn(true).anyTimes();
287 expect(mockTopology.isConsistent(50L, (short)3, 50L, (short)3)).
288 andReturn(true).anyTimes();
289
290 Date topologyUpdateTime = new Date();
291 expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
292 anyTimes();
293
294 deviceManager.topology = mockTopology;
295
296 Entity entity1 = new Entity(1L, null, null, 1L, 1, new Date());
297 Entity entity2 = new Entity(1L, null, null, 10L, 1, new Date());
298 Entity entity3 = new Entity(1L, null, 1, 10L, 1, new Date());
299 Entity entity4 = new Entity(1L, null, 1, 1L, 1, new Date());
300 Entity entity5 = new Entity(2L, (short)4, 1, 5L, 2, new Date());
301 Entity entity6 = new Entity(2L, (short)4, 1, 50L, 3, new Date());
302 Entity entity7 = new Entity(2L, (short)4, 2, 50L, 3, new Date());
303
304 mockListener.deviceAdded(isA(IDevice.class));
305 replay(mockListener, mockTopology);
306
307 Device d1 = deviceManager.learnDeviceByEntity(entity1);
308 assertSame(d1, deviceManager.learnDeviceByEntity(entity1));
309 assertSame(d1, deviceManager.findDeviceByEntity(entity1));
310 assertEquals(DefaultEntityClassifier.entityClass ,
311 d1.entityClass);
312 assertArrayEquals(new Short[] { -1 }, d1.getVlanId());
313 assertArrayEquals(new Integer[] { }, d1.getIPv4Addresses());
314
315 assertEquals(1, deviceManager.getAllDevices().size());
316 verify(mockListener);
317
318 reset(mockListener);
319 mockListener.deviceAdded(isA(IDevice.class));
320 replay(mockListener);
321
322 Device d2 = deviceManager.learnDeviceByEntity(entity2);
323 assertFalse(d1.equals(d2));
324 assertNotSame(d1, d2);
325 assertNotSame(d1.getDeviceKey(), d2.getDeviceKey());
326 assertEquals(MockEntityClassifier.testEC, d2.entityClass);
327 assertArrayEquals(new Short[] { -1 }, d2.getVlanId());
328 assertArrayEquals(new Integer[] { }, d2.getIPv4Addresses());
329
330 assertEquals(2, deviceManager.getAllDevices().size());
331 verify(mockListener);
332
333 reset(mockListener);
334 mockListener.deviceIPV4AddrChanged(isA(IDevice.class));
335 replay(mockListener);
336
337 Device d3 = deviceManager.learnDeviceByEntity(entity3);
338 assertNotSame(d2, d3);
339 assertEquals(d2.getDeviceKey(), d3.getDeviceKey());
340 assertEquals(MockEntityClassifier.testEC, d3.entityClass);
341 assertArrayEquals(new Integer[] { 1 },
342 d3.getIPv4Addresses());
343 assertArrayEquals(new SwitchPort[] { new SwitchPort(10L, 1) },
344 d3.getAttachmentPoints());
345 assertArrayEquals(new SwitchPort[] { new SwitchPort(10L, 1) },
346 d3.getAttachmentPoints(true));
347 assertArrayEquals(new Short[] { -1 },
348 d3.getVlanId());
349
350 assertEquals(2, deviceManager.getAllDevices().size());
351 verify(mockListener);
352
353 reset(mockListener);
354 mockListener.deviceIPV4AddrChanged(isA(IDevice.class));
355 replay(mockListener);
356
357 Device d4 = deviceManager.learnDeviceByEntity(entity4);
358 assertNotSame(d1, d4);
359 assertEquals(d1.getDeviceKey(), d4.getDeviceKey());
360 assertEquals(DefaultEntityClassifier.entityClass, d4.entityClass);
361 assertArrayEquals(new Integer[] { 1 },
362 d4.getIPv4Addresses());
363 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) },
364 d4.getAttachmentPoints());
365 assertArrayEquals(new Short[] { -1 },
366 d4.getVlanId());
367
368 assertEquals(2, deviceManager.getAllDevices().size());
369 verify(mockListener);
370
371 reset(mockListener);
372 mockListener.deviceAdded((isA(IDevice.class)));
373 replay(mockListener);
374
375 Device d5 = deviceManager.learnDeviceByEntity(entity5);
376 assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 2) },
377 d5.getAttachmentPoints());
378 assertArrayEquals(new Short[] { (short) 4 },
379 d5.getVlanId());
380 assertEquals(2L, d5.getMACAddress());
381 assertEquals("00:00:00:00:00:02", d5.getMACAddressString());
382 verify(mockListener);
383
384 reset(mockListener);
385 mockListener.deviceAdded(isA(IDevice.class));
386 replay(mockListener);
387
388 Device d6 = deviceManager.learnDeviceByEntity(entity6);
389 assertArrayEquals(new SwitchPort[] { new SwitchPort(50L, 3) },
390 d6.getAttachmentPoints());
391 assertArrayEquals(new Short[] { (short) 4 },
392 d6.getVlanId());
393
394 assertEquals(4, deviceManager.getAllDevices().size());
395 verify(mockListener);
396
397 reset(mockListener);
398 mockListener.deviceIPV4AddrChanged(isA(IDevice.class));
399 replay(mockListener);
400
401 Device d7 = deviceManager.learnDeviceByEntity(entity7);
402 assertNotSame(d6, d7);
403 assertEquals(d6.getDeviceKey(), d7.getDeviceKey());
404 assertArrayEquals(new SwitchPort[] { new SwitchPort(50L, 3) },
405 d7.getAttachmentPoints());
406 assertArrayEquals(new Short[] { (short) 4 },
407 d7.getVlanId());
408
409 assertEquals(4, deviceManager.getAllDevices().size());
410 verify(mockListener);
411
412
413 reset(mockListener);
414 replay(mockListener);
415
416 reset(deviceManager.topology);
417 deviceManager.topology.addListener(deviceManager);
418 expectLastCall().times(1);
419 replay(deviceManager.topology);
420
421 deviceManager.entityClassifier = new MockEntityClassifierMac();
422 deviceManager.startUp(null);
423 Entity entityNoClass = new Entity(5L, (short)1, 5, -1L, 1, new Date());
424 assertEquals(null, deviceManager.learnDeviceByEntity(entityNoClass));
425
426 verify(mockListener);
427 }
428
429
430 @Test
431 public void testAttachmentPointLearning() throws Exception {
432 IDeviceListener mockListener =
433 createStrictMock(IDeviceListener.class);
434
435 deviceManager.addListener(mockListener);
436
437 ITopologyService mockTopology = createMock(ITopologyService.class);
438 expect(mockTopology.getL2DomainId(1L)).
439 andReturn(1L).anyTimes();
440 expect(mockTopology.getL2DomainId(5L)).
441 andReturn(1L).anyTimes();
442 expect(mockTopology.getL2DomainId(10L)).
443 andReturn(10L).anyTimes();
444 expect(mockTopology.getL2DomainId(50L)).
445 andReturn(10L).anyTimes();
446 expect(mockTopology.isBroadcastDomainPort(anyLong(), anyShort())).
447 andReturn(false).anyTimes();
448 expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(),
449 anyLong(), anyShort())).andReturn(false).anyTimes();
450
451 expect(mockTopology.isAttachmentPointPort(anyLong(),
452 anyShort())).andReturn(true).anyTimes();
453 expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)1)).
454 andReturn(false).anyTimes();
455 expect(mockTopology.isConsistent(5L, (short)1, 10L, (short)1)).
456 andReturn(false).anyTimes();
457 expect(mockTopology.isConsistent(10L, (short)1, 50L, (short)1)).
458 andReturn(false).anyTimes();
459
460 Date topologyUpdateTime = new Date();
461 expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
462 anyTimes();
463
464 replay(mockTopology);
465
466 deviceManager.topology = mockTopology;
467
468 Calendar c = Calendar.getInstance();
469 Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime());
470 Entity entity0 = new Entity(1L, null, null, null, null, c.getTime());
471 c.add(Calendar.SECOND, 1);
472 Entity entity2 = new Entity(1L, null, null, 5L, 1, c.getTime());
473 c.add(Calendar.SECOND, 1);
474 Entity entity3 = new Entity(1L, null, null, 10L, 1, c.getTime());
475 c.add(Calendar.SECOND, 1);
476 Entity entity4 = new Entity(1L, null, null, 50L, 1, c.getTime());
477
478 IDevice d;
479 SwitchPort[] aps;
480 Integer[] ips;
481
482 mockListener.deviceAdded(isA(IDevice.class));
483 replay(mockListener);
484
485 deviceManager.learnDeviceByEntity(entity1);
486 d = deviceManager.learnDeviceByEntity(entity0);
487 assertEquals(1, deviceManager.getAllDevices().size());
488 aps = d.getAttachmentPoints();
489 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, aps);
490 ips = d.getIPv4Addresses();
491 assertArrayEquals(new Integer[] { 1 }, ips);
492 verify(mockListener);
493
494 reset(mockListener);
495 mockListener.deviceMoved((isA(IDevice.class)));
496 replay(mockListener);
497
498 d = deviceManager.learnDeviceByEntity(entity2);
499 assertEquals(1, deviceManager.getAllDevices().size());
500 aps = d.getAttachmentPoints();
501
502 assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1) }, aps);
503 ips = d.getIPv4Addresses();
504 assertArrayEquals(new Integer[] { 1 }, ips);
505 verify(mockListener);
506
507 reset(mockListener);
508 mockListener.deviceMoved((isA(IDevice.class)));
509 replay(mockListener);
510
511 d = deviceManager.learnDeviceByEntity(entity3);
512 assertEquals(1, deviceManager.getAllDevices().size());
513 aps = d.getAttachmentPoints();
514 assertArrayEquals(new SwitchPort[] {new SwitchPort(5L, 1), new SwitchPort(10L, 1)}, aps);
515 ips = d.getIPv4Addresses();
516 assertArrayEquals(new Integer[] { 1 }, ips);
517 verify(mockListener);
518
519 reset(mockListener);
520 mockListener.deviceMoved((isA(IDevice.class)));
521 replay(mockListener);
522
523 d = deviceManager.learnDeviceByEntity(entity4);
524 assertEquals(1, deviceManager.getAllDevices().size());
525 aps = d.getAttachmentPoints();
526 assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1),
527 new SwitchPort(50L, 1) }, aps);
528 ips = d.getIPv4Addresses();
529 assertArrayEquals(new Integer[] { 1 }, ips);
530 verify(mockListener);
531 }
532
533 @Test
534 public void testAttachmentPointSuppression() throws Exception {
535 IDeviceListener mockListener =
536 createStrictMock(IDeviceListener.class);
537
538 deviceManager.addListener(mockListener);
539
540 ITopologyService mockTopology = createMock(ITopologyService.class);
541 expect(mockTopology.getL2DomainId(1L)).
542 andReturn(1L).anyTimes();
543 expect(mockTopology.getL2DomainId(5L)).
544 andReturn(1L).anyTimes();
545 expect(mockTopology.getL2DomainId(10L)).
546 andReturn(10L).anyTimes();
547 expect(mockTopology.getL2DomainId(50L)).
548 andReturn(10L).anyTimes();
549 expect(mockTopology.isBroadcastDomainPort(anyLong(), anyShort())).
550 andReturn(false).anyTimes();
551 expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(),
552 anyLong(), anyShort())).andReturn(false).anyTimes();
553
554 expect(mockTopology.isAttachmentPointPort(anyLong(),
555 anyShort())).andReturn(true).anyTimes();
556 expect(mockTopology.isConsistent(5L, (short)1, 50L, (short)1)).
557 andReturn(false).anyTimes();
558
559 Date topologyUpdateTime = new Date();
560 expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
561 anyTimes();
562
563 replay(mockTopology);
564
565 deviceManager.topology = mockTopology;
566 // suppress (1L, 1) and (10L, 1)
567 deviceManager.addSuppressAPs(1L, (short)1);
568 deviceManager.addSuppressAPs(10L, (short)1);
569
570 Calendar c = Calendar.getInstance();
571 Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime());
572 Entity entity0 = new Entity(1L, null, null, null, null, c.getTime());
573 c.add(Calendar.SECOND, 1);
574 Entity entity2 = new Entity(1L, null, null, 5L, 1, c.getTime());
575 c.add(Calendar.SECOND, 1);
576 Entity entity3 = new Entity(1L, null, null, 10L, 1, c.getTime());
577 c.add(Calendar.SECOND, 1);
578 Entity entity4 = new Entity(1L, null, null, 50L, 1, c.getTime());
579
580 IDevice d;
581 SwitchPort[] aps;
582 Integer[] ips;
583
584 mockListener.deviceAdded(isA(IDevice.class));
585 replay(mockListener);
586
587 deviceManager.learnDeviceByEntity(entity1);
588 d = deviceManager.learnDeviceByEntity(entity0);
589 assertEquals(1, deviceManager.getAllDevices().size());
590 aps = d.getAttachmentPoints();
591 assertEquals(aps.length, 0);
592 ips = d.getIPv4Addresses();
593 assertArrayEquals(new Integer[] { 1 }, ips);
594 verify(mockListener);
595
596 reset(mockListener);
597 mockListener.deviceMoved((isA(IDevice.class)));
598 replay(mockListener);
599
600 d = deviceManager.learnDeviceByEntity(entity2);
601 assertEquals(1, deviceManager.getAllDevices().size());
602 aps = d.getAttachmentPoints();
603 assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1) }, aps);
604 ips = d.getIPv4Addresses();
605 assertArrayEquals(new Integer[] { 1 }, ips);
606 verify(mockListener);
607
608 reset(mockListener);
609 mockListener.deviceMoved((isA(IDevice.class)));
610 replay(mockListener);
611
612 d = deviceManager.learnDeviceByEntity(entity3);
613 assertEquals(1, deviceManager.getAllDevices().size());
614 aps = d.getAttachmentPoints();
615 assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1) }, aps);
616 ips = d.getIPv4Addresses();
617 assertArrayEquals(new Integer[] { 1 }, ips);
618 //verify(mockListener); // There is no device movement here; no not needed.
619
620 reset(mockListener);
621 mockListener.deviceMoved((isA(IDevice.class)));
622 replay(mockListener);
623
624 d = deviceManager.learnDeviceByEntity(entity4);
625 assertEquals(1, deviceManager.getAllDevices().size());
626 aps = d.getAttachmentPoints();
627 assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1),
628 new SwitchPort(50L, 1) }, aps);
629 ips = d.getIPv4Addresses();
630 assertArrayEquals(new Integer[] { 1 }, ips);
631 verify(mockListener);
632 }
633
634 @Test
635 public void testBDAttachmentPointLearning() throws Exception {
636 ITopologyService mockTopology = createMock(ITopologyService.class);
637 expect(mockTopology.getL2DomainId(anyLong())).
638 andReturn(1L).anyTimes();
639 expect(mockTopology.isAttachmentPointPort(anyLong(), anyShort())).
640 andReturn(true).anyTimes();
641 expect(mockTopology.isBroadcastDomainPort(1L, (short)1)).
642 andReturn(false).anyTimes();
643 expect(mockTopology.isBroadcastDomainPort(1L, (short)2)).
644 andReturn(true).anyTimes();
645 expect(mockTopology.isInSameBroadcastDomain(1L, (short)1,
646 1L, (short)2)).andReturn(true).anyTimes();
647 expect(mockTopology.isInSameBroadcastDomain(1L, (short)2,
648 1L, (short)1)).andReturn(true).anyTimes();
649 expect(mockTopology.isConsistent(anyLong(), anyShort(), anyLong(), anyShort())).andReturn(false).anyTimes();
650
651 Date topologyUpdateTime = new Date();
652 expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
653 anyTimes();
654
655 replay(mockTopology);
656
657 deviceManager.topology = mockTopology;
658
659 Calendar c = Calendar.getInstance();
660 Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime());
661 c.add(Calendar.MILLISECOND,
662 (int)AttachmentPoint.OPENFLOW_TO_EXTERNAL_TIMEOUT/ 2);
663 Entity entity2 = new Entity(1L, null, null, 1L, 2, c.getTime());
664 c.add(Calendar.MILLISECOND,
665 (int)AttachmentPoint.OPENFLOW_TO_EXTERNAL_TIMEOUT / 2 + 1);
666 Entity entity3 = new Entity(1L, null, null, 1L, 2, c.getTime());
667
668 IDevice d;
669 SwitchPort[] aps;
670
671 d = deviceManager.learnDeviceByEntity(entity1);
672 assertEquals(1, deviceManager.getAllDevices().size());
673 aps = d.getAttachmentPoints();
674 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, aps);
675
676 // this timestamp is too soon; don't switch
677 d = deviceManager.learnDeviceByEntity(entity2);
678 assertEquals(1, deviceManager.getAllDevices().size());
679 aps = d.getAttachmentPoints();
680 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, aps);
681
682 // it should switch when we learn with a timestamp after the
683 // timeout
684 d = deviceManager.learnDeviceByEntity(entity3);
685 assertEquals(1, deviceManager.getAllDevices().size());
686 aps = d.getAttachmentPoints();
687 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 2) }, aps);
688 }
689
690
691 @Test
692 public void testPacketIn() throws Exception {
693 byte[] dataLayerSource =
694 ((Ethernet)this.testARPReplyPacket_1).getSourceMACAddress();
695
696 // Mock up our expected behavior
697 ITopologyService mockTopology = createMock(ITopologyService.class);
698 deviceManager.topology = mockTopology;
699 expect(mockTopology.isAttachmentPointPort(EasyMock.anyLong(),
700 EasyMock.anyShort())).
701 andReturn(true).anyTimes();
702 expect(mockTopology.isConsistent(EasyMock.anyLong(),
703 EasyMock.anyShort(),
704 EasyMock.anyLong(),
705 EasyMock.anyShort())).andReturn(false).
706 anyTimes();
707 expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes();
708 replay(mockTopology);
709
710 Date currentDate = new Date();
711
712 // build our expected Device
713 Integer ipaddr = IPv4.toIPv4Address("192.168.1.1");
714 Device device =
715 new Device(deviceManager,
716 new Long(deviceManager.deviceKeyCounter),
717 new Entity(Ethernet.toLong(dataLayerSource),
718 (short)5,
719 ipaddr,
720 1L,
721 1,
722 currentDate),
723 DefaultEntityClassifier.entityClass);
724
725
726
727
728 // Get the listener and trigger the packet in
729 IOFSwitch switch1 = mockFloodlightProvider.getSwitches().get(1L);
730 mockFloodlightProvider.dispatchMessage(switch1, this.packetIn_1);
731
732 // Verify the replay matched our expectations
733 // verify(mockTopology);
734
735 // Verify the device
736 Device rdevice = (Device)
737 deviceManager.findDevice(Ethernet.toLong(dataLayerSource),
738 (short)5, null, null, null);
739
740 assertEquals(device, rdevice);
741 assertEquals(new Short((short)5), rdevice.getVlanId()[0]);
742
743 Device result = null;
744 Iterator<? extends IDevice> dstiter =
745 deviceManager.queryClassDevices(device, null, null, ipaddr,
746 null, null);
747 if (dstiter.hasNext()) {
748 result = (Device)dstiter.next();
749 }
750
751 assertEquals(device, result);
752
753 device =
754 new Device(device,
755 new Entity(Ethernet.toLong(dataLayerSource),
756 (short)5,
757 ipaddr,
758 5L,
759 2,
760 currentDate));
761
762 reset(mockTopology);
763 expect(mockTopology.isAttachmentPointPort(anyLong(),
764 anyShort())).
765 andReturn(true).
766 anyTimes();
767 expect(mockTopology.isConsistent(EasyMock.anyLong(),
768 EasyMock.anyShort(),
769 EasyMock.anyLong(),
770 EasyMock.anyShort())).andReturn(false).
771 anyTimes();
772 expect(mockTopology.isBroadcastDomainPort(EasyMock.anyLong(),
773 EasyMock.anyShort()))
774 .andReturn(false)
775 .anyTimes();
776 expect(mockTopology.getL2DomainId(1L)).andReturn(1L).anyTimes();
777 expect(mockTopology.getL2DomainId(5L)).andReturn(1L).anyTimes();
778 expect(mockTopology.isInSameBroadcastDomain(1L, (short)1, 5L, (short)2)).
779 andReturn(false).anyTimes();
780
781 // Start recording the replay on the mocks
782 replay(mockTopology);
783 // Get the listener and trigger the packet in
784 IOFSwitch switch5 = mockFloodlightProvider.getSwitches().get(5L);
785 mockFloodlightProvider.
786 dispatchMessage(switch5, this.packetIn_1.setInPort((short)2));
787
788 // Verify the replay matched our expectations
789 verify(mockTopology);
790
791 // Verify the device
792 rdevice = (Device)
793 deviceManager.findDevice(Ethernet.toLong(dataLayerSource),
794 (short)5, null, null, null);
795 assertEquals(device, rdevice);
796 }
797
798
799 /**
800 * Note: Entity expiration does not result in device moved notification.
801 * @throws Exception
802 */
803 public void doTestEntityExpiration() throws Exception {
804 IDeviceListener mockListener =
805 createStrictMock(IDeviceListener.class);
806 mockListener.deviceIPV4AddrChanged(isA(IDevice.class));
807
808 ITopologyService mockTopology = createMock(ITopologyService.class);
809 expect(mockTopology.isAttachmentPointPort(anyLong(),
810 anyShort())).
811 andReturn(true).anyTimes();
812
813 expect(mockTopology.isBroadcastDomainPort(1L, (short)1)).andReturn(false).anyTimes();
814 expect(mockTopology.isBroadcastDomainPort(5L, (short)1)).andReturn(false).anyTimes();
815 expect(mockTopology.getL2DomainId(1L)).andReturn(1L).anyTimes();
816 expect(mockTopology.getL2DomainId(5L)).andReturn(5L).anyTimes();
817 expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)1)).
818 andReturn(false).anyTimes();
819
820 Date topologyUpdateTime = new Date();
821 expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
822 anyTimes();
823
824 replay(mockTopology);
825 deviceManager.topology = mockTopology;
826
827 Calendar c = Calendar.getInstance();
828 Entity entity1 = new Entity(1L, null, 2, 1L, 1, c.getTime());
829 c.add(Calendar.MILLISECOND, -DeviceManagerImpl.ENTITY_TIMEOUT-1);
830 Entity entity2 = new Entity(1L, null, 1, 5L, 1, c.getTime());
831
832 deviceManager.learnDeviceByEntity(entity1);
833 IDevice d = deviceManager.learnDeviceByEntity(entity2);
834 assertArrayEquals(new Integer[] { 1, 2 }, d.getIPv4Addresses());
835 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
836 new SwitchPort(5L, 1)},
837 d.getAttachmentPoints());
838 Iterator<? extends IDevice> diter =
839 deviceManager.queryClassDevices(d, null, null, 1, null, null);
840 assertTrue(diter.hasNext());
841 assertEquals(d.getDeviceKey(), diter.next().getDeviceKey());
842 diter = deviceManager.queryClassDevices(d, null, null, 2, null, null);
843 assertTrue(diter.hasNext());
844 assertEquals(d.getDeviceKey(), diter.next().getDeviceKey());
845
846
847 deviceManager.addListener(mockListener);
848 replay(mockListener);
849 deviceManager.entityCleanupTask.reschedule(0, null);
850
851 d = deviceManager.getDevice(d.getDeviceKey());
852 assertArrayEquals(new Integer[] { 2 }, d.getIPv4Addresses());
853
854 // Attachment points are not removed, previous ones are still valid.
855 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
856 new SwitchPort(5L, 1) },
857 d.getAttachmentPoints());
858 diter = deviceManager.queryClassDevices(d, null, null, 2, null, null);
859 assertTrue(diter.hasNext());
860 assertEquals(d.getDeviceKey(), diter.next().getDeviceKey());
861 diter = deviceManager.queryClassDevices(d, null, null, 1, null, null);
862 assertFalse(diter.hasNext());
863
864 d = deviceManager.findDevice(1L, null, null, null, null);
865 assertArrayEquals(new Integer[] { 2 }, d.getIPv4Addresses());
866
867 // Attachment points are not removed, previous ones are still valid.
868 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
869 new SwitchPort(5L, 1) },
870 d.getAttachmentPoints());
871
872 verify(mockListener);
873 }
874
875 public void doTestDeviceExpiration() throws Exception {
876 IDeviceListener mockListener =
877 createStrictMock(IDeviceListener.class);
878 mockListener.deviceRemoved(isA(IDevice.class));
879
880 Calendar c = Calendar.getInstance();
881 c.add(Calendar.MILLISECOND, -DeviceManagerImpl.ENTITY_TIMEOUT-1);
882 Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime());
883 Entity entity2 = new Entity(1L, null, 2, 5L, 1, c.getTime());
884
885 ITopologyService mockTopology = createMock(ITopologyService.class);
886 deviceManager.topology = mockTopology;
887
888 expect(mockTopology.isAttachmentPointPort(EasyMock.anyLong(),
889 EasyMock.anyShort())).
890 andReturn(true).
891 anyTimes();
892 expect(mockTopology.getL2DomainId(1L)).andReturn(1L).anyTimes();
893 expect(mockTopology.getL2DomainId(5L)).andReturn(1L).anyTimes();
894 expect(mockTopology.isConsistent(EasyMock.anyLong(),
895 EasyMock.anyShort(),
896 EasyMock.anyLong(),
897 EasyMock.anyShort())).andReturn(false).
898 anyTimes();
899 expect(mockTopology.isBroadcastDomainPort(EasyMock.anyLong(),
900 EasyMock.anyShort())).
901 andReturn(false).anyTimes();
902 replay(mockTopology);
903
904 IDevice d = deviceManager.learnDeviceByEntity(entity2);
905 d = deviceManager.learnDeviceByEntity(entity1);
906 assertArrayEquals(new Integer[] { 1, 2 }, d.getIPv4Addresses());
907
908 deviceManager.addListener(mockListener);
909 replay(mockListener);
910 deviceManager.entityCleanupTask.reschedule(0, null);
911
912 IDevice r = deviceManager.getDevice(d.getDeviceKey());
913 assertNull(r);
914 Iterator<? extends IDevice> diter =
915 deviceManager.queryClassDevices(d, null, null, 1, null, null);
916 assertFalse(diter.hasNext());
917
918 r = deviceManager.findDevice(1L, null, null, null, null);
919 assertNull(r);
920
921 verify(mockListener);
922 }
923
924 /*
925 * A ConcurrentHashMap for devices (deviceMap) that can be used to test
926 * code that specially handles concurrent modification situations. In
927 * particular, we overwrite values() and will replace / remove all the
928 * elements returned by values.
929 *
930 * The remove flag in the constructor specifies if devices returned by
931 * values() should be removed or replaced.
932 */
933 protected static class ConcurrentlyModifiedDeviceMap
934 extends ConcurrentHashMap<Long, Device> {
935 private static final long serialVersionUID = 7784938535441180562L;
936 protected boolean remove;
937 public ConcurrentlyModifiedDeviceMap(boolean remove) {
938 super();
939 this.remove = remove;
940 }
941
942 @Override
943 public Collection<Device> values() {
944 // Get the values from the real map and copy them since
945 // the collection returned by values can reflect changed
946 Collection<Device> devs = new ArrayList<Device>(super.values());
947 for (Device d: devs) {
948 if (remove) {
949 // We remove the device from the underlying map
950 super.remove(d.getDeviceKey());
951 } else {
952 super.remove(d.getDeviceKey());
953 // We add a different Device instance with the same
954 // key to the map. We'll do some hackery so the device
955 // is different enough to compare differently in equals
956 // but otherwise looks the same.
957 // It's ugly but it works.
958 Entity[] curEntities = new Entity[d.getEntities().length];
959 int i = 0;
960 // clone entities
961 for (Entity e: d.getEntities()) {
962 curEntities[i] = new Entity (e.macAddress,
963 e.vlan,
964 e.ipv4Address,
965 e.switchDPID,
966 e.switchPort,
967 e.lastSeenTimestamp);
968 if (e.vlan == null)
969 curEntities[i].vlan = (short)1;
970 else
971 curEntities[i].vlan = (short)((e.vlan + 1 % 4095)+1);
972 i++;
973 }
974 Device newDevice = new Device(d, curEntities[0]);
975 newDevice.entities = curEntities;
976 assertEquals(false, newDevice.equals(d));
977 super.put(newDevice.getDeviceKey(), newDevice);
978 }
979 }
980 return devs;
981 }
982 }
983
984 @Test
985 public void testEntityExpiration() throws Exception {
986 doTestEntityExpiration();
987 }
988
989 @Test
990 public void testDeviceExpiration() throws Exception {
991 doTestDeviceExpiration();
992 }
993
994 /* Test correct entity cleanup behavior when a concurrent modification
995 * occurs.
996 */
997 @Test
998 public void testEntityExpirationConcurrentModification() throws Exception {
999 deviceManager.deviceMap = new ConcurrentlyModifiedDeviceMap(false);
1000 doTestEntityExpiration();
1001 }
1002
1003 /* Test correct entity cleanup behavior when a concurrent remove
1004 * occurs.
1005 */
1006 @Test
1007 public void testDeviceExpirationConcurrentRemove() throws Exception {
1008 deviceManager.deviceMap = new ConcurrentlyModifiedDeviceMap(true);
1009 doTestDeviceExpiration();
1010 }
1011
1012 /* Test correct entity cleanup behavior when a concurrent modification
1013 * occurs.
1014 */
1015 @Test
1016 public void testDeviceExpirationConcurrentModification() throws Exception {
1017 deviceManager.deviceMap = new ConcurrentlyModifiedDeviceMap(false);
1018 doTestDeviceExpiration();
1019 }
1020
1021
1022 @Test
1023 public void testAttachmentPointFlapping() throws Exception {
1024 Calendar c = Calendar.getInstance();
1025
1026 ITopologyService mockTopology = createMock(ITopologyService.class);
1027 expect(mockTopology.isAttachmentPointPort(anyLong(),
1028 anyShort())).andReturn(true).anyTimes();
1029 expect(mockTopology.isBroadcastDomainPort(anyLong(),
1030 anyShort())).
1031 andReturn(false).anyTimes();
1032 expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(),
1033 anyLong(), anyShort())).andReturn(false).anyTimes();
1034 expect(mockTopology.getL2DomainId(anyLong())).
1035 andReturn(1L).anyTimes();
1036 expect(mockTopology.isConsistent(1L, (short)1, 1L, (short)1)).
1037 andReturn(true).anyTimes();
1038 expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)1)).
1039 andReturn(false).anyTimes();
1040 expect(mockTopology.isConsistent(1L, (short)1, 10L, (short)1)).
1041 andReturn(false).anyTimes();
1042 expect(mockTopology.isConsistent(5L, (short)1, 10L, (short)1)).
1043 andReturn(false).anyTimes();
1044 expect(mockTopology.isConsistent(10L, (short)1, 1L, (short)1)).
1045 andReturn(false).anyTimes();
1046 expect(mockTopology.isConsistent(5L, (short)1, 1L, (short)1)).
1047 andReturn(false).anyTimes();
1048 expect(mockTopology.isConsistent(10L, (short)1, 5L, (short)1)).
1049 andReturn(false).anyTimes();
1050
1051 Date topologyUpdateTime = new Date();
1052 expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
1053 anyTimes();
1054
1055
1056 replay(mockTopology);
1057 deviceManager.topology = mockTopology;
1058
1059 Entity entity1 = new Entity(1L, null, null, 1L, 1, c.getTime());
1060 Entity entity1a = new Entity(1L, null, 1, 1L, 1, c.getTime());
1061 Entity entity2 = new Entity(1L, null, null, 5L, 1, c.getTime());
1062 Entity entity3 = new Entity(1L, null, null, 10L, 1, c.getTime());
1063 entity1.setLastSeenTimestamp(c.getTime());
1064 c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT/2);
1065 entity1a.setLastSeenTimestamp(c.getTime());
1066 c.add(Calendar.MILLISECOND, 1);
1067 entity2.setLastSeenTimestamp(c.getTime());
1068 c.add(Calendar.MILLISECOND, 1);
1069 entity3.setLastSeenTimestamp(c.getTime());
1070
1071
1072
1073 IDevice d;
1074 d = deviceManager.learnDeviceByEntity(entity1);
1075 d = deviceManager.learnDeviceByEntity(entity1a);
1076 d = deviceManager.learnDeviceByEntity(entity2);
1077 d = deviceManager.learnDeviceByEntity(entity3);
1078
1079 // all entities are active, so entity3 should win
1080 assertArrayEquals(new SwitchPort[] { new SwitchPort(10L, 1) },
1081 d.getAttachmentPoints());
1082
1083 assertArrayEquals(new SwitchPort[] { new SwitchPort(10L, 1),},
1084 d.getAttachmentPoints(true));
1085
1086 c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT/4);
1087 entity1.setLastSeenTimestamp(c.getTime());
1088 d = deviceManager.learnDeviceByEntity(entity1);
1089
1090 // all are still active; entity3 should still win
1091 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) },
1092 d.getAttachmentPoints());
1093 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
1094 new SwitchPort(5L, 1,
1095 ErrorStatus.DUPLICATE_DEVICE),
1096 new SwitchPort(10L, 1,
1097 ErrorStatus.DUPLICATE_DEVICE) },
1098 d.getAttachmentPoints(true));
1099
1100 c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT+2000);
1101 entity1.setLastSeenTimestamp(c.getTime());
1102 d = deviceManager.learnDeviceByEntity(entity1);
1103
1104 assertEquals(entity1.getActiveSince(), entity1.getLastSeenTimestamp());
1105 // entity1 should now be the only active entity
1106 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) },
1107 d.getAttachmentPoints());
1108 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) },
1109 d.getAttachmentPoints(true));
1110 }
1111
1112
1113 @Test
1114 public void testAttachmentPointFlappingTwoCluster() throws Exception {
1115 Calendar c = Calendar.getInstance();
1116
1117 ITopologyService mockTopology = createMock(ITopologyService.class);
1118 expect(mockTopology.isAttachmentPointPort(anyLong(),
1119 anyShort())).andReturn(true).anyTimes();
1120 expect(mockTopology.isBroadcastDomainPort(anyLong(),
1121 anyShort())).
1122 andReturn(false).anyTimes();
1123 expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(),
1124 anyLong(), anyShort())).andReturn(false).anyTimes();
1125 expect(mockTopology.getL2DomainId(1L)).
1126 andReturn(1L).anyTimes();
1127 expect(mockTopology.getL2DomainId(5L)).
1128 andReturn(5L).anyTimes();
1129 expect(mockTopology.isConsistent(1L, (short)1, 1L, (short)2)).
1130 andReturn(false).anyTimes();
1131 expect(mockTopology.isConsistent(1L, (short)2, 5L, (short)1)).
1132 andReturn(false).anyTimes();
1133 expect(mockTopology.isConsistent(5L, (short)1, 5L, (short)2)).
1134 andReturn(false).anyTimes();
1135 expect(mockTopology.isConsistent(1L, (short)2, 1L, (short)1)).
1136 andReturn(false).anyTimes();
1137 expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)1)).
1138 andReturn(false).anyTimes();
1139 expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)2)).
1140 andReturn(false).anyTimes();
1141 expect(mockTopology.isConsistent(5L, (short)2, 5L, (short)1)).
1142 andReturn(false).anyTimes();
1143
1144 Date topologyUpdateTime = new Date();
1145 expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
1146 anyTimes();
1147
1148 replay(mockTopology);
1149 deviceManager.topology = mockTopology;
1150
1151 Entity entity1 = new Entity(1L, null, null, 1L, 1, c.getTime());
1152 Entity entity2 = new Entity(1L, null, null, 1L, 2, c.getTime());
1153 Entity entity3 = new Entity(1L, null, null, 5L, 1, c.getTime());
1154 Entity entity4 = new Entity(1L, null, null, 5L, 2, c.getTime());
1155 entity1.setLastSeenTimestamp(c.getTime());
1156 c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT/2);
1157 c.add(Calendar.MILLISECOND, 1);
1158 entity2.setLastSeenTimestamp(c.getTime());
1159 c.add(Calendar.MILLISECOND, 1);
1160 entity3.setLastSeenTimestamp(c.getTime());
1161 c.add(Calendar.MILLISECOND, 1);
1162 entity4.setLastSeenTimestamp(c.getTime());
1163
1164 deviceManager.learnDeviceByEntity(entity1);
1165 deviceManager.learnDeviceByEntity(entity2);
1166 deviceManager.learnDeviceByEntity(entity3);
1167 IDevice d = deviceManager.learnDeviceByEntity(entity4);
1168
1169 // all entities are active, so entities 2,4 should win
1170 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 2),
1171 new SwitchPort(5L, 2) },
1172 d.getAttachmentPoints());
1173 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 2),
1174 new SwitchPort(5L, 2)},
1175 d.getAttachmentPoints(true));
1176
1177 c.add(Calendar.MILLISECOND, 1);
1178 entity1.setLastSeenTimestamp(c.getTime());
1179 d = deviceManager.learnDeviceByEntity(entity1);
1180
1181 // all entities are active, so entities 2,4 should win
1182 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
1183 new SwitchPort(5L, 2) },
1184 d.getAttachmentPoints());
1185 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
1186 new SwitchPort(5L, 2),
1187 new SwitchPort(1L, 2, ErrorStatus.DUPLICATE_DEVICE)},
1188 d.getAttachmentPoints(true));
1189
1190 c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT+1);
1191 entity1.setLastSeenTimestamp(c.getTime());
1192 d = deviceManager.learnDeviceByEntity(entity1);
1193
1194 // entities 3,4 are still in conflict, but 1 should be resolved
1195 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
1196 new SwitchPort(5L, 2) },
1197 d.getAttachmentPoints());
1198 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
1199 new SwitchPort(5L, 2)},
1200 d.getAttachmentPoints(true));
1201
1202 entity3.setLastSeenTimestamp(c.getTime());
1203 d = deviceManager.learnDeviceByEntity(entity3);
1204
1205 // no conflicts, 1 and 3 will win
1206 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
1207 new SwitchPort(5L, 1) },
1208 d.getAttachmentPoints());
1209 assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
1210 new SwitchPort(5L, 1) },
1211 d.getAttachmentPoints(true));
1212
1213 }
1214
1215 protected void doTestDeviceQuery() throws Exception {
1216 Entity entity1 = new Entity(1L, (short)1, 1, 1L, 1, new Date());
1217 Entity entity2 = new Entity(2L, (short)2, 2, 1L, 2, new Date());
1218 Entity entity3 = new Entity(3L, (short)3, 3, 5L, 1, new Date());
1219 Entity entity4 = new Entity(4L, (short)4, 3, 5L, 2, new Date());
1220 Entity entity5 = new Entity(1L, (short)4, 3, 5L, 2, new Date());
1221
1222 deviceManager.learnDeviceByEntity(entity1);
1223 deviceManager.learnDeviceByEntity(entity2);
1224 deviceManager.learnDeviceByEntity(entity3);
1225 deviceManager.learnDeviceByEntity(entity4);
1226
1227 Iterator<? extends IDevice> iter =
1228 deviceManager.queryDevices(null, (short)1, 1, null, null);
1229 int count = 0;
1230 while (iter.hasNext()) {
1231 count += 1;
1232 iter.next();
1233 }
1234 assertEquals(1, count);
1235
1236 iter = deviceManager.queryDevices(null, (short)3, 3, null, null);
1237 count = 0;
1238 while (iter.hasNext()) {
1239 count += 1;
1240 iter.next();
1241 }
1242 assertEquals(1, count);
1243
1244 iter = deviceManager.queryDevices(null, (short)1, 3, null, null);
1245 count = 0;
1246 while (iter.hasNext()) {
1247 count += 1;
1248 iter.next();
1249 }
1250 assertEquals(0, count);
1251
1252 deviceManager.learnDeviceByEntity(entity5);
1253 iter = deviceManager.queryDevices(null, (short)4, 3, null, null);
1254 count = 0;
1255 while (iter.hasNext()) {
1256 count += 1;
1257 iter.next();
1258 }
1259 assertEquals(2, count);
1260 }
1261
1262 @Test
1263 public void testDeviceIndex() throws Exception {
1264 EnumSet<IDeviceService.DeviceField> indexFields =
1265 EnumSet.noneOf(IDeviceService.DeviceField.class);
1266 indexFields.add(IDeviceService.DeviceField.IPV4);
1267 indexFields.add(IDeviceService.DeviceField.VLAN);
1268 deviceManager.addIndex(false, indexFields);
1269
1270 ITopologyService mockTopology = createMock(ITopologyService.class);
1271 deviceManager.topology = mockTopology;
1272 expect(mockTopology.isAttachmentPointPort(anyLong(),
1273 anyShort())).
1274 andReturn(true).anyTimes();
1275 expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes();
1276 replay(mockTopology);
1277 doTestDeviceQuery();
1278 }
1279
1280 @Test
1281 public void testDeviceQuery() throws Exception {
1282 ITopologyService mockTopology = createMock(ITopologyService.class);
1283 deviceManager.topology = mockTopology;
1284 expect(mockTopology.isAttachmentPointPort(anyLong(),
1285 anyShort())).
1286 andReturn(true).anyTimes();
1287 expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes();
1288 replay(mockTopology);
1289
1290 doTestDeviceQuery();
1291 }
1292
1293 protected void doTestDeviceClassQuery() throws Exception {
1294 Entity entity1 = new Entity(1L, (short)1, 1, 1L, 1, new Date());
1295 Entity entity2 = new Entity(2L, (short)2, 2, 1L, 2, new Date());
1296 Entity entity3 = new Entity(3L, (short)3, 3, 5L, 1, new Date());
1297 Entity entity4 = new Entity(4L, (short)4, 3, 5L, 2, new Date());
1298 Entity entity5 = new Entity(1L, (short)4, 3, 5L, 2, new Date());
1299
1300 IDevice d = deviceManager.learnDeviceByEntity(entity1);
1301 deviceManager.learnDeviceByEntity(entity2);
1302 deviceManager.learnDeviceByEntity(entity3);
1303 deviceManager.learnDeviceByEntity(entity4);
1304
1305 Iterator<? extends IDevice> iter =
1306 deviceManager.queryClassDevices(d, null,
1307 (short)1, 1, null, null);
1308 int count = 0;
1309 while (iter.hasNext()) {
1310 count += 1;
1311 iter.next();
1312 }
1313 assertEquals(1, count);
1314
1315 iter = deviceManager.queryClassDevices(d, null,
1316 (short)3, 3, null, null);
1317 count = 0;
1318 while (iter.hasNext()) {
1319 count += 1;
1320 iter.next();
1321 }
1322 assertEquals(1, count);
1323
1324 iter = deviceManager.queryClassDevices(d, null,
1325 (short)1, 3, null, null);
1326 count = 0;
1327 while (iter.hasNext()) {
1328 count += 1;
1329 iter.next();
1330 }
1331 assertEquals(0, count);
1332
1333 deviceManager.learnDeviceByEntity(entity5);
1334 iter = deviceManager.queryClassDevices(d, null,
1335 (short)4, 3, null, null);
1336 count = 0;
1337 while (iter.hasNext()) {
1338 count += 1;
1339 iter.next();
1340 }
1341 assertEquals(2, count);
1342 }
1343
1344 @Test
1345 public void testDeviceClassIndex() throws Exception {
1346 EnumSet<IDeviceService.DeviceField> indexFields =
1347 EnumSet.noneOf(IDeviceService.DeviceField.class);
1348 indexFields.add(IDeviceService.DeviceField.IPV4);
1349 indexFields.add(IDeviceService.DeviceField.VLAN);
1350 deviceManager.addIndex(true, indexFields);
1351
1352 ITopologyService mockTopology = createMock(ITopologyService.class);
1353 deviceManager.topology = mockTopology;
1354 expect(mockTopology.isAttachmentPointPort(anyLong(),
1355 anyShort())).
1356 andReturn(true).anyTimes();
1357 expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes();
1358 replay(mockTopology);
1359
1360 doTestDeviceClassQuery();
1361 }
1362
1363 @Test
1364 public void testDeviceClassQuery() throws Exception {
1365 ITopologyService mockTopology = createMock(ITopologyService.class);
1366 deviceManager.topology = mockTopology;
1367 expect(mockTopology.isAttachmentPointPort(anyLong(),
1368 anyShort())).
1369 andReturn(true).anyTimes();
1370 expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes();
1371 replay(mockTopology);
1372
1373 doTestDeviceClassQuery();
1374 }
1375
1376 @Test
1377 public void testFindDevice() {
1378 boolean exceptionCaught;
1379 deviceManager.entityClassifier= new MockEntityClassifierMac();
1380 deviceManager.startUp(null);
1381
1382 ITopologyService mockTopology = createMock(ITopologyService.class);
1383 deviceManager.topology = mockTopology;
1384 expect(mockTopology.isAttachmentPointPort(anyLong(),
1385 anyShort())).
1386 andReturn(true).anyTimes();
1387 expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes();
1388 replay(mockTopology);
1389
1390 Entity entity1 = new Entity(1L, (short)1, 1, 1L, 1, new Date());
1391 Entity entity2 = new Entity(2L, (short)2, 2, 1L, 2, new Date());
1392 Entity entity2b = new Entity(22L, (short)2, 2, 1L, 2, new Date());
1393
1394 Entity entity3 = new Entity(3L, (short)1, 3, 2L, 1, new Date());
1395 Entity entity4 = new Entity(4L, (short)2, 4, 2L, 2, new Date());
1396
1397 Entity entity5 = new Entity(5L, (short)1, 5, 3L, 1, new Date());
1398
1399
1400 IDevice d1 = deviceManager.learnDeviceByEntity(entity1);
1401 IDevice d2 = deviceManager.learnDeviceByEntity(entity2);
1402 IDevice d3 = deviceManager.learnDeviceByEntity(entity3);
1403 IDevice d4 = deviceManager.learnDeviceByEntity(entity4);
1404 IDevice d5 = deviceManager.learnDeviceByEntity(entity5);
1405
1406 // Make sure the entity classifier worked as expected
1407 assertEquals(MockEntityClassifierMac.testECMac1, d1.getEntityClass());
1408 assertEquals(MockEntityClassifierMac.testECMac1, d2.getEntityClass());
1409 assertEquals(MockEntityClassifierMac.testECMac2, d3.getEntityClass());
1410 assertEquals(MockEntityClassifierMac.testECMac2, d4.getEntityClass());
1411 assertEquals(DefaultEntityClassifier.entityClass,
1412 d5.getEntityClass());
1413
1414 // Look up the device using findDevice() which uses only the primary
1415 // index
1416 assertEquals(d1, deviceManager.findDevice(entity1.getMacAddress(),
1417 entity1.getVlan(),
1418 entity1.getIpv4Address(),
1419 entity1.getSwitchDPID(),
1420 entity1.getSwitchPort()));
1421 // port changed. Device will be found through class index
1422 assertEquals(d1, deviceManager.findDevice(entity1.getMacAddress(),
1423 entity1.getVlan(),
1424 entity1.getIpv4Address(),
1425 entity1.getSwitchDPID(),
1426 entity1.getSwitchPort()+1));
1427 // VLAN changed. No device matches
1428 assertEquals(null, deviceManager.findDevice(entity1.getMacAddress(),
1429 (short)42,
1430 entity1.getIpv4Address(),
1431 entity1.getSwitchDPID(),
1432 entity1.getSwitchPort()));
1433 assertEquals(null, deviceManager.findDevice(entity1.getMacAddress(),
1434 null,
1435 entity1.getIpv4Address(),
1436 entity1.getSwitchDPID(),
1437 entity1.getSwitchPort()));
1438 assertEquals(d2, deviceManager.findDeviceByEntity(entity2));
1439 assertEquals(null, deviceManager.findDeviceByEntity(entity2b));
1440 assertEquals(d3, deviceManager.findDevice(entity3.getMacAddress(),
1441 entity3.getVlan(),
1442 entity3.getIpv4Address(),
1443 entity3.getSwitchDPID(),
1444 entity3.getSwitchPort()));
1445 // switch and port not set. throws exception
1446 exceptionCaught = false;
1447 try {
1448 assertEquals(null, deviceManager.findDevice(entity3.getMacAddress(),
1449 entity3.getVlan(),
1450 entity3.getIpv4Address(),
1451 null,
1452 null));
1453 }
1454 catch (IllegalArgumentException e) {
1455 exceptionCaught = true;
1456 }
1457 if (!exceptionCaught)
1458 fail("findDevice() did not throw IllegalArgumentException");
1459 assertEquals(d4, deviceManager.findDeviceByEntity(entity4));
1460 assertEquals(d5, deviceManager.findDevice(entity5.getMacAddress(),
1461 entity5.getVlan(),
1462 entity5.getIpv4Address(),
1463 entity5.getSwitchDPID(),
1464 entity5.getSwitchPort()));
1465 // switch and port not set. throws exception (swith/port are key
1466 // fields of IEntityClassifier but not d5.entityClass
1467 exceptionCaught = false;
1468 try {
1469 assertEquals(d5, deviceManager.findDevice(entity5.getMacAddress(),
1470 entity5.getVlan(),
1471 entity5.getIpv4Address(),
1472 null,
1473 null));
1474 }
1475 catch (IllegalArgumentException e) {
1476 exceptionCaught = true;
1477 }
1478 if (!exceptionCaught)
1479 fail("findDevice() did not throw IllegalArgumentException");
1480
1481
1482 Entity entityNoClass = new Entity(5L, (short)1, 5, -1L, 1, new Date());
1483 assertEquals(null, deviceManager.findDeviceByEntity(entityNoClass));
1484
1485
1486 // Now look up destination devices
1487 assertEquals(d1, deviceManager.findDestDevice(d2,
1488 entity1.getMacAddress(),
1489 entity1.getVlan(),
1490 entity1.getIpv4Address()));
1491 assertEquals(d1, deviceManager.findDestDevice(d2,
1492 entity1.getMacAddress(),
1493 entity1.getVlan(),
1494 null));
1495 assertEquals(null, deviceManager.findDestDevice(d2,
1496 entity1.getMacAddress(),
1497 (short) -1,
1498 0));
1499 }
1500
1501 @Test
1502 public void testGetIPv4Addresses() {
1503 // Looks like Date is only 1s granularity
1504
1505 ITopologyService mockTopology = createMock(ITopologyService.class);
1506 deviceManager.topology = mockTopology;
1507 expect(mockTopology.isAttachmentPointPort(anyLong(),
1508 anyShort())).
1509 andReturn(true).anyTimes();
1510 expect(mockTopology.getL2DomainId(anyLong())).andReturn(1L).anyTimes();
1511 expect(mockTopology.isConsistent(EasyMock.anyLong(),
1512 EasyMock.anyShort(),
1513 EasyMock.anyLong(),
1514 EasyMock.anyShort()))
1515 .andReturn(false)
1516 .anyTimes();
1517 expect(mockTopology.isBroadcastDomainPort(EasyMock.anyLong(),
1518 EasyMock.anyShort()))
1519 .andReturn(false)
1520 .anyTimes();
1521 expect(mockTopology.isInSameBroadcastDomain(EasyMock.anyLong(),
1522 EasyMock.anyShort(),
1523 EasyMock.anyLong(),
1524 EasyMock.anyShort())).
1525 andReturn(false).anyTimes();
1526 replay(mockTopology);
1527
1528 Entity e1 = new Entity(1L, (short)1, null, null, null, new Date(2000));
1529 Device d1 = deviceManager.learnDeviceByEntity(e1);
1530 assertArrayEquals(new Integer[0], d1.getIPv4Addresses());
1531
1532
1533 Entity e2 = new Entity(2L, (short)2, 2, null, null, new Date(2000));
1534 Device d2 = deviceManager.learnDeviceByEntity(e2);
1535 d2 = deviceManager.learnDeviceByEntity(e2);
1536 assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
1537 // More than one entity
1538 Entity e2b = new Entity(2L, (short)2, null, 2L, 2, new Date(3000));
1539 d2 = deviceManager.learnDeviceByEntity(e2b);
1540 assertEquals(2, d2.entities.length);
1541 assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
1542 // and now add an entity with an IP
1543 Entity e2c = new Entity(2L, (short)2, 2, 2L, 3, new Date(3000));
1544 d2 = deviceManager.learnDeviceByEntity(e2c);
1545 assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
1546 assertEquals(3, d2.entities.length);
1547
1548 // Other devices with different IPs shouldn't interfere
1549 Entity e3 = new Entity(3L, (short)3, 3, null, null, new Date(4000));
1550 Entity e3b = new Entity(3L, (short)3, 3, 3L, 3, new Date(4400));
1551 Device d3 = deviceManager.learnDeviceByEntity(e3);
1552 d3 = deviceManager.learnDeviceByEntity(e3b);
1553 assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
1554 assertArrayEquals(new Integer[] { 3 }, d3.getIPv4Addresses());
1555
1556 // Add another IP to d3
1557 Entity e3c = new Entity(3L, (short)3, 33, 3L, 3, new Date(4400));
1558 d3 = deviceManager.learnDeviceByEntity(e3c);
1559 Integer[] ips = d3.getIPv4Addresses();
1560 Arrays.sort(ips);
1561 assertArrayEquals(new Integer[] { 3, 33 }, ips);
1562
1563 // Add another device that also claims IP2 but is older than e2
1564 Entity e4 = new Entity(4L, (short)4, 2, null, null, new Date(1000));
1565 Entity e4b = new Entity(4L, (short)4, null, 4L, 4, new Date(1000));
1566 Device d4 = deviceManager.learnDeviceByEntity(e4);
1567 assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
1568 assertArrayEquals(new Integer[0], d4.getIPv4Addresses());
1569 // add another entity to d4
1570 d4 = deviceManager.learnDeviceByEntity(e4b);
1571 assertArrayEquals(new Integer[0], d4.getIPv4Addresses());
1572
1573 // Make e4 and e4a newer
1574 Entity e4c = new Entity(4L, (short)4, 2, null, null, new Date(5000));
1575 Entity e4d = new Entity(4L, (short)4, null, 4L, 5, new Date(5000));
1576 d4 = deviceManager.learnDeviceByEntity(e4c);
1577 d4 = deviceManager.learnDeviceByEntity(e4d);
1578 assertArrayEquals(new Integer[0], d2.getIPv4Addresses());
1579 // FIXME: d4 should not return IP4
1580 assertArrayEquals(new Integer[] { 2 }, d4.getIPv4Addresses());
1581
1582 // Add another newer entity to d2 but with different IP
1583 Entity e2d = new Entity(2L, (short)2, 22, 4L, 6, new Date(6000));
1584 d2 = deviceManager.learnDeviceByEntity(e2d);
1585 assertArrayEquals(new Integer[] { 22 }, d2.getIPv4Addresses());
1586 assertArrayEquals(new Integer[] { 2 }, d4.getIPv4Addresses());
1587
1588 // new IP for d2,d4 but with same timestamp. Both devices get the IP
1589 Entity e2e = new Entity(2L, (short)2, 42, 2L, 4, new Date(7000));
1590 d2 = deviceManager.learnDeviceByEntity(e2e);
1591 ips= d2.getIPv4Addresses();
1592 Arrays.sort(ips);
1593 assertArrayEquals(new Integer[] { 22, 42 }, ips);
1594 Entity e4e = new Entity(4L, (short)4, 42, 4L, 7, new Date(7000));
1595 d4 = deviceManager.learnDeviceByEntity(e4e);
1596 ips= d4.getIPv4Addresses();
1597 Arrays.sort(ips);
1598 assertArrayEquals(new Integer[] { 2, 42 }, ips);
1599
1600 // add a couple more IPs
1601 Entity e2f = new Entity(2L, (short)2, 4242, 2L, 5, new Date(8000));
1602 d2 = deviceManager.learnDeviceByEntity(e2f);
1603 ips= d2.getIPv4Addresses();
1604 Arrays.sort(ips);
1605 assertArrayEquals(new Integer[] { 22, 42, 4242 }, ips);
1606 Entity e4f = new Entity(4L, (short)4, 4242, 4L, 8, new Date(9000));
1607 d4 = deviceManager.learnDeviceByEntity(e4f);
1608 ips= d4.getIPv4Addresses();
1609 Arrays.sort(ips);
1610 assertArrayEquals(new Integer[] { 2, 42, 4242 }, ips);
1611 }
1612
1613 // TODO: this test should really go into a separate class that collects
1614 // unit tests for Device
1615 @Test
1616 public void testGetSwitchPortVlanId() {
1617 Entity entity1 = new Entity(1L, (short)1, null, 10L, 1, new Date());
1618 Entity entity2 = new Entity(1L, null, null, 10L, 1, new Date());
1619 Entity entity3 = new Entity(1L, (short)3, null, 1L, 1, new Date());
1620 Entity entity4 = new Entity(1L, (short)42, null, 1L, 1, new Date());
1621 Entity[] entities = new Entity[] { entity1, entity2,
1622 entity3, entity4
1623 };
1624 Device d = new Device(null,1L, null, null, Arrays.asList(entities), null);
1625 SwitchPort swp1x1 = new SwitchPort(1L, 1);
1626 SwitchPort swp1x2 = new SwitchPort(1L, 2);
1627 SwitchPort swp2x1 = new SwitchPort(2L, 1);
1628 SwitchPort swp10x1 = new SwitchPort(10L, 1);
1629 assertArrayEquals(new Short[] { -1, 1},
1630 d.getSwitchPortVlanIds(swp10x1));
1631 assertArrayEquals(new Short[] { 3, 42},
1632 d.getSwitchPortVlanIds(swp1x1));
1633 assertArrayEquals(new Short[0],
1634 d.getSwitchPortVlanIds(swp1x2));
1635 assertArrayEquals(new Short[0],
1636 d.getSwitchPortVlanIds(swp2x1));
1637 }
1638
1639 @Test
1640 public void testReclassifyDevice() {
1641 MockFlexEntityClassifier flexClassifier =
1642 new MockFlexEntityClassifier();
1643 deviceManager.entityClassifier= flexClassifier;
1644 deviceManager.startUp(null);
1645
1646 ITopologyService mockTopology = createMock(ITopologyService.class);
1647 deviceManager.topology = mockTopology;
1648 expect(mockTopology.isAttachmentPointPort(anyLong(),
1649 anyShort())).
1650 andReturn(true).anyTimes();
1651 expect(mockTopology.getL2DomainId(anyLong())).andReturn(1L).anyTimes();
1652 expect(mockTopology.isConsistent(EasyMock.anyLong(),
1653 EasyMock.anyShort(),
1654 EasyMock.anyLong(),
1655 EasyMock.anyShort()))
1656 .andReturn(false)
1657 .anyTimes();
1658 expect(mockTopology.isBroadcastDomainPort(EasyMock.anyLong(),
1659 EasyMock.anyShort()))
1660 .andReturn(false)
1661 .anyTimes();
1662 replay(mockTopology);
1663
1664 //flexClassifier.createTestEntityClass("Class1");
1665
1666 Entity entity1 = new Entity(1L, (short)1, 1, 1L, 1, new Date());
1667 Entity entity1b = new Entity(1L, (short)2, 1, 1L, 1, new Date());
1668 Entity entity2 = new Entity(2L, (short)1, 2, 2L, 2, new Date());
1669 Entity entity2b = new Entity(2L, (short)2, 2, 2L, 2, new Date());
1670
1671
1672 Device d1 = deviceManager.learnDeviceByEntity(entity1);
1673 Device d2 = deviceManager.learnDeviceByEntity(entity2);
1674 Device d1b = deviceManager.learnDeviceByEntity(entity1b);
1675 Device d2b = deviceManager.learnDeviceByEntity(entity2b);
1676
1677 d1 = deviceManager.getDeviceIteratorForQuery(entity1.getMacAddress(),
1678 entity1.getVlan(), entity1.getIpv4Address(),
1679 entity1.getSwitchDPID(), entity1.getSwitchPort())
1680 .next();
1681 d1b = deviceManager.getDeviceIteratorForQuery(entity1b.getMacAddress(),
1682 entity1b.getVlan(), entity1b.getIpv4Address(),
1683 entity1b.getSwitchDPID(), entity1b.getSwitchPort()).next();
1684
1685 assertEquals(d1, d1b);
1686
1687 d2 = deviceManager.getDeviceIteratorForQuery(entity2.getMacAddress(),
1688 entity2.getVlan(), entity2.getIpv4Address(),
1689 entity2.getSwitchDPID(), entity2.getSwitchPort()).next();
1690 d2b = deviceManager.getDeviceIteratorForQuery(entity2b.getMacAddress(),
1691 entity2b.getVlan(), entity2b.getIpv4Address(),
1692 entity2b.getSwitchDPID(), entity2b.getSwitchPort()).next();
1693 assertEquals(d2, d2b);
1694
1695 IEntityClass eC1 = flexClassifier.createTestEntityClass("C1");
1696 IEntityClass eC2 = flexClassifier.createTestEntityClass("C2");
1697
1698 flexClassifier.addVlanEntities((short)1, eC1);
1699 flexClassifier.addVlanEntities((short)2, eC1);
1700
1701 deviceManager.reclassifyDevice(d1);
1702 deviceManager.reclassifyDevice(d2);
1703
1704 d1 = deviceManager.deviceMap.get(
1705 deviceManager.primaryIndex.findByEntity(entity1));
1706 d1b = deviceManager.deviceMap.get(
1707 deviceManager.primaryIndex.findByEntity(entity1b));
1708
1709 assertEquals(d1, d1b);
1710
1711 d2 = deviceManager.deviceMap.get(
1712 deviceManager.primaryIndex.findByEntity(entity2));
1713 d2b = deviceManager.deviceMap.get(
1714 deviceManager.primaryIndex.findByEntity(entity2b));
1715
1716 assertEquals(d2, d2b);
1717
1718 flexClassifier.addVlanEntities((short)1, eC2);
1719
1720 deviceManager.reclassifyDevice(d1);
1721 deviceManager.reclassifyDevice(d2);
1722 d1 = deviceManager.deviceMap.get(
1723 deviceManager.primaryIndex.findByEntity(entity1));
1724 d1b = deviceManager.deviceMap.get(
1725 deviceManager.primaryIndex.findByEntity(entity1b));
1726 d2 = deviceManager.deviceMap.get(
1727 deviceManager.primaryIndex.findByEntity(entity2));
1728 d2b = deviceManager.deviceMap.get(
1729 deviceManager.primaryIndex.findByEntity(entity2b));
1730
1731 assertNotSame(d1, d1b);
1732
1733 assertNotSame(d2, d2b);
1734
1735 flexClassifier.addVlanEntities((short)1, eC1);
1736 deviceManager.reclassifyDevice(d1);
1737 deviceManager.reclassifyDevice(d2);
1738 ClassState classState = deviceManager.classStateMap.get(eC1.getName());
1739
1740 Long deviceKey1 = null;
1741 Long deviceKey1b = null;
1742 Long deviceKey2 = null;
1743 Long deviceKey2b = null;
1744
1745 deviceKey1 =
1746 classState.classIndex.findByEntity(entity1);
1747 deviceKey1b =
1748 classState.classIndex.findByEntity(entity1b);
1749 deviceKey2 =
1750 classState.classIndex.findByEntity(entity2);
1751 deviceKey2b =
1752 classState.classIndex.findByEntity(entity2b);
1753
1754 assertEquals(deviceKey1, deviceKey1b);
1755
1756 assertEquals(deviceKey2, deviceKey2b);
1757
1758
1759 }
1760}