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