/* * 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.faultmanagement.impl; import com.google.common.collect.ImmutableList; 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.cluster.NodeId; import org.onosproject.cluster.RoleInfo; import org.onosproject.incubator.net.faultmanagement.alarm.Alarm; import org.onosproject.incubator.net.faultmanagement.alarm.AlarmConsumer; import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId; import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProvider; import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderRegistry; import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderRegistryAdapter; import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderService; import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm; import org.onosproject.mastership.MastershipEvent; import org.onosproject.mastership.MastershipListener; import org.onosproject.mastership.MastershipService; import org.onosproject.mastership.MastershipServiceAdapter; import org.onosproject.net.AbstractProjectableModel; import org.onosproject.net.Annotations; import org.onosproject.net.DefaultAnnotations; import org.onosproject.net.DefaultDevice; import org.onosproject.net.Device; import org.onosproject.net.DeviceId; import org.onosproject.net.device.DeviceEvent; import org.onosproject.net.device.DeviceListener; import org.onosproject.net.device.DeviceService; 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.provider.ProviderId; import org.osgi.service.component.ComponentContext; import java.io.IOException; import java.util.Collection; import java.util.Dictionary; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; import static org.junit.Assert.*; import static org.onlab.junit.TestTools.assertAfter; /** * Test for the polling alarm provider based on the driver subsystem. */ public class PollingAlarmProviderTest { private final DeviceService deviceService = new MockDeviceService(); private final MastershipService mastershipService = new MockMastershipService(); private final AlarmProviderRegistry providerRegistry = new MockDeviceProviderRegistry(); private final AlarmProviderService alarmProviderService = new MockAlarmProviderService(); private final ComponentContext context = new MockComponentContext(); private static final DeviceId DEVICE_ID = DeviceId.deviceId("foo:1.1.1.1:1"); private Device device = new MockDevice(ProviderId.NONE, DEVICE_ID, Device.Type.OTHER, "foo.inc", "0", "0", "0", null, DefaultAnnotations.builder().build()); private final NodeId nodeId = NodeId.nodeId("fooNode"); private final MastershipEvent mastershipEvent = new MastershipEvent(MastershipEvent.Type.MASTER_CHANGED, DEVICE_ID, new RoleInfo(nodeId, ImmutableList.of())); private final DeviceEvent deviceEvent = new DeviceEvent(DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED, device); private static final String UNIQUE_ID_1 = "unique_id_1"; private static final AlarmId A_ID = AlarmId.alarmId(DEVICE_ID, UNIQUE_ID_1); private static final DefaultAlarm ALARM = new DefaultAlarm.Builder(A_ID, DEVICE_ID, "aaa", Alarm.SeverityLevel.CRITICAL, 0).build(); private final Driver driver = new MockDriver(); private PollingAlarmProvider provider = new PollingAlarmProvider(); private Set<DeviceListener> deviceListeners = new HashSet<>(); private Set<MastershipListener> mastershipListeners = new HashSet<>(); private HashMap<DeviceId, Collection<Alarm>> alarmStore = new HashMap<>(); @Before public void setUp() { provider.providerRegistry = providerRegistry; provider.deviceService = deviceService; provider.mastershipService = mastershipService; AbstractProjectableModel.setDriverService(null, new DriverServiceAdapter()); provider.activate(context); } @Test public void activate() throws Exception { assertFalse("Provider should be registered", providerRegistry.getProviders().contains(provider)); assertEquals("Device listener should be added", 1, deviceListeners.size()); assertEquals("Incorrect alarm provider service", alarmProviderService, provider.providerService); assertEquals("Mastership listener should be added", 1, mastershipListeners.size()); assertEquals("Incorrect polling frequency", 1, provider.alarmPollFrequencySeconds); assertFalse("Executor should be running", provider.alarmsExecutor.isShutdown()); provider.activate(null); assertEquals("Incorrect polling frequency, should be default", 60, provider.alarmPollFrequencySeconds); } @Test public void deactivate() throws Exception { provider.deactivate(); assertEquals("Device listener should be removed", 0, deviceListeners.size()); assertEquals("Mastership listener should be removed", 0, mastershipListeners.size()); assertFalse("Provider should not be registered", providerRegistry.getProviders().contains(provider)); assertTrue(provider.alarmsExecutor.isShutdown()); assertNull(provider.providerService); } @Test public void modified() throws Exception { provider.modified(null); assertEquals("Incorrect polling frequency", 1, provider.alarmPollFrequencySeconds); provider.activate(null); provider.modified(context); assertEquals("Incorrect polling frequency", 1, provider.alarmPollFrequencySeconds); } @Test public void alarmsPresent() throws IOException { assertAfter(1100, () -> { assertTrue("Alarms should be added", alarmStore.containsKey(DEVICE_ID)); assertTrue("Alarms should be added", alarmStore.get(DEVICE_ID).contains(ALARM)); }); } @Test public void mastershipListenerEvent() throws Exception { assertTrue("Incorrect relevant event", provider.mastershipListener .isRelevant(mastershipEvent)); provider.mastershipListener.event(mastershipEvent); assertAfter(1100, () -> { assertTrue("Alarms should be added", alarmStore.containsKey(DEVICE_ID)); }); } @Test public void deviceListenerEvent() throws Exception { assertTrue("Incorrect relevant event", provider.deviceListener .isRelevant(deviceEvent)); provider.deviceListener.event(deviceEvent); assertAfter(1100, () -> { assertTrue("Alarms should be added", alarmStore.containsKey(DEVICE_ID)); }); } //TODO add test for modified context and event handling form device listener. private class MockDeviceService extends DeviceServiceAdapter { @Override public Device getDevice(DeviceId did) { if (did.equals(DEVICE_ID)) { return device; } return null; } @Override public Iterable<Device> getAvailableDevices() { return ImmutableSet.of(device); } @Override public boolean isAvailable(DeviceId did) { return did.equals(DEVICE_ID); } @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; } @Override public void addListener(MastershipListener listener) { mastershipListeners.add(listener); } @Override public void removeListener(MastershipListener listener) { mastershipListeners.remove(listener); } } private class MockDeviceProviderRegistry extends AlarmProviderRegistryAdapter { Set<ProviderId> providers = new HashSet<>(); @Override public AlarmProviderService register(AlarmProvider provider) { return alarmProviderService; } @Override public void unregister(AlarmProvider provider) { providers.remove(provider.id()); } @Override public Set<ProviderId> getProviders() { return providers; } } private class MockAlarmProviderService implements AlarmProviderService { @Override public void updateAlarmList(DeviceId deviceId, Collection<Alarm> alarms) { if (alarmStore.containsKey(deviceId)) { Collection<Alarm> deviceAlarms = alarmStore.get(deviceId); deviceAlarms.addAll(alarms); alarmStore.put(deviceId, deviceAlarms); } else { alarmStore.put(deviceId, alarms); } } @Override public AlarmProvider provider() { return null; } } private class MockComponentContext extends ComponentContextAdapter { @Override public Dictionary getProperties() { return new MockDictionary(); } } private class MockDictionary extends Dictionary { @Override public int size() { return 0; } @Override public boolean isEmpty() { return false; } @Override public Enumeration keys() { return null; } @Override public Enumeration elements() { return null; } @Override public Object get(Object key) { if ("pollFrequency".equals(key)) { return "1"; } return null; } @Override public Object put(Object key, Object value) { return null; } @Override public Object remove(Object key) { return null; } } private class MockDevice extends DefaultDevice { /** * Creates a network element attributed to the specified provider. * * @param providerId identity of the provider * @param id device identifier * @param type device type * @param manufacturer device manufacturer * @param hwVersion device HW version * @param swVersion device SW version * @param serialNumber device serial number * @param chassisId chassis id * @param annotations optional key/value annotations */ 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) new TestAlarmConsumer(); } } private class TestAlarmConsumer extends AbstractHandlerBehaviour implements AlarmConsumer { @Override public List<Alarm> consumeAlarms() { return ImmutableList.of(ALARM); } } }