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