| /* |
| * Copyright 2015-present Open Networking Foundation |
| * |
| * 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 org.onosproject.provider.lldp.impl; |
| |
| import java.nio.ByteBuffer; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.concurrent.CompletableFuture; |
| |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.onlab.packet.ChassisId; |
| import org.onlab.packet.Ethernet; |
| import org.onlab.packet.MacAddress; |
| import org.onlab.packet.ONOSLLDP; |
| import org.onosproject.cfg.ComponentConfigAdapter; |
| import org.onosproject.cluster.ClusterMetadataServiceAdapter; |
| import org.onosproject.cluster.NodeId; |
| import org.onosproject.cluster.RoleInfo; |
| import org.onosproject.core.ApplicationId; |
| import org.onosproject.core.CoreService; |
| import org.onosproject.core.DefaultApplicationId; |
| import org.onosproject.mastership.MastershipInfo; |
| import org.onosproject.mastership.MastershipListener; |
| import org.onosproject.mastership.MastershipService; |
| import org.onosproject.net.Annotations; |
| import org.onosproject.net.ConnectPoint; |
| import org.onosproject.net.DefaultAnnotations; |
| import org.onosproject.net.DefaultDevice; |
| import org.onosproject.net.DefaultPort; |
| import org.onosproject.net.Device; |
| import org.onosproject.net.DeviceId; |
| import org.onosproject.net.MastershipRole; |
| import org.onosproject.net.Port; |
| import org.onosproject.net.PortNumber; |
| import org.onosproject.net.config.Config; |
| import org.onosproject.net.config.NetworkConfigEvent; |
| import org.onosproject.net.config.NetworkConfigEvent.Type; |
| import org.onosproject.net.config.NetworkConfigListener; |
| import org.onosproject.net.config.NetworkConfigRegistryAdapter; |
| import org.onosproject.net.device.DeviceEvent; |
| import org.onosproject.net.device.DeviceListener; |
| import org.onosproject.net.device.DeviceServiceAdapter; |
| import org.onosproject.net.flow.TrafficTreatment; |
| import org.onosproject.net.link.LinkProviderRegistryAdapter; |
| import org.onosproject.net.link.LinkProviderServiceAdapter; |
| import org.onosproject.net.link.LinkServiceAdapter; |
| import org.onosproject.net.packet.DefaultInboundPacket; |
| import org.onosproject.net.packet.InboundPacket; |
| import org.onosproject.net.packet.OutboundPacket; |
| import org.onosproject.net.packet.PacketContext; |
| import org.onosproject.net.packet.PacketProcessor; |
| import org.onosproject.net.packet.PacketServiceAdapter; |
| import org.onosproject.net.provider.ProviderId; |
| import org.onosproject.provider.lldpcommon.LinkDiscovery; |
| |
| import com.google.common.collect.ArrayListMultimap; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableMap; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.Lists; |
| import com.google.common.util.concurrent.MoreExecutors; |
| |
| import static org.easymock.EasyMock.createMock; |
| import static org.easymock.EasyMock.expect; |
| import static org.easymock.EasyMock.replay; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.onlab.junit.TestTools.assertAfter; |
| import static org.onosproject.provider.lldp.impl.LldpLinkProvider.DEFAULT_RULES; |
| |
| |
| public class LldpLinkProviderTest { |
| |
| private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001"); |
| private static final DeviceId DID2 = DeviceId.deviceId("of:0000000000000002"); |
| private static final DeviceId DID3 = DeviceId.deviceId("of:0000000000000003"); |
| private static final int EVENT_MS = 500; |
| |
| private static Port pd1; |
| private static Port pd2; |
| private static Port pd3; |
| private static Port pd4; |
| |
| private final LldpLinkProvider provider = new LldpLinkProvider(); |
| private final LinkProviderRegistryAdapter linkRegistry = new LinkProviderRegistryAdapter(); |
| private final TestLinkService linkService = new TestLinkService(); |
| private final TestPacketService packetService = new TestPacketService(); |
| private final TestDeviceService deviceService = new TestDeviceService(); |
| private final TestMasterShipService masterService = new TestMasterShipService(); |
| private final TestNetworkConfigRegistry configRegistry = new TestNetworkConfigRegistry(); |
| |
| private CoreService coreService; |
| private LinkProviderServiceAdapter providerService; |
| |
| private PacketProcessor testProcessor; |
| private DeviceListener deviceListener; |
| private NetworkConfigListener configListener; |
| |
| private ApplicationId appId = |
| new DefaultApplicationId(100, "org.onosproject.provider.lldp"); |
| |
| private TestSuppressionConfig cfg; |
| |
| private Set<DeviceId> deviceBlacklist; |
| |
| private Set<ConnectPoint> portBlacklist; |
| |
| @Before |
| public void setUp() { |
| deviceBlacklist = new HashSet<>(); |
| portBlacklist = new HashSet<>(); |
| cfg = new TestSuppressionConfig(); |
| coreService = createMock(CoreService.class); |
| expect(coreService.registerApplication(appId.name())) |
| .andReturn(appId).anyTimes(); |
| replay(coreService); |
| |
| provider.cfgService = new ComponentConfigAdapter(); |
| provider.coreService = coreService; |
| provider.cfgRegistry = configRegistry; |
| |
| provider.deviceService = deviceService; |
| provider.linkService = linkService; |
| provider.packetService = packetService; |
| provider.providerRegistry = linkRegistry; |
| provider.masterService = masterService; |
| provider.clusterMetadataService = new ClusterMetadataServiceAdapter(); |
| |
| provider.activate(null); |
| |
| provider.eventExecutor = MoreExecutors.newDirectExecutorService(); |
| |
| providerService = linkRegistry.registeredProvider(); |
| } |
| |
| @Test |
| public void basics() { |
| assertNotNull("registration expected", providerService); |
| assertEquals("incorrect provider", provider, providerService.provider()); |
| } |
| |
| @Test |
| public void switchAdd() { |
| DeviceEvent de = deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1); |
| deviceListener.event(de); |
| |
| assertFalse("Device not added", provider.discoverers.isEmpty()); |
| } |
| |
| @Test |
| public void switchRemove() { |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1)); |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_REMOVED, DID1)); |
| |
| final LinkDiscovery linkDiscovery = provider.discoverers.get(DID1); |
| if (linkDiscovery != null) { |
| // If LinkDiscovery helper is there after DEVICE_REMOVED, |
| // it should be stopped |
| assertTrue("Discoverer is not stopped", linkDiscovery.isStopped()); |
| } |
| assertTrue("Device is not gone.", vanishedDpid(DID1)); |
| } |
| |
| /** |
| * Checks that links on a reconfigured switch are properly removed. |
| */ |
| @Test |
| public void switchSuppressedByAnnotation() { |
| |
| // add device to stub DeviceService |
| deviceService.putDevice(device(DID3)); |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3)); |
| |
| assertFalse("Device not added", provider.discoverers.isEmpty()); |
| |
| // update device in stub DeviceService with suppression config |
| deviceService.putDevice(device(DID3, DefaultAnnotations.builder() |
| .set(LldpLinkProvider.NO_LLDP, "true") |
| .build())); |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3)); |
| |
| // discovery on device is expected to be gone or stopped |
| LinkDiscovery linkDiscovery = provider.discoverers.get(DID3); |
| if (linkDiscovery != null) { |
| assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped()); |
| } |
| } |
| |
| @Test |
| public void switchSuppressByBlacklist() { |
| // add device in stub DeviceService |
| deviceService.putDevice(device(DID3)); |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3)); |
| |
| // add deviveId to device blacklist |
| deviceBlacklist.add(DID3); |
| configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED, |
| DID3, |
| LinkDiscoveryFromDevice.class)); |
| |
| assertAfter(EVENT_MS, () -> { |
| // discovery helper for device is expected to be gone or stopped |
| LinkDiscovery linkDiscovery = provider.discoverers.get(DID3); |
| if (linkDiscovery != null) { |
| assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped()); |
| } |
| }); |
| } |
| |
| @Test |
| public void portUp() { |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1)); |
| deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true))); |
| |
| assertTrue("Port not added to discoverer", |
| provider.discoverers.get(DID1).containsPort(3L)); |
| } |
| |
| @Test |
| public void portDown() { |
| |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1)); |
| deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 1, false))); |
| |
| assertFalse("Port added to discoverer", |
| provider.discoverers.get(DID1).containsPort(1L)); |
| assertTrue("Port is not gone.", vanishedPort(1L)); |
| } |
| |
| @Test |
| public void portRemoved() { |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1)); |
| deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true))); |
| deviceListener.event(portEvent(DeviceEvent.Type.PORT_REMOVED, DID1, port(DID1, 3, true))); |
| |
| assertTrue("Port is not gone.", vanishedPort(3L)); |
| assertFalse("Port was not removed from discoverer", |
| provider.discoverers.get(DID1).containsPort(3L)); |
| } |
| |
| /** |
| * Checks that discovery on reconfigured switch are properly restarted. |
| */ |
| @Test |
| public void portSuppressedByDeviceAnnotationConfig() { |
| |
| /// When Device is configured with suppression:ON, Port also is same |
| |
| // add device in stub DeviceService with suppression configured |
| deviceService.putDevice(device(DID3, DefaultAnnotations.builder() |
| .set(LldpLinkProvider.NO_LLDP, "true") |
| .build())); |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3)); |
| |
| // non-suppressed port added to suppressed device |
| final long portno3 = 3L; |
| deviceService.putPorts(DID3, port(DID3, portno3, true)); |
| deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, portno3, true))); |
| |
| // discovery on device is expected to be stopped |
| LinkDiscovery linkDiscovery = provider.discoverers.get(DID3); |
| if (linkDiscovery != null) { |
| assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped()); |
| } |
| |
| /// When Device is reconfigured without suppression:OFF, |
| /// Port should be included for discovery |
| |
| // update device in stub DeviceService without suppression configured |
| deviceService.putDevice(device(DID3)); |
| // update the Port in stub DeviceService. (Port has reference to Device) |
| deviceService.putPorts(DID3, port(DID3, portno3, true)); |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3)); |
| |
| // discovery should come back on |
| assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped()); |
| assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID3).containsPort(portno3)); |
| } |
| |
| /** |
| * Checks that discovery on reconfigured switch are properly restarted. |
| */ |
| @Test |
| public void portSuppressedByParentDeviceIdBlacklist() { |
| |
| /// When Device is configured without suppression:OFF, |
| /// Port should be included for discovery |
| |
| // add device in stub DeviceService without suppression configured |
| deviceService.putDevice(device(DID3)); |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3)); |
| |
| // non-suppressed port added to suppressed device |
| final long portno3 = 3L; |
| deviceService.putPorts(DID3, port(DID3, portno3, true)); |
| deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, portno3, true))); |
| |
| // discovery should succeed |
| assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped()); |
| assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID3).containsPort(portno3)); |
| |
| // add suppression rule for "deviceId: "of:0000000000000003"" |
| deviceBlacklist.add(DID3); |
| configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED, |
| DID3, |
| LinkDiscoveryFromDevice.class)); |
| |
| |
| /// When Device is reconfigured with suppression:ON, Port also is same |
| |
| // update device in stub DeviceService with suppression configured |
| deviceService.putDevice(device(DID3)); |
| // update the Port in stub DeviceService. (Port has reference to Device) |
| deviceService.putPorts(DID3, port(DID3, portno3, true)); |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3)); |
| |
| // discovery helper for device is expected to be gone or stopped |
| LinkDiscovery linkDiscovery = provider.discoverers.get(DID3); |
| if (linkDiscovery != null) { |
| assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped()); |
| } |
| } |
| |
| /** |
| * Checks that discovery on reconfigured switch are properly restarted. |
| */ |
| @Test |
| public void portSuppressedByDeviceTypeConfig() { |
| |
| /// When Device is configured without suppression:OFF, |
| /// Port should be included for discovery |
| |
| // add device in stub DeviceService without suppression configured |
| deviceService.putDevice(device(DID1, Device.Type.SWITCH)); |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1)); |
| |
| // non-suppressed port added to suppressed device |
| final long portno3 = 3L; |
| deviceService.putPorts(DID1, port(DID1, portno3, true)); |
| deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, portno3, true))); |
| |
| // add device in stub DeviceService with suppression configured |
| deviceService.putDevice(device(DID2, Device.Type.ROADM)); |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2)); |
| |
| // non-suppressed port added to suppressed device |
| final long portno4 = 4L; |
| deviceService.putPorts(DID2, port(DID2, portno4, true)); |
| deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID2, port(DID2, portno4, true))); |
| |
| // discovery should succeed for this device |
| assertFalse("Discoverer is expected to start", provider.discoverers.get(DID1).isStopped()); |
| assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID1).containsPort(portno3)); |
| |
| // discovery on device is expected to be stopped for this device |
| LinkDiscovery linkDiscovery = provider.discoverers.get(DID2); |
| if (linkDiscovery != null) { |
| assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped()); |
| } |
| } |
| |
| /** |
| * Checks that discovery on reconfigured port are properly restarted. |
| */ |
| @Test |
| public void portSuppressedByPortConfig() { |
| |
| // add device in stub DeviceService without suppression configured |
| deviceService.putDevice(device(DID3)); |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3)); |
| |
| // suppressed port added to non-suppressed device |
| final long portno3 = 3L; |
| final Port port3 = port(DID3, portno3, true, |
| DefaultAnnotations.builder() |
| .set(LldpLinkProvider.NO_LLDP, "true") |
| .build()); |
| deviceService.putPorts(DID3, port3); |
| deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port3)); |
| |
| // discovery helper should be there turned on |
| assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped()); |
| assertFalse("Discoverer should not contain the port there", |
| provider.discoverers.get(DID3).containsPort(portno3)); |
| } |
| |
| @Test |
| public void portSuppressedByPortBlacklist() { |
| |
| // add device in stub DeviceService without suppression configured |
| deviceService.putDevice(device(DID3)); |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3)); |
| |
| final long portno3 = 3L; |
| final Port port3 = port(DID3, portno3, true); |
| |
| final ConnectPoint cpDid3no3 = new ConnectPoint(DID3, PortNumber.portNumber(portno3)); |
| portBlacklist.add(cpDid3no3); |
| |
| // suppressed port added to non-suppressed device |
| deviceService.putPorts(DID3, port3); |
| deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port3)); |
| |
| configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED, |
| cpDid3no3, |
| LinkDiscoveryFromPort.class)); |
| |
| // discovery helper should be there turned on |
| assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped()); |
| // but port is not a discovery target |
| assertFalse("Discoverer should not contain the port there", |
| provider.discoverers.get(DID3).containsPort(portno3)); |
| } |
| |
| @Test |
| public void portUnknown() { |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1)); |
| // Note: DID3 hasn't been added to TestDeviceService, but only port is added |
| deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, 1, false))); |
| |
| |
| assertNull("DeviceId exists", |
| provider.discoverers.get(DID3)); |
| } |
| |
| @Test |
| public void unknownPktCtx() { |
| |
| // Note: DID3 hasn't been added to TestDeviceService |
| PacketContext pktCtx = new TestPacketContext(device(DID3)); |
| |
| testProcessor.process(pktCtx); |
| assertFalse("Context should still be free", pktCtx.isHandled()); |
| } |
| |
| @Test |
| public void knownPktCtx() { |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1)); |
| deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2)); |
| PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2)); |
| |
| |
| testProcessor.process(pktCtx); |
| |
| assertTrue("Link not detected", detectedLink(DID1, DID2)); |
| |
| } |
| |
| |
| @After |
| public void tearDown() { |
| provider.deactivate(); |
| provider.coreService = null; |
| provider.providerRegistry = null; |
| provider.deviceService = null; |
| provider.packetService = null; |
| } |
| |
| private DeviceEvent deviceEvent(DeviceEvent.Type type, DeviceId did) { |
| return new DeviceEvent(type, deviceService.getDevice(did)); |
| |
| } |
| |
| private DefaultDevice device(DeviceId did) { |
| return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH, |
| "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId()); |
| } |
| |
| private DefaultDevice device(DeviceId did, Device.Type type) { |
| return new DefaultDevice(ProviderId.NONE, did, type, |
| "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId()); |
| } |
| |
| private DefaultDevice device(DeviceId did, Annotations annotations) { |
| return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH, |
| "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId(), annotations); |
| } |
| |
| @SuppressWarnings(value = {"unused"}) |
| private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, PortNumber port) { |
| return new DeviceEvent(type, deviceService.getDevice(did), |
| deviceService.getPort(did, port)); |
| } |
| |
| private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, Port port) { |
| return new DeviceEvent(type, deviceService.getDevice(did), port); |
| } |
| |
| private Port port(DeviceId did, long port, boolean enabled) { |
| return new DefaultPort(deviceService.getDevice(did), |
| PortNumber.portNumber(port), enabled); |
| } |
| |
| private Port port(DeviceId did, long port, boolean enabled, Annotations annotations) { |
| return new DefaultPort(deviceService.getDevice(did), |
| PortNumber.portNumber(port), enabled, annotations); |
| } |
| |
| private boolean vanishedDpid(DeviceId... dids) { |
| for (int i = 0; i < dids.length; i++) { |
| if (!providerService.vanishedDpid().contains(dids[i])) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| private boolean vanishedPort(Long... ports) { |
| for (int i = 0; i < ports.length; i++) { |
| if (!providerService.vanishedPort().contains(ports[i])) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| private boolean detectedLink(DeviceId src, DeviceId dst) { |
| for (DeviceId key : providerService.discoveredLinks().keySet()) { |
| if (key.equals(src)) { |
| return providerService.discoveredLinks().get(src).equals(dst); |
| } |
| } |
| return false; |
| } |
| |
| @Test |
| public void addDeviceTypeRule() { |
| Device.Type deviceType1 = Device.Type.ROADM; |
| Device.Type deviceType2 = Device.Type.SWITCH; |
| |
| Set<Device.Type> deviceTypes = new HashSet<>(); |
| deviceTypes.add(deviceType1); |
| |
| cfg.deviceTypes(deviceTypes); |
| |
| configEvent(NetworkConfigEvent.Type.CONFIG_ADDED); |
| |
| assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType1)); |
| assertFalse(provider.rules().getSuppressedDeviceType().contains(deviceType2)); |
| } |
| |
| @Test |
| public void updateDeviceTypeRule() { |
| Device.Type deviceType1 = Device.Type.ROADM; |
| Device.Type deviceType2 = Device.Type.SWITCH; |
| Set<Device.Type> deviceTypes = new HashSet<>(); |
| |
| deviceTypes.add(deviceType1); |
| cfg.deviceTypes(deviceTypes); |
| |
| configEvent(NetworkConfigEvent.Type.CONFIG_ADDED); |
| |
| deviceTypes.add(deviceType2); |
| cfg.deviceTypes(deviceTypes); |
| |
| configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED); |
| |
| assertAfter(EVENT_MS, () -> { |
| assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType1)); |
| assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType2)); |
| }); |
| } |
| |
| @Test |
| public void addAnnotationRule() { |
| final String key1 = "key1", key2 = "key2"; |
| final String value1 = "value1"; |
| |
| Map<String, String> annotation = new HashMap<>(); |
| annotation.put(key1, value1); |
| |
| cfg.annotation(annotation); |
| |
| configEvent(NetworkConfigEvent.Type.CONFIG_ADDED); |
| |
| assertAfter(EVENT_MS, () -> { |
| assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1)); |
| assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1)); |
| assertFalse(provider.rules().getSuppressedAnnotation().containsKey(key2)); |
| }); |
| } |
| |
| @Test |
| public void updateAnnotationRule() { |
| final String key1 = "key1", key2 = "key2"; |
| final String value1 = "value1", value2 = "value2"; |
| Map<String, String> annotation = new HashMap<>(); |
| |
| annotation.put(key1, value1); |
| cfg.annotation(annotation); |
| |
| configEvent(NetworkConfigEvent.Type.CONFIG_ADDED); |
| |
| assertAfter(EVENT_MS, () -> { |
| assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1)); |
| assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1)); |
| assertFalse(provider.rules().getSuppressedAnnotation().containsKey(key2)); |
| }); |
| |
| annotation.put(key2, value2); |
| cfg.annotation(annotation); |
| |
| configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED); |
| |
| assertAfter(EVENT_MS, () -> { |
| assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1)); |
| assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1)); |
| assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key2)); |
| assertEquals(value2, provider.rules().getSuppressedAnnotation().get(key2)); |
| }); |
| } |
| |
| private void configEvent(NetworkConfigEvent.Type evType) { |
| configListener.event(new NetworkConfigEvent(evType, |
| appId, |
| SuppressionConfig.class)); |
| } |
| |
| private class TestPacketContext implements PacketContext { |
| |
| protected Device device; |
| protected boolean blocked = false; |
| |
| public TestPacketContext(Device dev) { |
| device = dev; |
| } |
| |
| @Override |
| public long time() { |
| return 0; |
| } |
| |
| @Override |
| public InboundPacket inPacket() { |
| ONOSLLDP lldp = ONOSLLDP.onosLLDP(deviceService.getDevice(DID1).id().toString(), |
| device.chassisId(), |
| (int) pd1.number().toLong()); |
| |
| Ethernet ethPacket = new Ethernet(); |
| ethPacket.setEtherType(Ethernet.TYPE_LLDP); |
| ethPacket.setDestinationMACAddress(MacAddress.ONOS_LLDP); |
| ethPacket.setPayload(lldp); |
| ethPacket.setPad(true); |
| |
| ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11"); |
| |
| ConnectPoint cp = new ConnectPoint(device.id(), pd3.number()); |
| |
| return new DefaultInboundPacket(cp, ethPacket, |
| ByteBuffer.wrap(ethPacket.serialize())); |
| |
| } |
| |
| @Override |
| public OutboundPacket outPacket() { |
| return null; |
| } |
| |
| @Override |
| public TrafficTreatment.Builder treatmentBuilder() { |
| return null; |
| } |
| |
| @Override |
| public void send() { |
| |
| } |
| |
| @Override |
| public boolean block() { |
| blocked = true; |
| return blocked; |
| } |
| |
| @Override |
| public boolean isHandled() { |
| return blocked; |
| } |
| |
| } |
| |
| private class TestPacketService extends PacketServiceAdapter { |
| @Override |
| public void addProcessor(PacketProcessor processor, int priority) { |
| testProcessor = processor; |
| } |
| } |
| |
| private class TestDeviceService extends DeviceServiceAdapter { |
| |
| private final Map<DeviceId, Device> devices = new HashMap<>(); |
| private final ArrayListMultimap<DeviceId, Port> ports = |
| ArrayListMultimap.create(); |
| |
| public TestDeviceService() { |
| Device d1 = new DefaultDevice(ProviderId.NONE, DID1, Device.Type.SWITCH, |
| "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId()); |
| Device d2 = new DefaultDevice(ProviderId.NONE, DID2, Device.Type.SWITCH, |
| "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId()); |
| devices.put(DID1, d1); |
| devices.put(DID2, d2); |
| pd1 = new DefaultPort(d1, PortNumber.portNumber(1), true); |
| pd2 = new DefaultPort(d1, PortNumber.portNumber(2), true); |
| pd3 = new DefaultPort(d2, PortNumber.portNumber(1), true); |
| pd4 = new DefaultPort(d2, PortNumber.portNumber(2), true); |
| |
| ports.putAll(DID1, Lists.newArrayList(pd1, pd2)); |
| ports.putAll(DID2, Lists.newArrayList(pd3, pd4)); |
| } |
| |
| private void putDevice(Device device) { |
| DeviceId deviceId = device.id(); |
| devices.put(deviceId, device); |
| } |
| |
| private void putPorts(DeviceId did, Port... ports) { |
| this.ports.putAll(did, Lists.newArrayList(ports)); |
| } |
| |
| @Override |
| public int getDeviceCount() { |
| return devices.values().size(); |
| } |
| |
| @Override |
| public Iterable<Device> getDevices() { |
| return ImmutableList.copyOf(devices.values()); |
| } |
| |
| @Override |
| public Device getDevice(DeviceId deviceId) { |
| return devices.get(deviceId); |
| } |
| |
| @Override |
| public MastershipRole getRole(DeviceId deviceId) { |
| return MastershipRole.MASTER; |
| } |
| |
| @Override |
| public List<Port> getPorts(DeviceId deviceId) { |
| return ports.get(deviceId); |
| } |
| |
| @Override |
| public Port getPort(DeviceId deviceId, PortNumber portNumber) { |
| for (Port p : ports.get(deviceId)) { |
| if (p.number().equals(portNumber)) { |
| return p; |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public boolean isAvailable(DeviceId deviceId) { |
| return true; |
| } |
| |
| @Override |
| public void addListener(DeviceListener listener) { |
| deviceListener = listener; |
| |
| } |
| |
| @Override |
| public void removeListener(DeviceListener listener) { |
| |
| } |
| } |
| |
| private final class TestMasterShipService implements MastershipService { |
| |
| @Override |
| public MastershipRole getLocalRole(DeviceId deviceId) { |
| return MastershipRole.MASTER; |
| } |
| |
| @Override |
| public CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId) { |
| return CompletableFuture.completedFuture(null); |
| } |
| |
| @Override |
| public CompletableFuture<Void> relinquishMastership(DeviceId deviceId) { |
| return null; |
| } |
| |
| @Override |
| public NodeId getMasterFor(DeviceId deviceId) { |
| return null; |
| } |
| |
| @Override |
| public Set<DeviceId> getDevicesOf(NodeId nodeId) { |
| return null; |
| } |
| |
| @Override |
| public MastershipInfo getMastershipFor(DeviceId deviceId) { |
| return null; |
| } |
| |
| @Override |
| public void addListener(MastershipListener listener) { |
| |
| } |
| |
| @Override |
| public void removeListener(MastershipListener listener) { |
| |
| } |
| |
| @Override |
| public RoleInfo getNodesFor(DeviceId deviceId) { |
| return new RoleInfo(new NodeId("foo"), Collections.<NodeId>emptyList()); |
| } |
| } |
| |
| |
| private class TestLinkService extends LinkServiceAdapter { |
| } |
| |
| private final class TestNetworkConfigRegistry |
| extends NetworkConfigRegistryAdapter { |
| @SuppressWarnings("unchecked") |
| @Override |
| public <S, C extends Config<S>> C getConfig(S subj, Class<C> configClass) { |
| if (configClass == SuppressionConfig.class) { |
| return (C) cfg; |
| } else if (configClass == LinkDiscoveryFromDevice.class) { |
| return (C) new LinkDiscoveryFromDevice() { |
| @Override |
| public boolean enabled() { |
| return !deviceBlacklist.contains(subj); |
| } |
| }; |
| } else if (configClass == LinkDiscoveryFromPort.class) { |
| return (C) new LinkDiscoveryFromPort() { |
| @Override |
| public boolean enabled() { |
| return !portBlacklist.contains(subj); |
| } |
| }; |
| } else { |
| return null; |
| } |
| } |
| |
| @Override |
| public void addListener(NetworkConfigListener listener) { |
| configListener = listener; |
| } |
| } |
| |
| private final class TestSuppressionConfig extends SuppressionConfig { |
| private Set<Device.Type> deviceTypes = new HashSet<>(DEFAULT_RULES.getSuppressedDeviceType()); |
| private Map<String, String> annotation = new HashMap<>(DEFAULT_RULES.getSuppressedAnnotation()); |
| |
| @Override |
| public Set<Device.Type> deviceTypes() { |
| return ImmutableSet.copyOf(deviceTypes); |
| } |
| |
| @Override |
| public SuppressionConfig deviceTypes(Set<Device.Type> deviceTypes) { |
| this.deviceTypes = ImmutableSet.copyOf(deviceTypes); |
| return this; |
| } |
| |
| @Override |
| public Map<String, String> annotation() { |
| return ImmutableMap.copyOf(annotation); |
| } |
| |
| @Override |
| public SuppressionConfig annotation(Map<String, String> annotation) { |
| this.annotation = ImmutableMap.copyOf(annotation); |
| return this; |
| } |
| } |
| } |