| /** |
| * Copyright 2011, Big Switch Networks, Inc. |
| * Originally created by David Erickson, Stanford University |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may |
| * not use this file except in compliance with the License. You may obtain |
| * a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations |
| * under the License. |
| **/ |
| |
| package net.floodlightcontroller.devicemanager.internal; |
| |
| |
| import static org.easymock.EasyMock.*; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Calendar; |
| import java.util.Collection; |
| import java.util.Date; |
| import java.util.EnumSet; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.concurrent.ConcurrentHashMap; |
| |
| import static org.easymock.EasyMock.expectLastCall; |
| import net.floodlightcontroller.core.IFloodlightProviderService; |
| import net.floodlightcontroller.core.IOFSwitch; |
| import net.floodlightcontroller.core.module.FloodlightModuleContext; |
| import net.floodlightcontroller.core.test.MockFloodlightProvider; |
| import net.floodlightcontroller.core.test.MockThreadPoolService; |
| import net.floodlightcontroller.devicemanager.IDeviceListener; |
| import net.floodlightcontroller.devicemanager.IDevice; |
| import net.floodlightcontroller.devicemanager.IEntityClass; |
| import net.floodlightcontroller.devicemanager.IEntityClassifierService; |
| import net.floodlightcontroller.devicemanager.SwitchPort; |
| import net.floodlightcontroller.devicemanager.IDeviceService; |
| import net.floodlightcontroller.devicemanager.SwitchPort.ErrorStatus; |
| import net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl.ClassState; |
| import net.floodlightcontroller.devicemanager.test.MockEntityClassifier; |
| import net.floodlightcontroller.devicemanager.test.MockEntityClassifierMac; |
| import net.floodlightcontroller.devicemanager.test.MockFlexEntityClassifier; |
| import net.floodlightcontroller.flowcache.FlowReconcileManager; |
| import net.floodlightcontroller.flowcache.IFlowReconcileService; |
| import net.floodlightcontroller.packet.ARP; |
| import net.floodlightcontroller.packet.Ethernet; |
| import net.floodlightcontroller.packet.IPacket; |
| import net.floodlightcontroller.packet.IPv4; |
| import net.floodlightcontroller.restserver.IRestApiService; |
| import net.floodlightcontroller.restserver.RestApiServer; |
| import net.floodlightcontroller.storage.IStorageSourceService; |
| import net.floodlightcontroller.storage.memory.MemoryStorageSource; |
| import net.floodlightcontroller.test.FloodlightTestCase; |
| import net.floodlightcontroller.threadpool.IThreadPoolService; |
| import net.floodlightcontroller.topology.ITopologyService; |
| import static org.junit.Assert.*; |
| |
| import org.easymock.EasyMock; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.openflow.protocol.OFPacketIn; |
| import org.openflow.protocol.OFPhysicalPort; |
| import org.openflow.protocol.OFType; |
| import org.openflow.protocol.OFPacketIn.OFPacketInReason; |
| import org.openflow.util.HexString; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| public class DeviceManagerImplTest extends FloodlightTestCase { |
| |
| protected static Logger logger = |
| LoggerFactory.getLogger(DeviceManagerImplTest.class); |
| |
| protected OFPacketIn packetIn_1, packetIn_2, packetIn_3; |
| protected IPacket testARPReplyPacket_1, testARPReplyPacket_2, |
| testARPReplyPacket_3; |
| protected IPacket testARPReqPacket_1, testARPReqPacket_2; |
| protected byte[] testARPReplyPacket_1_Srld, testARPReplyPacket_2_Srld; |
| private byte[] testARPReplyPacket_3_Serialized; |
| MockFloodlightProvider mockFloodlightProvider; |
| DeviceManagerImpl deviceManager; |
| MemoryStorageSource storageSource; |
| FlowReconcileManager flowReconcileMgr; |
| |
| private IOFSwitch makeSwitchMock(long id) { |
| IOFSwitch mockSwitch = createMock(IOFSwitch.class); |
| expect(mockSwitch.getId()).andReturn(id).anyTimes(); |
| expect(mockSwitch.getStringId()). |
| andReturn(HexString.toHexString(id, 6)).anyTimes(); |
| expect(mockSwitch.getPort(anyShort())). |
| andReturn(new OFPhysicalPort()).anyTimes(); |
| expect(mockSwitch.portEnabled(isA(OFPhysicalPort.class))). |
| andReturn(true).anyTimes(); |
| return mockSwitch; |
| } |
| |
| @Before |
| public void setUp() throws Exception { |
| super.setUp(); |
| |
| FloodlightModuleContext fmc = new FloodlightModuleContext(); |
| RestApiServer restApi = new RestApiServer(); |
| MockThreadPoolService tp = new MockThreadPoolService(); |
| ITopologyService topology = createMock(ITopologyService.class); |
| fmc.addService(IThreadPoolService.class, tp); |
| mockFloodlightProvider = getMockFloodlightProvider(); |
| deviceManager = new DeviceManagerImpl(); |
| flowReconcileMgr = new FlowReconcileManager(); |
| DefaultEntityClassifier entityClassifier = new DefaultEntityClassifier(); |
| fmc.addService(IDeviceService.class, deviceManager); |
| storageSource = new MemoryStorageSource(); |
| fmc.addService(IStorageSourceService.class, storageSource); |
| fmc.addService(IFloodlightProviderService.class, mockFloodlightProvider); |
| fmc.addService(IRestApiService.class, restApi); |
| fmc.addService(IFlowReconcileService.class, flowReconcileMgr); |
| fmc.addService(IEntityClassifierService.class, entityClassifier); |
| fmc.addService(ITopologyService.class, topology); |
| tp.init(fmc); |
| restApi.init(fmc); |
| storageSource.init(fmc); |
| deviceManager.init(fmc); |
| flowReconcileMgr.init(fmc); |
| entityClassifier.init(fmc); |
| storageSource.startUp(fmc); |
| deviceManager.startUp(fmc); |
| flowReconcileMgr.startUp(fmc); |
| tp.startUp(fmc); |
| entityClassifier.startUp(fmc); |
| |
| reset(topology); |
| topology.addListener(deviceManager); |
| expectLastCall().anyTimes(); |
| replay(topology); |
| |
| IOFSwitch mockSwitch1 = makeSwitchMock(1L); |
| IOFSwitch mockSwitch10 = makeSwitchMock(10L); |
| IOFSwitch mockSwitch5 = makeSwitchMock(5L); |
| IOFSwitch mockSwitch50 = makeSwitchMock(50L); |
| Map<Long, IOFSwitch> switches = new HashMap<Long,IOFSwitch>(); |
| switches.put(1L, mockSwitch1); |
| switches.put(10L, mockSwitch10); |
| switches.put(5L, mockSwitch5); |
| switches.put(50L, mockSwitch50); |
| mockFloodlightProvider.setSwitches(switches); |
| |
| replay(mockSwitch1, mockSwitch5, mockSwitch10, mockSwitch50); |
| |
| // Build our test packet |
| this.testARPReplyPacket_1 = new Ethernet() |
| .setSourceMACAddress("00:44:33:22:11:01") |
| .setDestinationMACAddress("00:11:22:33:44:55") |
| .setEtherType(Ethernet.TYPE_ARP) |
| .setVlanID((short)5) |
| .setPayload( |
| new ARP() |
| .setHardwareType(ARP.HW_TYPE_ETHERNET) |
| .setProtocolType(ARP.PROTO_TYPE_IP) |
| .setHardwareAddressLength((byte) 6) |
| .setProtocolAddressLength((byte) 4) |
| .setOpCode(ARP.OP_REPLY) |
| .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01")) |
| .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1")) |
| .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55")) |
| .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2"))); |
| this.testARPReplyPacket_1_Srld = testARPReplyPacket_1.serialize(); |
| |
| // Another test packet with a different source IP |
| this.testARPReplyPacket_2 = new Ethernet() |
| .setSourceMACAddress("00:44:33:22:11:01") |
| .setDestinationMACAddress("00:11:22:33:44:55") |
| .setEtherType(Ethernet.TYPE_ARP) |
| .setPayload( |
| new ARP() |
| .setHardwareType(ARP.HW_TYPE_ETHERNET) |
| .setProtocolType(ARP.PROTO_TYPE_IP) |
| .setHardwareAddressLength((byte) 6) |
| .setProtocolAddressLength((byte) 4) |
| .setOpCode(ARP.OP_REPLY) |
| .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01")) |
| .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1")) |
| .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55")) |
| .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2"))); |
| this.testARPReplyPacket_2_Srld = testARPReplyPacket_2.serialize(); |
| |
| this.testARPReplyPacket_3 = new Ethernet() |
| .setSourceMACAddress("00:44:33:22:11:01") |
| .setDestinationMACAddress("00:11:22:33:44:55") |
| .setEtherType(Ethernet.TYPE_ARP) |
| .setPayload( |
| new ARP() |
| .setHardwareType(ARP.HW_TYPE_ETHERNET) |
| .setProtocolType(ARP.PROTO_TYPE_IP) |
| .setHardwareAddressLength((byte) 6) |
| .setProtocolAddressLength((byte) 4) |
| .setOpCode(ARP.OP_REPLY) |
| .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01")) |
| .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.3")) |
| .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55")) |
| .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2"))); |
| this.testARPReplyPacket_3_Serialized = testARPReplyPacket_3.serialize(); |
| |
| // Build the PacketIn |
| this.packetIn_1 = ((OFPacketIn) mockFloodlightProvider. |
| getOFMessageFactory().getMessage(OFType.PACKET_IN)) |
| .setBufferId(-1) |
| .setInPort((short) 1) |
| .setPacketData(this.testARPReplyPacket_1_Srld) |
| .setReason(OFPacketInReason.NO_MATCH) |
| .setTotalLength((short) this.testARPReplyPacket_1_Srld.length); |
| |
| // Build the PacketIn |
| this.packetIn_2 = ((OFPacketIn) mockFloodlightProvider. |
| getOFMessageFactory().getMessage(OFType.PACKET_IN)) |
| .setBufferId(-1) |
| .setInPort((short) 1) |
| .setPacketData(this.testARPReplyPacket_2_Srld) |
| .setReason(OFPacketInReason.NO_MATCH) |
| .setTotalLength((short) this.testARPReplyPacket_2_Srld.length); |
| |
| // Build the PacketIn |
| this.packetIn_3 = ((OFPacketIn) mockFloodlightProvider. |
| getOFMessageFactory().getMessage(OFType.PACKET_IN)) |
| .setBufferId(-1) |
| .setInPort((short) 1) |
| .setPacketData(this.testARPReplyPacket_3_Serialized) |
| .setReason(OFPacketInReason.NO_MATCH) |
| .setTotalLength((short) this.testARPReplyPacket_3_Serialized.length); |
| } |
| |
| |
| |
| |
| |
| @Test |
| public void testLastSeen() throws Exception { |
| Calendar c = Calendar.getInstance(); |
| Date d1 = c.getTime(); |
| Entity entity1 = new Entity(1L, null, null, null, null, d1); |
| c.add(Calendar.SECOND, 1); |
| Entity entity2 = new Entity(1L, null, 1, null, null, c.getTime()); |
| |
| IDevice d = deviceManager.learnDeviceByEntity(entity2); |
| assertEquals(c.getTime(), d.getLastSeen()); |
| d = deviceManager.learnDeviceByEntity(entity1); |
| assertEquals(c.getTime(), d.getLastSeen()); |
| |
| deviceManager.startUp(null); |
| d = deviceManager.learnDeviceByEntity(entity1); |
| assertEquals(d1, d.getLastSeen()); |
| d = deviceManager.learnDeviceByEntity(entity2); |
| assertEquals(c.getTime(), d.getLastSeen()); |
| } |
| |
| @Test |
| public void testEntityLearning() throws Exception { |
| IDeviceListener mockListener = |
| createStrictMock(IDeviceListener.class); |
| |
| deviceManager.addListener(mockListener); |
| deviceManager.entityClassifier= new MockEntityClassifier(); |
| deviceManager.startUp(null); |
| |
| ITopologyService mockTopology = createMock(ITopologyService.class); |
| expect(mockTopology.getL2DomainId(anyLong())). |
| andReturn(1L).anyTimes(); |
| expect(mockTopology.isBroadcastDomainPort(anyLong(), anyShort())). |
| andReturn(false).anyTimes(); |
| |
| expect(mockTopology.isAttachmentPointPort(anyLong(), |
| anyShort())).andReturn(true).anyTimes(); |
| expect(mockTopology.isConsistent(10L, (short)1, 10L, (short)1)). |
| andReturn(true).anyTimes(); |
| expect(mockTopology.isConsistent(1L, (short)1, 1L, (short)1)). |
| andReturn(true).anyTimes(); |
| expect(mockTopology.isConsistent(50L, (short)3, 50L, (short)3)). |
| andReturn(true).anyTimes(); |
| |
| Date topologyUpdateTime = new Date(); |
| expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime). |
| anyTimes(); |
| |
| deviceManager.topology = mockTopology; |
| |
| Entity entity1 = new Entity(1L, null, null, 1L, 1, new Date()); |
| Entity entity2 = new Entity(1L, null, null, 10L, 1, new Date()); |
| Entity entity3 = new Entity(1L, null, 1, 10L, 1, new Date()); |
| Entity entity4 = new Entity(1L, null, 1, 1L, 1, new Date()); |
| Entity entity5 = new Entity(2L, (short)4, 1, 5L, 2, new Date()); |
| Entity entity6 = new Entity(2L, (short)4, 1, 50L, 3, new Date()); |
| Entity entity7 = new Entity(2L, (short)4, 2, 50L, 3, new Date()); |
| |
| mockListener.deviceAdded(isA(IDevice.class)); |
| replay(mockListener, mockTopology); |
| |
| Device d1 = deviceManager.learnDeviceByEntity(entity1); |
| assertSame(d1, deviceManager.learnDeviceByEntity(entity1)); |
| assertSame(d1, deviceManager.findDeviceByEntity(entity1)); |
| assertEquals(DefaultEntityClassifier.entityClass , |
| d1.entityClass); |
| assertArrayEquals(new Short[] { -1 }, d1.getVlanId()); |
| assertArrayEquals(new Integer[] { }, d1.getIPv4Addresses()); |
| |
| assertEquals(1, deviceManager.getAllDevices().size()); |
| verify(mockListener); |
| |
| reset(mockListener); |
| mockListener.deviceAdded(isA(IDevice.class)); |
| replay(mockListener); |
| |
| Device d2 = deviceManager.learnDeviceByEntity(entity2); |
| assertFalse(d1.equals(d2)); |
| assertNotSame(d1, d2); |
| assertNotSame(d1.getDeviceKey(), d2.getDeviceKey()); |
| assertEquals(MockEntityClassifier.testEC, d2.entityClass); |
| assertArrayEquals(new Short[] { -1 }, d2.getVlanId()); |
| assertArrayEquals(new Integer[] { }, d2.getIPv4Addresses()); |
| |
| assertEquals(2, deviceManager.getAllDevices().size()); |
| verify(mockListener); |
| |
| reset(mockListener); |
| mockListener.deviceIPV4AddrChanged(isA(IDevice.class)); |
| replay(mockListener); |
| |
| Device d3 = deviceManager.learnDeviceByEntity(entity3); |
| assertNotSame(d2, d3); |
| assertEquals(d2.getDeviceKey(), d3.getDeviceKey()); |
| assertEquals(MockEntityClassifier.testEC, d3.entityClass); |
| assertArrayEquals(new Integer[] { 1 }, |
| d3.getIPv4Addresses()); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(10L, 1) }, |
| d3.getAttachmentPoints()); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(10L, 1) }, |
| d3.getAttachmentPoints(true)); |
| assertArrayEquals(new Short[] { -1 }, |
| d3.getVlanId()); |
| |
| assertEquals(2, deviceManager.getAllDevices().size()); |
| verify(mockListener); |
| |
| reset(mockListener); |
| mockListener.deviceIPV4AddrChanged(isA(IDevice.class)); |
| replay(mockListener); |
| |
| Device d4 = deviceManager.learnDeviceByEntity(entity4); |
| assertNotSame(d1, d4); |
| assertEquals(d1.getDeviceKey(), d4.getDeviceKey()); |
| assertEquals(DefaultEntityClassifier.entityClass, d4.entityClass); |
| assertArrayEquals(new Integer[] { 1 }, |
| d4.getIPv4Addresses()); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, |
| d4.getAttachmentPoints()); |
| assertArrayEquals(new Short[] { -1 }, |
| d4.getVlanId()); |
| |
| assertEquals(2, deviceManager.getAllDevices().size()); |
| verify(mockListener); |
| |
| reset(mockListener); |
| mockListener.deviceAdded((isA(IDevice.class))); |
| replay(mockListener); |
| |
| Device d5 = deviceManager.learnDeviceByEntity(entity5); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 2) }, |
| d5.getAttachmentPoints()); |
| assertArrayEquals(new Short[] { (short) 4 }, |
| d5.getVlanId()); |
| assertEquals(2L, d5.getMACAddress()); |
| assertEquals("00:00:00:00:00:02", d5.getMACAddressString()); |
| verify(mockListener); |
| |
| reset(mockListener); |
| mockListener.deviceAdded(isA(IDevice.class)); |
| replay(mockListener); |
| |
| Device d6 = deviceManager.learnDeviceByEntity(entity6); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(50L, 3) }, |
| d6.getAttachmentPoints()); |
| assertArrayEquals(new Short[] { (short) 4 }, |
| d6.getVlanId()); |
| |
| assertEquals(4, deviceManager.getAllDevices().size()); |
| verify(mockListener); |
| |
| reset(mockListener); |
| mockListener.deviceIPV4AddrChanged(isA(IDevice.class)); |
| replay(mockListener); |
| |
| Device d7 = deviceManager.learnDeviceByEntity(entity7); |
| assertNotSame(d6, d7); |
| assertEquals(d6.getDeviceKey(), d7.getDeviceKey()); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(50L, 3) }, |
| d7.getAttachmentPoints()); |
| assertArrayEquals(new Short[] { (short) 4 }, |
| d7.getVlanId()); |
| |
| assertEquals(4, deviceManager.getAllDevices().size()); |
| verify(mockListener); |
| |
| |
| reset(mockListener); |
| replay(mockListener); |
| |
| reset(deviceManager.topology); |
| deviceManager.topology.addListener(deviceManager); |
| expectLastCall().times(1); |
| replay(deviceManager.topology); |
| |
| deviceManager.entityClassifier = new MockEntityClassifierMac(); |
| deviceManager.startUp(null); |
| Entity entityNoClass = new Entity(5L, (short)1, 5, -1L, 1, new Date()); |
| assertEquals(null, deviceManager.learnDeviceByEntity(entityNoClass)); |
| |
| verify(mockListener); |
| } |
| |
| |
| @Test |
| public void testAttachmentPointLearning() throws Exception { |
| IDeviceListener mockListener = |
| createStrictMock(IDeviceListener.class); |
| |
| deviceManager.addListener(mockListener); |
| |
| ITopologyService mockTopology = createMock(ITopologyService.class); |
| expect(mockTopology.getL2DomainId(1L)). |
| andReturn(1L).anyTimes(); |
| expect(mockTopology.getL2DomainId(5L)). |
| andReturn(1L).anyTimes(); |
| expect(mockTopology.getL2DomainId(10L)). |
| andReturn(10L).anyTimes(); |
| expect(mockTopology.getL2DomainId(50L)). |
| andReturn(10L).anyTimes(); |
| expect(mockTopology.isBroadcastDomainPort(anyLong(), anyShort())). |
| andReturn(false).anyTimes(); |
| expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(), |
| anyLong(), anyShort())).andReturn(false).anyTimes(); |
| |
| expect(mockTopology.isAttachmentPointPort(anyLong(), |
| anyShort())).andReturn(true).anyTimes(); |
| expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)1)). |
| andReturn(false).anyTimes(); |
| expect(mockTopology.isConsistent(5L, (short)1, 10L, (short)1)). |
| andReturn(false).anyTimes(); |
| expect(mockTopology.isConsistent(10L, (short)1, 50L, (short)1)). |
| andReturn(false).anyTimes(); |
| |
| Date topologyUpdateTime = new Date(); |
| expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime). |
| anyTimes(); |
| |
| replay(mockTopology); |
| |
| deviceManager.topology = mockTopology; |
| |
| Calendar c = Calendar.getInstance(); |
| Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime()); |
| Entity entity0 = new Entity(1L, null, null, null, null, c.getTime()); |
| c.add(Calendar.SECOND, 1); |
| Entity entity2 = new Entity(1L, null, null, 5L, 1, c.getTime()); |
| c.add(Calendar.SECOND, 1); |
| Entity entity3 = new Entity(1L, null, null, 10L, 1, c.getTime()); |
| c.add(Calendar.SECOND, 1); |
| Entity entity4 = new Entity(1L, null, null, 50L, 1, c.getTime()); |
| |
| IDevice d; |
| SwitchPort[] aps; |
| Integer[] ips; |
| |
| mockListener.deviceAdded(isA(IDevice.class)); |
| replay(mockListener); |
| |
| deviceManager.learnDeviceByEntity(entity1); |
| d = deviceManager.learnDeviceByEntity(entity0); |
| assertEquals(1, deviceManager.getAllDevices().size()); |
| aps = d.getAttachmentPoints(); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, aps); |
| ips = d.getIPv4Addresses(); |
| assertArrayEquals(new Integer[] { 1 }, ips); |
| verify(mockListener); |
| |
| reset(mockListener); |
| mockListener.deviceMoved((isA(IDevice.class))); |
| replay(mockListener); |
| |
| d = deviceManager.learnDeviceByEntity(entity2); |
| assertEquals(1, deviceManager.getAllDevices().size()); |
| aps = d.getAttachmentPoints(); |
| |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1) }, aps); |
| ips = d.getIPv4Addresses(); |
| assertArrayEquals(new Integer[] { 1 }, ips); |
| verify(mockListener); |
| |
| reset(mockListener); |
| mockListener.deviceMoved((isA(IDevice.class))); |
| replay(mockListener); |
| |
| d = deviceManager.learnDeviceByEntity(entity3); |
| assertEquals(1, deviceManager.getAllDevices().size()); |
| aps = d.getAttachmentPoints(); |
| assertArrayEquals(new SwitchPort[] {new SwitchPort(5L, 1), new SwitchPort(10L, 1)}, aps); |
| ips = d.getIPv4Addresses(); |
| assertArrayEquals(new Integer[] { 1 }, ips); |
| verify(mockListener); |
| |
| reset(mockListener); |
| mockListener.deviceMoved((isA(IDevice.class))); |
| replay(mockListener); |
| |
| d = deviceManager.learnDeviceByEntity(entity4); |
| assertEquals(1, deviceManager.getAllDevices().size()); |
| aps = d.getAttachmentPoints(); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1), |
| new SwitchPort(50L, 1) }, aps); |
| ips = d.getIPv4Addresses(); |
| assertArrayEquals(new Integer[] { 1 }, ips); |
| verify(mockListener); |
| } |
| |
| @Test |
| public void testAttachmentPointSuppression() throws Exception { |
| IDeviceListener mockListener = |
| createStrictMock(IDeviceListener.class); |
| |
| deviceManager.addListener(mockListener); |
| |
| ITopologyService mockTopology = createMock(ITopologyService.class); |
| expect(mockTopology.getL2DomainId(1L)). |
| andReturn(1L).anyTimes(); |
| expect(mockTopology.getL2DomainId(5L)). |
| andReturn(1L).anyTimes(); |
| expect(mockTopology.getL2DomainId(10L)). |
| andReturn(10L).anyTimes(); |
| expect(mockTopology.getL2DomainId(50L)). |
| andReturn(10L).anyTimes(); |
| expect(mockTopology.isBroadcastDomainPort(anyLong(), anyShort())). |
| andReturn(false).anyTimes(); |
| expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(), |
| anyLong(), anyShort())).andReturn(false).anyTimes(); |
| |
| expect(mockTopology.isAttachmentPointPort(anyLong(), |
| anyShort())).andReturn(true).anyTimes(); |
| expect(mockTopology.isConsistent(5L, (short)1, 50L, (short)1)). |
| andReturn(false).anyTimes(); |
| |
| Date topologyUpdateTime = new Date(); |
| expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime). |
| anyTimes(); |
| |
| replay(mockTopology); |
| |
| deviceManager.topology = mockTopology; |
| // suppress (1L, 1) and (10L, 1) |
| deviceManager.addSuppressAPs(1L, (short)1); |
| deviceManager.addSuppressAPs(10L, (short)1); |
| |
| Calendar c = Calendar.getInstance(); |
| Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime()); |
| Entity entity0 = new Entity(1L, null, null, null, null, c.getTime()); |
| c.add(Calendar.SECOND, 1); |
| Entity entity2 = new Entity(1L, null, null, 5L, 1, c.getTime()); |
| c.add(Calendar.SECOND, 1); |
| Entity entity3 = new Entity(1L, null, null, 10L, 1, c.getTime()); |
| c.add(Calendar.SECOND, 1); |
| Entity entity4 = new Entity(1L, null, null, 50L, 1, c.getTime()); |
| |
| IDevice d; |
| SwitchPort[] aps; |
| Integer[] ips; |
| |
| mockListener.deviceAdded(isA(IDevice.class)); |
| replay(mockListener); |
| |
| deviceManager.learnDeviceByEntity(entity1); |
| d = deviceManager.learnDeviceByEntity(entity0); |
| assertEquals(1, deviceManager.getAllDevices().size()); |
| aps = d.getAttachmentPoints(); |
| assertEquals(aps.length, 0); |
| ips = d.getIPv4Addresses(); |
| assertArrayEquals(new Integer[] { 1 }, ips); |
| verify(mockListener); |
| |
| reset(mockListener); |
| mockListener.deviceMoved((isA(IDevice.class))); |
| replay(mockListener); |
| |
| d = deviceManager.learnDeviceByEntity(entity2); |
| assertEquals(1, deviceManager.getAllDevices().size()); |
| aps = d.getAttachmentPoints(); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1) }, aps); |
| ips = d.getIPv4Addresses(); |
| assertArrayEquals(new Integer[] { 1 }, ips); |
| verify(mockListener); |
| |
| reset(mockListener); |
| mockListener.deviceMoved((isA(IDevice.class))); |
| replay(mockListener); |
| |
| d = deviceManager.learnDeviceByEntity(entity3); |
| assertEquals(1, deviceManager.getAllDevices().size()); |
| aps = d.getAttachmentPoints(); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1) }, aps); |
| ips = d.getIPv4Addresses(); |
| assertArrayEquals(new Integer[] { 1 }, ips); |
| //verify(mockListener); // There is no device movement here; no not needed. |
| |
| reset(mockListener); |
| mockListener.deviceMoved((isA(IDevice.class))); |
| replay(mockListener); |
| |
| d = deviceManager.learnDeviceByEntity(entity4); |
| assertEquals(1, deviceManager.getAllDevices().size()); |
| aps = d.getAttachmentPoints(); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1), |
| new SwitchPort(50L, 1) }, aps); |
| ips = d.getIPv4Addresses(); |
| assertArrayEquals(new Integer[] { 1 }, ips); |
| verify(mockListener); |
| } |
| |
| @Test |
| public void testBDAttachmentPointLearning() throws Exception { |
| ITopologyService mockTopology = createMock(ITopologyService.class); |
| expect(mockTopology.getL2DomainId(anyLong())). |
| andReturn(1L).anyTimes(); |
| expect(mockTopology.isAttachmentPointPort(anyLong(), anyShort())). |
| andReturn(true).anyTimes(); |
| expect(mockTopology.isBroadcastDomainPort(1L, (short)1)). |
| andReturn(false).anyTimes(); |
| expect(mockTopology.isBroadcastDomainPort(1L, (short)2)). |
| andReturn(true).anyTimes(); |
| expect(mockTopology.isInSameBroadcastDomain(1L, (short)1, |
| 1L, (short)2)).andReturn(true).anyTimes(); |
| expect(mockTopology.isInSameBroadcastDomain(1L, (short)2, |
| 1L, (short)1)).andReturn(true).anyTimes(); |
| expect(mockTopology.isConsistent(anyLong(), anyShort(), anyLong(), anyShort())).andReturn(false).anyTimes(); |
| |
| Date topologyUpdateTime = new Date(); |
| expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime). |
| anyTimes(); |
| |
| replay(mockTopology); |
| |
| deviceManager.topology = mockTopology; |
| |
| Calendar c = Calendar.getInstance(); |
| Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime()); |
| c.add(Calendar.MILLISECOND, |
| (int)AttachmentPoint.OPENFLOW_TO_EXTERNAL_TIMEOUT/ 2); |
| Entity entity2 = new Entity(1L, null, null, 1L, 2, c.getTime()); |
| c.add(Calendar.MILLISECOND, |
| (int)AttachmentPoint.OPENFLOW_TO_EXTERNAL_TIMEOUT / 2 + 1); |
| Entity entity3 = new Entity(1L, null, null, 1L, 2, c.getTime()); |
| |
| IDevice d; |
| SwitchPort[] aps; |
| |
| d = deviceManager.learnDeviceByEntity(entity1); |
| assertEquals(1, deviceManager.getAllDevices().size()); |
| aps = d.getAttachmentPoints(); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, aps); |
| |
| // this timestamp is too soon; don't switch |
| d = deviceManager.learnDeviceByEntity(entity2); |
| assertEquals(1, deviceManager.getAllDevices().size()); |
| aps = d.getAttachmentPoints(); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, aps); |
| |
| // it should switch when we learn with a timestamp after the |
| // timeout |
| d = deviceManager.learnDeviceByEntity(entity3); |
| assertEquals(1, deviceManager.getAllDevices().size()); |
| aps = d.getAttachmentPoints(); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 2) }, aps); |
| } |
| |
| |
| @Test |
| public void testPacketIn() throws Exception { |
| byte[] dataLayerSource = |
| ((Ethernet)this.testARPReplyPacket_1).getSourceMACAddress(); |
| |
| // Mock up our expected behavior |
| ITopologyService mockTopology = createMock(ITopologyService.class); |
| deviceManager.topology = mockTopology; |
| expect(mockTopology.isAttachmentPointPort(EasyMock.anyLong(), |
| EasyMock.anyShort())). |
| andReturn(true).anyTimes(); |
| expect(mockTopology.isConsistent(EasyMock.anyLong(), |
| EasyMock.anyShort(), |
| EasyMock.anyLong(), |
| EasyMock.anyShort())).andReturn(false). |
| anyTimes(); |
| expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes(); |
| replay(mockTopology); |
| |
| Date currentDate = new Date(); |
| |
| // build our expected Device |
| Integer ipaddr = IPv4.toIPv4Address("192.168.1.1"); |
| Device device = |
| new Device(deviceManager, |
| new Long(deviceManager.deviceKeyCounter), |
| new Entity(Ethernet.toLong(dataLayerSource), |
| (short)5, |
| ipaddr, |
| 1L, |
| 1, |
| currentDate), |
| DefaultEntityClassifier.entityClass); |
| |
| |
| |
| |
| // Get the listener and trigger the packet in |
| IOFSwitch switch1 = mockFloodlightProvider.getSwitches().get(1L); |
| mockFloodlightProvider.dispatchMessage(switch1, this.packetIn_1); |
| |
| // Verify the replay matched our expectations |
| // verify(mockTopology); |
| |
| // Verify the device |
| Device rdevice = (Device) |
| deviceManager.findDevice(Ethernet.toLong(dataLayerSource), |
| (short)5, null, null, null); |
| |
| assertEquals(device, rdevice); |
| assertEquals(new Short((short)5), rdevice.getVlanId()[0]); |
| |
| Device result = null; |
| Iterator<? extends IDevice> dstiter = |
| deviceManager.queryClassDevices(device, null, null, ipaddr, |
| null, null); |
| if (dstiter.hasNext()) { |
| result = (Device)dstiter.next(); |
| } |
| |
| assertEquals(device, result); |
| |
| device = |
| new Device(device, |
| new Entity(Ethernet.toLong(dataLayerSource), |
| (short)5, |
| ipaddr, |
| 5L, |
| 2, |
| currentDate)); |
| |
| reset(mockTopology); |
| expect(mockTopology.isAttachmentPointPort(anyLong(), |
| anyShort())). |
| andReturn(true). |
| anyTimes(); |
| expect(mockTopology.isConsistent(EasyMock.anyLong(), |
| EasyMock.anyShort(), |
| EasyMock.anyLong(), |
| EasyMock.anyShort())).andReturn(false). |
| anyTimes(); |
| expect(mockTopology.isBroadcastDomainPort(EasyMock.anyLong(), |
| EasyMock.anyShort())) |
| .andReturn(false) |
| .anyTimes(); |
| expect(mockTopology.getL2DomainId(1L)).andReturn(1L).anyTimes(); |
| expect(mockTopology.getL2DomainId(5L)).andReturn(1L).anyTimes(); |
| expect(mockTopology.isInSameBroadcastDomain(1L, (short)1, 5L, (short)2)). |
| andReturn(false).anyTimes(); |
| |
| // Start recording the replay on the mocks |
| replay(mockTopology); |
| // Get the listener and trigger the packet in |
| IOFSwitch switch5 = mockFloodlightProvider.getSwitches().get(5L); |
| mockFloodlightProvider. |
| dispatchMessage(switch5, this.packetIn_1.setInPort((short)2)); |
| |
| // Verify the replay matched our expectations |
| verify(mockTopology); |
| |
| // Verify the device |
| rdevice = (Device) |
| deviceManager.findDevice(Ethernet.toLong(dataLayerSource), |
| (short)5, null, null, null); |
| assertEquals(device, rdevice); |
| } |
| |
| |
| /** |
| * Note: Entity expiration does not result in device moved notification. |
| * @throws Exception |
| */ |
| public void doTestEntityExpiration() throws Exception { |
| IDeviceListener mockListener = |
| createStrictMock(IDeviceListener.class); |
| mockListener.deviceIPV4AddrChanged(isA(IDevice.class)); |
| |
| ITopologyService mockTopology = createMock(ITopologyService.class); |
| expect(mockTopology.isAttachmentPointPort(anyLong(), |
| anyShort())). |
| andReturn(true).anyTimes(); |
| |
| expect(mockTopology.isBroadcastDomainPort(1L, (short)1)).andReturn(false).anyTimes(); |
| expect(mockTopology.isBroadcastDomainPort(5L, (short)1)).andReturn(false).anyTimes(); |
| expect(mockTopology.getL2DomainId(1L)).andReturn(1L).anyTimes(); |
| expect(mockTopology.getL2DomainId(5L)).andReturn(5L).anyTimes(); |
| expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)1)). |
| andReturn(false).anyTimes(); |
| |
| Date topologyUpdateTime = new Date(); |
| expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime). |
| anyTimes(); |
| |
| replay(mockTopology); |
| deviceManager.topology = mockTopology; |
| |
| Calendar c = Calendar.getInstance(); |
| Entity entity1 = new Entity(1L, null, 2, 1L, 1, c.getTime()); |
| c.add(Calendar.MILLISECOND, -DeviceManagerImpl.ENTITY_TIMEOUT-1); |
| Entity entity2 = new Entity(1L, null, 1, 5L, 1, c.getTime()); |
| |
| deviceManager.learnDeviceByEntity(entity1); |
| IDevice d = deviceManager.learnDeviceByEntity(entity2); |
| assertArrayEquals(new Integer[] { 1, 2 }, d.getIPv4Addresses()); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1), |
| new SwitchPort(5L, 1)}, |
| d.getAttachmentPoints()); |
| Iterator<? extends IDevice> diter = |
| deviceManager.queryClassDevices(d, null, null, 1, null, null); |
| assertTrue(diter.hasNext()); |
| assertEquals(d.getDeviceKey(), diter.next().getDeviceKey()); |
| diter = deviceManager.queryClassDevices(d, null, null, 2, null, null); |
| assertTrue(diter.hasNext()); |
| assertEquals(d.getDeviceKey(), diter.next().getDeviceKey()); |
| |
| |
| deviceManager.addListener(mockListener); |
| replay(mockListener); |
| deviceManager.entityCleanupTask.reschedule(0, null); |
| |
| d = deviceManager.getDevice(d.getDeviceKey()); |
| assertArrayEquals(new Integer[] { 2 }, d.getIPv4Addresses()); |
| |
| // Attachment points are not removed, previous ones are still valid. |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1), |
| new SwitchPort(5L, 1) }, |
| d.getAttachmentPoints()); |
| diter = deviceManager.queryClassDevices(d, null, null, 2, null, null); |
| assertTrue(diter.hasNext()); |
| assertEquals(d.getDeviceKey(), diter.next().getDeviceKey()); |
| diter = deviceManager.queryClassDevices(d, null, null, 1, null, null); |
| assertFalse(diter.hasNext()); |
| |
| d = deviceManager.findDevice(1L, null, null, null, null); |
| assertArrayEquals(new Integer[] { 2 }, d.getIPv4Addresses()); |
| |
| // Attachment points are not removed, previous ones are still valid. |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1), |
| new SwitchPort(5L, 1) }, |
| d.getAttachmentPoints()); |
| |
| verify(mockListener); |
| } |
| |
| public void doTestDeviceExpiration() throws Exception { |
| IDeviceListener mockListener = |
| createStrictMock(IDeviceListener.class); |
| mockListener.deviceRemoved(isA(IDevice.class)); |
| |
| Calendar c = Calendar.getInstance(); |
| c.add(Calendar.MILLISECOND, -DeviceManagerImpl.ENTITY_TIMEOUT-1); |
| Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime()); |
| Entity entity2 = new Entity(1L, null, 2, 5L, 1, c.getTime()); |
| |
| ITopologyService mockTopology = createMock(ITopologyService.class); |
| deviceManager.topology = mockTopology; |
| |
| expect(mockTopology.isAttachmentPointPort(EasyMock.anyLong(), |
| EasyMock.anyShort())). |
| andReturn(true). |
| anyTimes(); |
| expect(mockTopology.getL2DomainId(1L)).andReturn(1L).anyTimes(); |
| expect(mockTopology.getL2DomainId(5L)).andReturn(1L).anyTimes(); |
| expect(mockTopology.isConsistent(EasyMock.anyLong(), |
| EasyMock.anyShort(), |
| EasyMock.anyLong(), |
| EasyMock.anyShort())).andReturn(false). |
| anyTimes(); |
| expect(mockTopology.isBroadcastDomainPort(EasyMock.anyLong(), |
| EasyMock.anyShort())). |
| andReturn(false).anyTimes(); |
| replay(mockTopology); |
| |
| IDevice d = deviceManager.learnDeviceByEntity(entity2); |
| d = deviceManager.learnDeviceByEntity(entity1); |
| assertArrayEquals(new Integer[] { 1, 2 }, d.getIPv4Addresses()); |
| |
| deviceManager.addListener(mockListener); |
| replay(mockListener); |
| deviceManager.entityCleanupTask.reschedule(0, null); |
| |
| IDevice r = deviceManager.getDevice(d.getDeviceKey()); |
| assertNull(r); |
| Iterator<? extends IDevice> diter = |
| deviceManager.queryClassDevices(d, null, null, 1, null, null); |
| assertFalse(diter.hasNext()); |
| |
| r = deviceManager.findDevice(1L, null, null, null, null); |
| assertNull(r); |
| |
| verify(mockListener); |
| } |
| |
| /* |
| * A ConcurrentHashMap for devices (deviceMap) that can be used to test |
| * code that specially handles concurrent modification situations. In |
| * particular, we overwrite values() and will replace / remove all the |
| * elements returned by values. |
| * |
| * The remove flag in the constructor specifies if devices returned by |
| * values() should be removed or replaced. |
| */ |
| protected static class ConcurrentlyModifiedDeviceMap |
| extends ConcurrentHashMap<Long, Device> { |
| private static final long serialVersionUID = 7784938535441180562L; |
| protected boolean remove; |
| public ConcurrentlyModifiedDeviceMap(boolean remove) { |
| super(); |
| this.remove = remove; |
| } |
| |
| @Override |
| public Collection<Device> values() { |
| // Get the values from the real map and copy them since |
| // the collection returned by values can reflect changed |
| Collection<Device> devs = new ArrayList<Device>(super.values()); |
| for (Device d: devs) { |
| if (remove) { |
| // We remove the device from the underlying map |
| super.remove(d.getDeviceKey()); |
| } else { |
| super.remove(d.getDeviceKey()); |
| // We add a different Device instance with the same |
| // key to the map. We'll do some hackery so the device |
| // is different enough to compare differently in equals |
| // but otherwise looks the same. |
| // It's ugly but it works. |
| Entity[] curEntities = new Entity[d.getEntities().length]; |
| int i = 0; |
| // clone entities |
| for (Entity e: d.getEntities()) { |
| curEntities[i] = new Entity (e.macAddress, |
| e.vlan, |
| e.ipv4Address, |
| e.switchDPID, |
| e.switchPort, |
| e.lastSeenTimestamp); |
| if (e.vlan == null) |
| curEntities[i].vlan = (short)1; |
| else |
| curEntities[i].vlan = (short)((e.vlan + 1 % 4095)+1); |
| i++; |
| } |
| Device newDevice = new Device(d, curEntities[0]); |
| newDevice.entities = curEntities; |
| assertEquals(false, newDevice.equals(d)); |
| super.put(newDevice.getDeviceKey(), newDevice); |
| } |
| } |
| return devs; |
| } |
| } |
| |
| @Test |
| public void testEntityExpiration() throws Exception { |
| doTestEntityExpiration(); |
| } |
| |
| @Test |
| public void testDeviceExpiration() throws Exception { |
| doTestDeviceExpiration(); |
| } |
| |
| /* Test correct entity cleanup behavior when a concurrent modification |
| * occurs. |
| */ |
| @Test |
| public void testEntityExpirationConcurrentModification() throws Exception { |
| deviceManager.deviceMap = new ConcurrentlyModifiedDeviceMap(false); |
| doTestEntityExpiration(); |
| } |
| |
| /* Test correct entity cleanup behavior when a concurrent remove |
| * occurs. |
| */ |
| @Test |
| public void testDeviceExpirationConcurrentRemove() throws Exception { |
| deviceManager.deviceMap = new ConcurrentlyModifiedDeviceMap(true); |
| doTestDeviceExpiration(); |
| } |
| |
| /* Test correct entity cleanup behavior when a concurrent modification |
| * occurs. |
| */ |
| @Test |
| public void testDeviceExpirationConcurrentModification() throws Exception { |
| deviceManager.deviceMap = new ConcurrentlyModifiedDeviceMap(false); |
| doTestDeviceExpiration(); |
| } |
| |
| |
| @Test |
| public void testAttachmentPointFlapping() throws Exception { |
| Calendar c = Calendar.getInstance(); |
| |
| ITopologyService mockTopology = createMock(ITopologyService.class); |
| expect(mockTopology.isAttachmentPointPort(anyLong(), |
| anyShort())).andReturn(true).anyTimes(); |
| expect(mockTopology.isBroadcastDomainPort(anyLong(), |
| anyShort())). |
| andReturn(false).anyTimes(); |
| expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(), |
| anyLong(), anyShort())).andReturn(false).anyTimes(); |
| expect(mockTopology.getL2DomainId(anyLong())). |
| andReturn(1L).anyTimes(); |
| expect(mockTopology.isConsistent(1L, (short)1, 1L, (short)1)). |
| andReturn(true).anyTimes(); |
| expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)1)). |
| andReturn(false).anyTimes(); |
| expect(mockTopology.isConsistent(1L, (short)1, 10L, (short)1)). |
| andReturn(false).anyTimes(); |
| expect(mockTopology.isConsistent(5L, (short)1, 10L, (short)1)). |
| andReturn(false).anyTimes(); |
| expect(mockTopology.isConsistent(10L, (short)1, 1L, (short)1)). |
| andReturn(false).anyTimes(); |
| expect(mockTopology.isConsistent(5L, (short)1, 1L, (short)1)). |
| andReturn(false).anyTimes(); |
| expect(mockTopology.isConsistent(10L, (short)1, 5L, (short)1)). |
| andReturn(false).anyTimes(); |
| |
| Date topologyUpdateTime = new Date(); |
| expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime). |
| anyTimes(); |
| |
| |
| replay(mockTopology); |
| deviceManager.topology = mockTopology; |
| |
| Entity entity1 = new Entity(1L, null, null, 1L, 1, c.getTime()); |
| Entity entity1a = new Entity(1L, null, 1, 1L, 1, c.getTime()); |
| Entity entity2 = new Entity(1L, null, null, 5L, 1, c.getTime()); |
| Entity entity3 = new Entity(1L, null, null, 10L, 1, c.getTime()); |
| entity1.setLastSeenTimestamp(c.getTime()); |
| c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT/2); |
| entity1a.setLastSeenTimestamp(c.getTime()); |
| c.add(Calendar.MILLISECOND, 1); |
| entity2.setLastSeenTimestamp(c.getTime()); |
| c.add(Calendar.MILLISECOND, 1); |
| entity3.setLastSeenTimestamp(c.getTime()); |
| |
| |
| |
| IDevice d; |
| d = deviceManager.learnDeviceByEntity(entity1); |
| d = deviceManager.learnDeviceByEntity(entity1a); |
| d = deviceManager.learnDeviceByEntity(entity2); |
| d = deviceManager.learnDeviceByEntity(entity3); |
| |
| // all entities are active, so entity3 should win |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(10L, 1) }, |
| d.getAttachmentPoints()); |
| |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(10L, 1),}, |
| d.getAttachmentPoints(true)); |
| |
| c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT/4); |
| entity1.setLastSeenTimestamp(c.getTime()); |
| d = deviceManager.learnDeviceByEntity(entity1); |
| |
| // all are still active; entity3 should still win |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, |
| d.getAttachmentPoints()); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1), |
| new SwitchPort(5L, 1, |
| ErrorStatus.DUPLICATE_DEVICE), |
| new SwitchPort(10L, 1, |
| ErrorStatus.DUPLICATE_DEVICE) }, |
| d.getAttachmentPoints(true)); |
| |
| c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT+2000); |
| entity1.setLastSeenTimestamp(c.getTime()); |
| d = deviceManager.learnDeviceByEntity(entity1); |
| |
| assertEquals(entity1.getActiveSince(), entity1.getLastSeenTimestamp()); |
| // entity1 should now be the only active entity |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, |
| d.getAttachmentPoints()); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, |
| d.getAttachmentPoints(true)); |
| } |
| |
| |
| @Test |
| public void testAttachmentPointFlappingTwoCluster() throws Exception { |
| Calendar c = Calendar.getInstance(); |
| |
| ITopologyService mockTopology = createMock(ITopologyService.class); |
| expect(mockTopology.isAttachmentPointPort(anyLong(), |
| anyShort())).andReturn(true).anyTimes(); |
| expect(mockTopology.isBroadcastDomainPort(anyLong(), |
| anyShort())). |
| andReturn(false).anyTimes(); |
| expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(), |
| anyLong(), anyShort())).andReturn(false).anyTimes(); |
| expect(mockTopology.getL2DomainId(1L)). |
| andReturn(1L).anyTimes(); |
| expect(mockTopology.getL2DomainId(5L)). |
| andReturn(5L).anyTimes(); |
| expect(mockTopology.isConsistent(1L, (short)1, 1L, (short)2)). |
| andReturn(false).anyTimes(); |
| expect(mockTopology.isConsistent(1L, (short)2, 5L, (short)1)). |
| andReturn(false).anyTimes(); |
| expect(mockTopology.isConsistent(5L, (short)1, 5L, (short)2)). |
| andReturn(false).anyTimes(); |
| expect(mockTopology.isConsistent(1L, (short)2, 1L, (short)1)). |
| andReturn(false).anyTimes(); |
| expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)1)). |
| andReturn(false).anyTimes(); |
| expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)2)). |
| andReturn(false).anyTimes(); |
| expect(mockTopology.isConsistent(5L, (short)2, 5L, (short)1)). |
| andReturn(false).anyTimes(); |
| |
| Date topologyUpdateTime = new Date(); |
| expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime). |
| anyTimes(); |
| |
| replay(mockTopology); |
| deviceManager.topology = mockTopology; |
| |
| Entity entity1 = new Entity(1L, null, null, 1L, 1, c.getTime()); |
| Entity entity2 = new Entity(1L, null, null, 1L, 2, c.getTime()); |
| Entity entity3 = new Entity(1L, null, null, 5L, 1, c.getTime()); |
| Entity entity4 = new Entity(1L, null, null, 5L, 2, c.getTime()); |
| entity1.setLastSeenTimestamp(c.getTime()); |
| c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT/2); |
| c.add(Calendar.MILLISECOND, 1); |
| entity2.setLastSeenTimestamp(c.getTime()); |
| c.add(Calendar.MILLISECOND, 1); |
| entity3.setLastSeenTimestamp(c.getTime()); |
| c.add(Calendar.MILLISECOND, 1); |
| entity4.setLastSeenTimestamp(c.getTime()); |
| |
| deviceManager.learnDeviceByEntity(entity1); |
| deviceManager.learnDeviceByEntity(entity2); |
| deviceManager.learnDeviceByEntity(entity3); |
| IDevice d = deviceManager.learnDeviceByEntity(entity4); |
| |
| // all entities are active, so entities 2,4 should win |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 2), |
| new SwitchPort(5L, 2) }, |
| d.getAttachmentPoints()); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 2), |
| new SwitchPort(5L, 2)}, |
| d.getAttachmentPoints(true)); |
| |
| c.add(Calendar.MILLISECOND, 1); |
| entity1.setLastSeenTimestamp(c.getTime()); |
| d = deviceManager.learnDeviceByEntity(entity1); |
| |
| // all entities are active, so entities 2,4 should win |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1), |
| new SwitchPort(5L, 2) }, |
| d.getAttachmentPoints()); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1), |
| new SwitchPort(5L, 2), |
| new SwitchPort(1L, 2, ErrorStatus.DUPLICATE_DEVICE)}, |
| d.getAttachmentPoints(true)); |
| |
| c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT+1); |
| entity1.setLastSeenTimestamp(c.getTime()); |
| d = deviceManager.learnDeviceByEntity(entity1); |
| |
| // entities 3,4 are still in conflict, but 1 should be resolved |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1), |
| new SwitchPort(5L, 2) }, |
| d.getAttachmentPoints()); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1), |
| new SwitchPort(5L, 2)}, |
| d.getAttachmentPoints(true)); |
| |
| entity3.setLastSeenTimestamp(c.getTime()); |
| d = deviceManager.learnDeviceByEntity(entity3); |
| |
| // no conflicts, 1 and 3 will win |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1), |
| new SwitchPort(5L, 1) }, |
| d.getAttachmentPoints()); |
| assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1), |
| new SwitchPort(5L, 1) }, |
| d.getAttachmentPoints(true)); |
| |
| } |
| |
| protected void doTestDeviceQuery() throws Exception { |
| Entity entity1 = new Entity(1L, (short)1, 1, 1L, 1, new Date()); |
| Entity entity2 = new Entity(2L, (short)2, 2, 1L, 2, new Date()); |
| Entity entity3 = new Entity(3L, (short)3, 3, 5L, 1, new Date()); |
| Entity entity4 = new Entity(4L, (short)4, 3, 5L, 2, new Date()); |
| Entity entity5 = new Entity(1L, (short)4, 3, 5L, 2, new Date()); |
| |
| deviceManager.learnDeviceByEntity(entity1); |
| deviceManager.learnDeviceByEntity(entity2); |
| deviceManager.learnDeviceByEntity(entity3); |
| deviceManager.learnDeviceByEntity(entity4); |
| |
| Iterator<? extends IDevice> iter = |
| deviceManager.queryDevices(null, (short)1, 1, null, null); |
| int count = 0; |
| while (iter.hasNext()) { |
| count += 1; |
| iter.next(); |
| } |
| assertEquals(1, count); |
| |
| iter = deviceManager.queryDevices(null, (short)3, 3, null, null); |
| count = 0; |
| while (iter.hasNext()) { |
| count += 1; |
| iter.next(); |
| } |
| assertEquals(1, count); |
| |
| iter = deviceManager.queryDevices(null, (short)1, 3, null, null); |
| count = 0; |
| while (iter.hasNext()) { |
| count += 1; |
| iter.next(); |
| } |
| assertEquals(0, count); |
| |
| deviceManager.learnDeviceByEntity(entity5); |
| iter = deviceManager.queryDevices(null, (short)4, 3, null, null); |
| count = 0; |
| while (iter.hasNext()) { |
| count += 1; |
| iter.next(); |
| } |
| assertEquals(2, count); |
| } |
| |
| @Test |
| public void testDeviceIndex() throws Exception { |
| EnumSet<IDeviceService.DeviceField> indexFields = |
| EnumSet.noneOf(IDeviceService.DeviceField.class); |
| indexFields.add(IDeviceService.DeviceField.IPV4); |
| indexFields.add(IDeviceService.DeviceField.VLAN); |
| deviceManager.addIndex(false, indexFields); |
| |
| ITopologyService mockTopology = createMock(ITopologyService.class); |
| deviceManager.topology = mockTopology; |
| expect(mockTopology.isAttachmentPointPort(anyLong(), |
| anyShort())). |
| andReturn(true).anyTimes(); |
| expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes(); |
| replay(mockTopology); |
| doTestDeviceQuery(); |
| } |
| |
| @Test |
| public void testDeviceQuery() throws Exception { |
| ITopologyService mockTopology = createMock(ITopologyService.class); |
| deviceManager.topology = mockTopology; |
| expect(mockTopology.isAttachmentPointPort(anyLong(), |
| anyShort())). |
| andReturn(true).anyTimes(); |
| expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes(); |
| replay(mockTopology); |
| |
| doTestDeviceQuery(); |
| } |
| |
| protected void doTestDeviceClassQuery() throws Exception { |
| Entity entity1 = new Entity(1L, (short)1, 1, 1L, 1, new Date()); |
| Entity entity2 = new Entity(2L, (short)2, 2, 1L, 2, new Date()); |
| Entity entity3 = new Entity(3L, (short)3, 3, 5L, 1, new Date()); |
| Entity entity4 = new Entity(4L, (short)4, 3, 5L, 2, new Date()); |
| Entity entity5 = new Entity(1L, (short)4, 3, 5L, 2, new Date()); |
| |
| IDevice d = deviceManager.learnDeviceByEntity(entity1); |
| deviceManager.learnDeviceByEntity(entity2); |
| deviceManager.learnDeviceByEntity(entity3); |
| deviceManager.learnDeviceByEntity(entity4); |
| |
| Iterator<? extends IDevice> iter = |
| deviceManager.queryClassDevices(d, null, |
| (short)1, 1, null, null); |
| int count = 0; |
| while (iter.hasNext()) { |
| count += 1; |
| iter.next(); |
| } |
| assertEquals(1, count); |
| |
| iter = deviceManager.queryClassDevices(d, null, |
| (short)3, 3, null, null); |
| count = 0; |
| while (iter.hasNext()) { |
| count += 1; |
| iter.next(); |
| } |
| assertEquals(1, count); |
| |
| iter = deviceManager.queryClassDevices(d, null, |
| (short)1, 3, null, null); |
| count = 0; |
| while (iter.hasNext()) { |
| count += 1; |
| iter.next(); |
| } |
| assertEquals(0, count); |
| |
| deviceManager.learnDeviceByEntity(entity5); |
| iter = deviceManager.queryClassDevices(d, null, |
| (short)4, 3, null, null); |
| count = 0; |
| while (iter.hasNext()) { |
| count += 1; |
| iter.next(); |
| } |
| assertEquals(2, count); |
| } |
| |
| @Test |
| public void testDeviceClassIndex() throws Exception { |
| EnumSet<IDeviceService.DeviceField> indexFields = |
| EnumSet.noneOf(IDeviceService.DeviceField.class); |
| indexFields.add(IDeviceService.DeviceField.IPV4); |
| indexFields.add(IDeviceService.DeviceField.VLAN); |
| deviceManager.addIndex(true, indexFields); |
| |
| ITopologyService mockTopology = createMock(ITopologyService.class); |
| deviceManager.topology = mockTopology; |
| expect(mockTopology.isAttachmentPointPort(anyLong(), |
| anyShort())). |
| andReturn(true).anyTimes(); |
| expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes(); |
| replay(mockTopology); |
| |
| doTestDeviceClassQuery(); |
| } |
| |
| @Test |
| public void testDeviceClassQuery() throws Exception { |
| ITopologyService mockTopology = createMock(ITopologyService.class); |
| deviceManager.topology = mockTopology; |
| expect(mockTopology.isAttachmentPointPort(anyLong(), |
| anyShort())). |
| andReturn(true).anyTimes(); |
| expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes(); |
| replay(mockTopology); |
| |
| doTestDeviceClassQuery(); |
| } |
| |
| @Test |
| public void testFindDevice() { |
| boolean exceptionCaught; |
| deviceManager.entityClassifier= new MockEntityClassifierMac(); |
| deviceManager.startUp(null); |
| |
| ITopologyService mockTopology = createMock(ITopologyService.class); |
| deviceManager.topology = mockTopology; |
| expect(mockTopology.isAttachmentPointPort(anyLong(), |
| anyShort())). |
| andReturn(true).anyTimes(); |
| expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes(); |
| replay(mockTopology); |
| |
| Entity entity1 = new Entity(1L, (short)1, 1, 1L, 1, new Date()); |
| Entity entity2 = new Entity(2L, (short)2, 2, 1L, 2, new Date()); |
| Entity entity2b = new Entity(22L, (short)2, 2, 1L, 2, new Date()); |
| |
| Entity entity3 = new Entity(3L, (short)1, 3, 2L, 1, new Date()); |
| Entity entity4 = new Entity(4L, (short)2, 4, 2L, 2, new Date()); |
| |
| Entity entity5 = new Entity(5L, (short)1, 5, 3L, 1, new Date()); |
| |
| |
| IDevice d1 = deviceManager.learnDeviceByEntity(entity1); |
| IDevice d2 = deviceManager.learnDeviceByEntity(entity2); |
| IDevice d3 = deviceManager.learnDeviceByEntity(entity3); |
| IDevice d4 = deviceManager.learnDeviceByEntity(entity4); |
| IDevice d5 = deviceManager.learnDeviceByEntity(entity5); |
| |
| // Make sure the entity classifier worked as expected |
| assertEquals(MockEntityClassifierMac.testECMac1, d1.getEntityClass()); |
| assertEquals(MockEntityClassifierMac.testECMac1, d2.getEntityClass()); |
| assertEquals(MockEntityClassifierMac.testECMac2, d3.getEntityClass()); |
| assertEquals(MockEntityClassifierMac.testECMac2, d4.getEntityClass()); |
| assertEquals(DefaultEntityClassifier.entityClass, |
| d5.getEntityClass()); |
| |
| // Look up the device using findDevice() which uses only the primary |
| // index |
| assertEquals(d1, deviceManager.findDevice(entity1.getMacAddress(), |
| entity1.getVlan(), |
| entity1.getIpv4Address(), |
| entity1.getSwitchDPID(), |
| entity1.getSwitchPort())); |
| // port changed. Device will be found through class index |
| assertEquals(d1, deviceManager.findDevice(entity1.getMacAddress(), |
| entity1.getVlan(), |
| entity1.getIpv4Address(), |
| entity1.getSwitchDPID(), |
| entity1.getSwitchPort()+1)); |
| // VLAN changed. No device matches |
| assertEquals(null, deviceManager.findDevice(entity1.getMacAddress(), |
| (short)42, |
| entity1.getIpv4Address(), |
| entity1.getSwitchDPID(), |
| entity1.getSwitchPort())); |
| assertEquals(null, deviceManager.findDevice(entity1.getMacAddress(), |
| null, |
| entity1.getIpv4Address(), |
| entity1.getSwitchDPID(), |
| entity1.getSwitchPort())); |
| assertEquals(d2, deviceManager.findDeviceByEntity(entity2)); |
| assertEquals(null, deviceManager.findDeviceByEntity(entity2b)); |
| assertEquals(d3, deviceManager.findDevice(entity3.getMacAddress(), |
| entity3.getVlan(), |
| entity3.getIpv4Address(), |
| entity3.getSwitchDPID(), |
| entity3.getSwitchPort())); |
| // switch and port not set. throws exception |
| exceptionCaught = false; |
| try { |
| assertEquals(null, deviceManager.findDevice(entity3.getMacAddress(), |
| entity3.getVlan(), |
| entity3.getIpv4Address(), |
| null, |
| null)); |
| } |
| catch (IllegalArgumentException e) { |
| exceptionCaught = true; |
| } |
| if (!exceptionCaught) |
| fail("findDevice() did not throw IllegalArgumentException"); |
| assertEquals(d4, deviceManager.findDeviceByEntity(entity4)); |
| assertEquals(d5, deviceManager.findDevice(entity5.getMacAddress(), |
| entity5.getVlan(), |
| entity5.getIpv4Address(), |
| entity5.getSwitchDPID(), |
| entity5.getSwitchPort())); |
| // switch and port not set. throws exception (swith/port are key |
| // fields of IEntityClassifier but not d5.entityClass |
| exceptionCaught = false; |
| try { |
| assertEquals(d5, deviceManager.findDevice(entity5.getMacAddress(), |
| entity5.getVlan(), |
| entity5.getIpv4Address(), |
| null, |
| null)); |
| } |
| catch (IllegalArgumentException e) { |
| exceptionCaught = true; |
| } |
| if (!exceptionCaught) |
| fail("findDevice() did not throw IllegalArgumentException"); |
| |
| |
| Entity entityNoClass = new Entity(5L, (short)1, 5, -1L, 1, new Date()); |
| assertEquals(null, deviceManager.findDeviceByEntity(entityNoClass)); |
| |
| |
| // Now look up destination devices |
| assertEquals(d1, deviceManager.findDestDevice(d2, |
| entity1.getMacAddress(), |
| entity1.getVlan(), |
| entity1.getIpv4Address())); |
| assertEquals(d1, deviceManager.findDestDevice(d2, |
| entity1.getMacAddress(), |
| entity1.getVlan(), |
| null)); |
| assertEquals(null, deviceManager.findDestDevice(d2, |
| entity1.getMacAddress(), |
| (short) -1, |
| 0)); |
| } |
| |
| @Test |
| public void testGetIPv4Addresses() { |
| // Looks like Date is only 1s granularity |
| |
| ITopologyService mockTopology = createMock(ITopologyService.class); |
| deviceManager.topology = mockTopology; |
| expect(mockTopology.isAttachmentPointPort(anyLong(), |
| anyShort())). |
| andReturn(true).anyTimes(); |
| expect(mockTopology.getL2DomainId(anyLong())).andReturn(1L).anyTimes(); |
| expect(mockTopology.isConsistent(EasyMock.anyLong(), |
| EasyMock.anyShort(), |
| EasyMock.anyLong(), |
| EasyMock.anyShort())) |
| .andReturn(false) |
| .anyTimes(); |
| expect(mockTopology.isBroadcastDomainPort(EasyMock.anyLong(), |
| EasyMock.anyShort())) |
| .andReturn(false) |
| .anyTimes(); |
| expect(mockTopology.isInSameBroadcastDomain(EasyMock.anyLong(), |
| EasyMock.anyShort(), |
| EasyMock.anyLong(), |
| EasyMock.anyShort())). |
| andReturn(false).anyTimes(); |
| replay(mockTopology); |
| |
| Entity e1 = new Entity(1L, (short)1, null, null, null, new Date(2000)); |
| Device d1 = deviceManager.learnDeviceByEntity(e1); |
| assertArrayEquals(new Integer[0], d1.getIPv4Addresses()); |
| |
| |
| Entity e2 = new Entity(2L, (short)2, 2, null, null, new Date(2000)); |
| Device d2 = deviceManager.learnDeviceByEntity(e2); |
| d2 = deviceManager.learnDeviceByEntity(e2); |
| assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses()); |
| // More than one entity |
| Entity e2b = new Entity(2L, (short)2, null, 2L, 2, new Date(3000)); |
| d2 = deviceManager.learnDeviceByEntity(e2b); |
| assertEquals(2, d2.entities.length); |
| assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses()); |
| // and now add an entity with an IP |
| Entity e2c = new Entity(2L, (short)2, 2, 2L, 3, new Date(3000)); |
| d2 = deviceManager.learnDeviceByEntity(e2c); |
| assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses()); |
| assertEquals(3, d2.entities.length); |
| |
| // Other devices with different IPs shouldn't interfere |
| Entity e3 = new Entity(3L, (short)3, 3, null, null, new Date(4000)); |
| Entity e3b = new Entity(3L, (short)3, 3, 3L, 3, new Date(4400)); |
| Device d3 = deviceManager.learnDeviceByEntity(e3); |
| d3 = deviceManager.learnDeviceByEntity(e3b); |
| assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses()); |
| assertArrayEquals(new Integer[] { 3 }, d3.getIPv4Addresses()); |
| |
| // Add another IP to d3 |
| Entity e3c = new Entity(3L, (short)3, 33, 3L, 3, new Date(4400)); |
| d3 = deviceManager.learnDeviceByEntity(e3c); |
| Integer[] ips = d3.getIPv4Addresses(); |
| Arrays.sort(ips); |
| assertArrayEquals(new Integer[] { 3, 33 }, ips); |
| |
| // Add another device that also claims IP2 but is older than e2 |
| Entity e4 = new Entity(4L, (short)4, 2, null, null, new Date(1000)); |
| Entity e4b = new Entity(4L, (short)4, null, 4L, 4, new Date(1000)); |
| Device d4 = deviceManager.learnDeviceByEntity(e4); |
| assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses()); |
| assertArrayEquals(new Integer[0], d4.getIPv4Addresses()); |
| // add another entity to d4 |
| d4 = deviceManager.learnDeviceByEntity(e4b); |
| assertArrayEquals(new Integer[0], d4.getIPv4Addresses()); |
| |
| // Make e4 and e4a newer |
| Entity e4c = new Entity(4L, (short)4, 2, null, null, new Date(5000)); |
| Entity e4d = new Entity(4L, (short)4, null, 4L, 5, new Date(5000)); |
| d4 = deviceManager.learnDeviceByEntity(e4c); |
| d4 = deviceManager.learnDeviceByEntity(e4d); |
| assertArrayEquals(new Integer[0], d2.getIPv4Addresses()); |
| // FIXME: d4 should not return IP4 |
| assertArrayEquals(new Integer[] { 2 }, d4.getIPv4Addresses()); |
| |
| // Add another newer entity to d2 but with different IP |
| Entity e2d = new Entity(2L, (short)2, 22, 4L, 6, new Date(6000)); |
| d2 = deviceManager.learnDeviceByEntity(e2d); |
| assertArrayEquals(new Integer[] { 22 }, d2.getIPv4Addresses()); |
| assertArrayEquals(new Integer[] { 2 }, d4.getIPv4Addresses()); |
| |
| // new IP for d2,d4 but with same timestamp. Both devices get the IP |
| Entity e2e = new Entity(2L, (short)2, 42, 2L, 4, new Date(7000)); |
| d2 = deviceManager.learnDeviceByEntity(e2e); |
| ips= d2.getIPv4Addresses(); |
| Arrays.sort(ips); |
| assertArrayEquals(new Integer[] { 22, 42 }, ips); |
| Entity e4e = new Entity(4L, (short)4, 42, 4L, 7, new Date(7000)); |
| d4 = deviceManager.learnDeviceByEntity(e4e); |
| ips= d4.getIPv4Addresses(); |
| Arrays.sort(ips); |
| assertArrayEquals(new Integer[] { 2, 42 }, ips); |
| |
| // add a couple more IPs |
| Entity e2f = new Entity(2L, (short)2, 4242, 2L, 5, new Date(8000)); |
| d2 = deviceManager.learnDeviceByEntity(e2f); |
| ips= d2.getIPv4Addresses(); |
| Arrays.sort(ips); |
| assertArrayEquals(new Integer[] { 22, 42, 4242 }, ips); |
| Entity e4f = new Entity(4L, (short)4, 4242, 4L, 8, new Date(9000)); |
| d4 = deviceManager.learnDeviceByEntity(e4f); |
| ips= d4.getIPv4Addresses(); |
| Arrays.sort(ips); |
| assertArrayEquals(new Integer[] { 2, 42, 4242 }, ips); |
| } |
| |
| // TODO: this test should really go into a separate class that collects |
| // unit tests for Device |
| @Test |
| public void testGetSwitchPortVlanId() { |
| Entity entity1 = new Entity(1L, (short)1, null, 10L, 1, new Date()); |
| Entity entity2 = new Entity(1L, null, null, 10L, 1, new Date()); |
| Entity entity3 = new Entity(1L, (short)3, null, 1L, 1, new Date()); |
| Entity entity4 = new Entity(1L, (short)42, null, 1L, 1, new Date()); |
| Entity[] entities = new Entity[] { entity1, entity2, |
| entity3, entity4 |
| }; |
| Device d = new Device(null,1L, null, null, Arrays.asList(entities), null); |
| SwitchPort swp1x1 = new SwitchPort(1L, 1); |
| SwitchPort swp1x2 = new SwitchPort(1L, 2); |
| SwitchPort swp2x1 = new SwitchPort(2L, 1); |
| SwitchPort swp10x1 = new SwitchPort(10L, 1); |
| assertArrayEquals(new Short[] { -1, 1}, |
| d.getSwitchPortVlanIds(swp10x1)); |
| assertArrayEquals(new Short[] { 3, 42}, |
| d.getSwitchPortVlanIds(swp1x1)); |
| assertArrayEquals(new Short[0], |
| d.getSwitchPortVlanIds(swp1x2)); |
| assertArrayEquals(new Short[0], |
| d.getSwitchPortVlanIds(swp2x1)); |
| } |
| |
| @Test |
| public void testReclassifyDevice() { |
| MockFlexEntityClassifier flexClassifier = |
| new MockFlexEntityClassifier(); |
| deviceManager.entityClassifier= flexClassifier; |
| deviceManager.startUp(null); |
| |
| ITopologyService mockTopology = createMock(ITopologyService.class); |
| deviceManager.topology = mockTopology; |
| expect(mockTopology.isAttachmentPointPort(anyLong(), |
| anyShort())). |
| andReturn(true).anyTimes(); |
| expect(mockTopology.getL2DomainId(anyLong())).andReturn(1L).anyTimes(); |
| expect(mockTopology.isConsistent(EasyMock.anyLong(), |
| EasyMock.anyShort(), |
| EasyMock.anyLong(), |
| EasyMock.anyShort())) |
| .andReturn(false) |
| .anyTimes(); |
| expect(mockTopology.isBroadcastDomainPort(EasyMock.anyLong(), |
| EasyMock.anyShort())) |
| .andReturn(false) |
| .anyTimes(); |
| replay(mockTopology); |
| |
| //flexClassifier.createTestEntityClass("Class1"); |
| |
| Entity entity1 = new Entity(1L, (short)1, 1, 1L, 1, new Date()); |
| Entity entity1b = new Entity(1L, (short)2, 1, 1L, 1, new Date()); |
| Entity entity2 = new Entity(2L, (short)1, 2, 2L, 2, new Date()); |
| Entity entity2b = new Entity(2L, (short)2, 2, 2L, 2, new Date()); |
| |
| |
| Device d1 = deviceManager.learnDeviceByEntity(entity1); |
| Device d2 = deviceManager.learnDeviceByEntity(entity2); |
| Device d1b = deviceManager.learnDeviceByEntity(entity1b); |
| Device d2b = deviceManager.learnDeviceByEntity(entity2b); |
| |
| d1 = deviceManager.getDeviceIteratorForQuery(entity1.getMacAddress(), |
| entity1.getVlan(), entity1.getIpv4Address(), |
| entity1.getSwitchDPID(), entity1.getSwitchPort()) |
| .next(); |
| d1b = deviceManager.getDeviceIteratorForQuery(entity1b.getMacAddress(), |
| entity1b.getVlan(), entity1b.getIpv4Address(), |
| entity1b.getSwitchDPID(), entity1b.getSwitchPort()).next(); |
| |
| assertEquals(d1, d1b); |
| |
| d2 = deviceManager.getDeviceIteratorForQuery(entity2.getMacAddress(), |
| entity2.getVlan(), entity2.getIpv4Address(), |
| entity2.getSwitchDPID(), entity2.getSwitchPort()).next(); |
| d2b = deviceManager.getDeviceIteratorForQuery(entity2b.getMacAddress(), |
| entity2b.getVlan(), entity2b.getIpv4Address(), |
| entity2b.getSwitchDPID(), entity2b.getSwitchPort()).next(); |
| assertEquals(d2, d2b); |
| |
| IEntityClass eC1 = flexClassifier.createTestEntityClass("C1"); |
| IEntityClass eC2 = flexClassifier.createTestEntityClass("C2"); |
| |
| flexClassifier.addVlanEntities((short)1, eC1); |
| flexClassifier.addVlanEntities((short)2, eC1); |
| |
| deviceManager.reclassifyDevice(d1); |
| deviceManager.reclassifyDevice(d2); |
| |
| d1 = deviceManager.deviceMap.get( |
| deviceManager.primaryIndex.findByEntity(entity1)); |
| d1b = deviceManager.deviceMap.get( |
| deviceManager.primaryIndex.findByEntity(entity1b)); |
| |
| assertEquals(d1, d1b); |
| |
| d2 = deviceManager.deviceMap.get( |
| deviceManager.primaryIndex.findByEntity(entity2)); |
| d2b = deviceManager.deviceMap.get( |
| deviceManager.primaryIndex.findByEntity(entity2b)); |
| |
| assertEquals(d2, d2b); |
| |
| flexClassifier.addVlanEntities((short)1, eC2); |
| |
| deviceManager.reclassifyDevice(d1); |
| deviceManager.reclassifyDevice(d2); |
| d1 = deviceManager.deviceMap.get( |
| deviceManager.primaryIndex.findByEntity(entity1)); |
| d1b = deviceManager.deviceMap.get( |
| deviceManager.primaryIndex.findByEntity(entity1b)); |
| d2 = deviceManager.deviceMap.get( |
| deviceManager.primaryIndex.findByEntity(entity2)); |
| d2b = deviceManager.deviceMap.get( |
| deviceManager.primaryIndex.findByEntity(entity2b)); |
| |
| assertNotSame(d1, d1b); |
| |
| assertNotSame(d2, d2b); |
| |
| flexClassifier.addVlanEntities((short)1, eC1); |
| deviceManager.reclassifyDevice(d1); |
| deviceManager.reclassifyDevice(d2); |
| ClassState classState = deviceManager.classStateMap.get(eC1.getName()); |
| |
| Long deviceKey1 = null; |
| Long deviceKey1b = null; |
| Long deviceKey2 = null; |
| Long deviceKey2b = null; |
| |
| deviceKey1 = |
| classState.classIndex.findByEntity(entity1); |
| deviceKey1b = |
| classState.classIndex.findByEntity(entity1b); |
| deviceKey2 = |
| classState.classIndex.findByEntity(entity2); |
| deviceKey2b = |
| classState.classIndex.findByEntity(entity2b); |
| |
| assertEquals(deviceKey1, deviceKey1b); |
| |
| assertEquals(deviceKey2, deviceKey2b); |
| |
| |
| } |
| } |