/* * Copyright 2016-present Open Networking Laboratory * * 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.linkdiscovery.impl; import com.google.common.collect.ImmutableSet; import org.junit.Before; import org.junit.Test; import org.onlab.osgi.ComponentContextAdapter; import org.onlab.packet.ChassisId; import org.onosproject.cfg.ComponentConfigAdapter; import org.onosproject.core.ApplicationId; import org.onosproject.core.CoreService; import org.onosproject.core.DefaultApplicationId; import org.onosproject.mastership.MastershipService; import org.onosproject.mastership.MastershipServiceAdapter; import org.onosproject.net.AbstractProjectableModel; import org.onosproject.net.AnnotationKeys; import org.onosproject.net.Annotations; import org.onosproject.net.ConnectPoint; import org.onosproject.net.DefaultAnnotations; import org.onosproject.net.DefaultDevice; import org.onosproject.net.DefaultLink; import org.onosproject.net.Device; import org.onosproject.net.DeviceId; import org.onosproject.net.Link; import org.onosproject.net.LinkKey; import org.onosproject.net.PortNumber; import org.onosproject.net.behaviour.LinkDiscovery; import org.onosproject.net.device.DeviceListener; import org.onosproject.net.device.DeviceServiceAdapter; import org.onosproject.net.driver.AbstractHandlerBehaviour; import org.onosproject.net.driver.Behaviour; import org.onosproject.net.driver.Driver; import org.onosproject.net.driver.DriverAdapter; import org.onosproject.net.driver.DriverHandler; import org.onosproject.net.driver.DriverServiceAdapter; import org.onosproject.net.link.DefaultLinkDescription; import org.onosproject.net.link.LinkDescription; import org.onosproject.net.link.LinkProviderRegistryAdapter; import org.onosproject.net.link.LinkProviderServiceAdapter; import org.onosproject.net.link.LinkServiceAdapter; import org.onosproject.net.provider.ProviderId; import java.util.Dictionary; import java.util.HashSet; import java.util.Hashtable; import java.util.Set; import static org.easymock.EasyMock.*; import static org.junit.Assert.*; import static org.onlab.junit.TestTools.assertAfter; import static org.onosproject.provider.linkdiscovery.impl.LinkDiscoveryProvider.APP_NAME; import static org.onosproject.provider.linkdiscovery.impl.LinkDiscoveryProvider.SCHEME_NAME; /** * Test for polling mechanism of the NetconfLinkProvider. */ public class LinkDiscoveryProviderTest { private static final ComponentContextAdapter CONTEXT = new ComponentContextAdapter() { @Override public Dictionary getProperties() { Hashtable<String, Integer> props = new Hashtable<>(); props.put("linkPollFrequencySeconds", 2); props.put("linkPollDelaySeconds", 1); return props; } }; // Network Mocks private static final DeviceId DEVICE_ID_1 = DeviceId.deviceId("netconf:1.1.1.1"); private static final DeviceId DEVICE_ID_2 = DeviceId.deviceId("netconf:1.1.1.2"); private static final ConnectPoint CP11 = new ConnectPoint(DEVICE_ID_1, PortNumber.portNumber(1)); private static final ConnectPoint CP12 = new ConnectPoint(DEVICE_ID_1, PortNumber.portNumber(2)); private static final ConnectPoint CP13 = new ConnectPoint(DEVICE_ID_1, PortNumber.portNumber(3)); private static final ConnectPoint CP14 = new ConnectPoint(DEVICE_ID_1, PortNumber.portNumber(4)); private static final ConnectPoint CP21 = new ConnectPoint(DEVICE_ID_2, PortNumber.portNumber(1)); private static final ConnectPoint CP22 = new ConnectPoint(DEVICE_ID_2, PortNumber.portNumber(2)); private static final ConnectPoint CP23 = new ConnectPoint(DEVICE_ID_2, PortNumber.portNumber(3)); private static final ConnectPoint CP24 = new ConnectPoint(DEVICE_ID_2, PortNumber.portNumber(4)); private static final DefaultAnnotations DEVICE_ANNOTATIONS = DefaultAnnotations.builder() .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase()).build(); private static final DefaultAnnotations LINK_ANNOTATIONS = DefaultAnnotations.builder() .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase()).build(); private static final LinkKey LINKKEY1 = LinkKey.linkKey(CP11, CP21); private static final LinkDescription LINK1 = new DefaultLinkDescription(CP11, CP21, Link.Type.DIRECT, LINK_ANNOTATIONS); private static final LinkKey LINKKEY2 = LinkKey.linkKey(CP12, CP22); private static final LinkDescription LINK2 = new DefaultLinkDescription(CP12, CP22, Link.Type.DIRECT, LINK_ANNOTATIONS); private static final LinkKey LINKKEY3 = LinkKey.linkKey(CP13, CP23); private static final LinkDescription LINK3 = new DefaultLinkDescription(CP13, CP23, Link.Type.DIRECT, DefaultAnnotations.builder() .build()); private static final LinkKey LINKKEY4 = LinkKey.linkKey(CP14, CP24); private static final LinkDescription LINK4 = new DefaultLinkDescription(CP14, CP24, Link.Type.DIRECT, DefaultAnnotations.builder().build()); //Service Mocks private final MockDeviceService deviceService = new MockDeviceService(); private final LinkProviderRegistryAdapter linkRegistry = new LinkProviderRegistryAdapter(); private final MastershipService mastershipService = new MockMastershipService(); private final MockLinkService linkService = new MockLinkService(); private final Driver driver = new MockDriver(); //Provider related classes private LinkProviderServiceAdapter providerService; private CoreService coreService; private LinkDiscoveryProvider provider = new LinkDiscoveryProvider(); private final Device device1 = new MockDevice(provider.id(), DEVICE_ID_1, Device.Type.SWITCH, "foo.inc", "0", "0", "0", new ChassisId(), DEVICE_ANNOTATIONS); private Set<DeviceListener> deviceListeners = new HashSet<>(); private ApplicationId appId = new DefaultApplicationId(100, APP_NAME); private TestLink testLink = new TestLink(); @Before public void setUp() { coreService = createMock(CoreService.class); expect(coreService.registerApplication(appId.name())) .andReturn(appId).anyTimes(); replay(coreService); provider.coreService = coreService; provider.providerRegistry = linkRegistry; provider.deviceService = deviceService; provider.mastershipService = mastershipService; provider.linkService = linkService; provider.cfgService = new ComponentConfigAdapter(); AbstractProjectableModel.setDriverService(null, new DriverServiceAdapter()); provider.activate(null); providerService = linkRegistry.registeredProvider(); } @Test public void activate() throws Exception { assertFalse("Provider should be registered", linkRegistry.getProviders().contains(provider)); assertEquals("Device service should be registered", provider.deviceService, deviceService); assertEquals("Device listener should be added", 1, deviceListeners.size()); assertNotNull("Registration expected", providerService); assertEquals("Incorrect provider", provider, providerService.provider()); assertFalse("Executor should be running", provider.executor.isShutdown()); assertFalse("Executor should be running", provider.executor.isTerminated()); assertEquals("Incorrect polling frequency, should be default", 10, provider.linkPollFrequencySeconds); assertEquals("Incorrect polling delay , should be default", 20, provider.linkPollDelaySeconds); } @Test public void modified() throws Exception { provider.modified(CONTEXT); assertEquals("Incorrect polling frequency, should be default", 2, provider.linkPollFrequencySeconds); assertEquals("Incorrect polling delay , should be default", 1, provider.linkPollDelaySeconds); } @Test public void deactivate() throws Exception { provider.deactivate(); assertEquals("Device listener should be removed", 0, deviceListeners.size()); assertFalse("Provider should not be registered", linkRegistry.getProviders().contains(provider)); assertTrue(provider.executor.isShutdown()); assertNull(provider.providerService); } @Test public void linksTestForStoredDevice() { provider.modified(CONTEXT); providerService.discoveredLinkDescriptions().put(LINKKEY1, LINK1); providerService.discoveredLinkDescriptions().put(LINKKEY2, LINK2); providerService.discoveredLinkDescriptions().put(LINKKEY4, LINK4); testLink.addLinkDesc(LINK2); testLink.addLinkDesc(LINK3); assertAfter(1100, () -> { assertEquals("Total number of link must be 3", 3, providerService.discoveredLinkDescriptions().size()); assertFalse("Link1 should be removed", providerService.discoveredLinkDescriptions().containsKey(LINKKEY1)); assertTrue("Link2 should be present", providerService.discoveredLinkDescriptions().containsKey(LINKKEY2)); assertTrue("Link3 should be added", providerService.discoveredLinkDescriptions().containsKey(LINKKEY3)); assertEquals("Link3 should be annotated", SCHEME_NAME.toUpperCase(), providerService.discoveredLinkDescriptions() .get(LINKKEY3).annotations().value(AnnotationKeys.PROTOCOL)); assertTrue("Link4 should be present because it is not related to the LinkDiscovery", providerService.discoveredLinkDescriptions().containsKey(LINKKEY4)); }); clear(); } private void clear() { testLink.clearLinkDesc(); providerService.discoveredLinkDescriptions().clear(); providerService.discoveredLinks().clear(); } private class MockDeviceService extends DeviceServiceAdapter { @Override public Iterable<Device> getAvailableDevices() { return ImmutableSet.of(device1); } @Override public void addListener(DeviceListener listener) { deviceListeners.add(listener); } @Override public void removeListener(DeviceListener listener) { deviceListeners.remove(listener); } } private class MockMastershipService extends MastershipServiceAdapter { @Override public boolean isLocalMaster(DeviceId deviceId) { return true; } } private class MockLinkService extends LinkServiceAdapter { @Override public Set<Link> getDeviceEgressLinks(DeviceId deviceId) { Set<Link> links = new HashSet<>(); providerService.discoveredLinkDescriptions().values() .forEach(x -> links.add(DefaultLink.builder() .providerId(provider.id()) .src(x.src()) .dst(x.dst()) .type(x.type()) .isExpected(x.isExpected()) .annotations(x.annotations()).build())); return ImmutableSet.copyOf(links); } } private class MockDevice extends DefaultDevice { public MockDevice(ProviderId providerId, DeviceId id, Type type, String manufacturer, String hwVersion, String swVersion, String serialNumber, ChassisId chassisId, Annotations... annotations) { super(providerId, id, type, manufacturer, hwVersion, swVersion, serialNumber, chassisId, annotations); } @Override protected Driver locateDriver() { return driver; } @Override public Driver driver() { return driver; } } private class MockDriver extends DriverAdapter { @Override public <T extends Behaviour> T createBehaviour(DriverHandler handler, Class<T> behaviourClass) { return (T) testLink; } } private class TestLink extends AbstractHandlerBehaviour implements LinkDiscovery { Set<LinkDescription> linkDescriptions = new HashSet<>(); @Override public Set<LinkDescription> getLinks() { return ImmutableSet.copyOf(linkDescriptions); } private void addLinkDesc(LinkDescription link) { linkDescriptions.add(link); } private void clearLinkDesc() { linkDescriptions.clear(); } } }