/* * 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.ImmutableSet; import com.google.common.collect.Lists; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.onlab.junit.TestTools; import org.onlab.junit.TestUtils; import org.onlab.util.ItemNotFoundException; import org.onosproject.common.event.impl.TestEventDispatcher; import org.onosproject.event.Event; import org.onosproject.incubator.net.faultmanagement.alarm.Alarm; import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId; import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEvent; import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId; import org.onosproject.incubator.net.faultmanagement.alarm.AlarmListener; import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProvider; import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderRegistry; import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderService; import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm; import org.onosproject.net.DeviceId; import org.onosproject.net.MastershipRole; import org.onosproject.net.NetTestTools; import org.onosproject.net.provider.AbstractProvider; import org.onosproject.store.service.TestStorageService; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import static junit.framework.TestCase.assertFalse; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.onosproject.incubator.net.faultmanagement.alarm.Alarm.SeverityLevel.CLEARED; import static org.onosproject.incubator.net.faultmanagement.alarm.Alarm.SeverityLevel.CRITICAL; import static org.onosproject.net.NetTestTools.PID; /** * Alarm manager test suite. */ public class AlarmManagerTest { private static final DeviceId DEVICE_ID = DeviceId.deviceId("foo:bar"); private static final String UNIQUE_ID_1 = "unique_id_1"; private static final String UNIQUE_ID_2 = "unique_id_2"; private static final AlarmId A_ID = AlarmId.alarmId(DEVICE_ID, UNIQUE_ID_1); private static final AlarmId B_ID = AlarmId.alarmId(DEVICE_ID, UNIQUE_ID_2); private static final DefaultAlarm ALARM_A = new DefaultAlarm.Builder(A_ID, DEVICE_ID, "aaa", Alarm.SeverityLevel.CRITICAL, 0).build(); private static final DefaultAlarm ALARM_A_CLEARED = new DefaultAlarm.Builder(ALARM_A) .clear().build(); private static final DefaultAlarm ALARM_A_WITHSRC = new DefaultAlarm.Builder( ALARM_A).forSource(AlarmEntityId.alarmEntityId("port:foo")).build(); private static final DefaultAlarm ALARM_B = new DefaultAlarm.Builder(B_ID, DEVICE_ID, "bbb", Alarm.SeverityLevel.CRITICAL, 0).build(); private AlarmManager manager; private DistributedAlarmStore alarmStore; private AlarmProviderService providerService; private TestProvider provider; protected AlarmProviderRegistry registry; protected TestListener listener = new TestListener(); @Rule public final ExpectedException exception = ExpectedException.none(); @Before public void setUp() throws Exception { alarmStore = new DistributedAlarmStore(); TestUtils.setField(alarmStore, "storageService", new TestStorageService()); alarmStore.activate(); manager = new AlarmManager(); registry = manager; manager.addListener(listener); NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher()); manager.store = alarmStore; manager.activate(); provider = new TestProvider(); providerService = registry.register(provider); } @Test public void deactivate() throws Exception { providerService.updateAlarmList(DEVICE_ID, ImmutableSet.of(ALARM_B, ALARM_A)); verifyGettingSetsOfAlarms(manager, 2, 2); alarmStore.deactivate(); manager.removeListener(listener); manager.deactivate(); NetTestTools.injectEventDispatcher(manager, null); assertFalse("Store should not have delegate", alarmStore.hasDelegate()); } @Test public void testGettersWhenNoAlarms() { assertTrue("No alarms should be present", manager.getAlarms().isEmpty()); assertTrue("No active alarms should be present", manager.getActiveAlarms().isEmpty()); assertTrue("The map should be empty per unknown device", manager.getAlarmCounts(DeviceId.NONE).keySet().isEmpty()); assertTrue("The counts should be empty", manager.getAlarmCounts().keySet().isEmpty()); assertEquals("Incorrect number of alarms for unknown device", 0, manager.getAlarms(DeviceId.NONE).size()); assertEquals("Incorrect number of major alarms for unknown device", 0, manager.getAlarms(Alarm.SeverityLevel.MAJOR).size()); exception.expect(NullPointerException.class); manager.getAlarm(null); exception.expect(ItemNotFoundException.class); manager.getAlarm(AlarmId.alarmId(DEVICE_ID, "unique_3")); } @Test public void testAlarmUpdates() throws InterruptedException { assertTrue("No alarms should be present", manager.getAlarms().isEmpty()); providerService.updateAlarmList(DEVICE_ID, ImmutableSet.of()); assertTrue("No alarms should be present", manager.getAlarms().isEmpty()); Map<Alarm.SeverityLevel, Long> zeroAlarms = new CountsMapBuilder().create(); assertEquals("No alarms count should be present", zeroAlarms, manager.getAlarmCounts()); assertEquals("No alarms count should be present", zeroAlarms, manager.getAlarmCounts(DEVICE_ID)); providerService.updateAlarmList(DEVICE_ID, ImmutableSet.of(ALARM_B, ALARM_A)); verifyGettingSetsOfAlarms(manager, 2, 2); validateEvents(AlarmEvent.Type.CREATED, AlarmEvent.Type.CREATED); Map<Alarm.SeverityLevel, Long> critical2 = new CountsMapBuilder().with(CRITICAL, 2L).create(); assertEquals("A critical should be present", critical2, manager.getAlarmCounts()); assertEquals("A critical should be present", critical2, manager.getAlarmCounts(DEVICE_ID)); Alarm updated = manager.updateBookkeepingFields(ALARM_A.id(), true, false, null); // providerService.updateAlarmList(DEVICE_ID, ImmutableSet.of(ALARM_A)); verifyGettingSetsOfAlarms(manager, 2, 1); validateEvents(AlarmEvent.Type.UPDATED); Map<Alarm.SeverityLevel, Long> critical1cleared1 = new CountsMapBuilder().with(CRITICAL, 1L).with(CLEARED, 1L).create(); assertEquals("A critical should be present and cleared", critical1cleared1, manager.getAlarmCounts()); assertEquals("A critical should be present and cleared", critical1cleared1, manager.getAlarmCounts(DEVICE_ID)); // No change map when same alarms sent providerService.updateAlarmList(DEVICE_ID, ImmutableSet.of(updated)); verifyGettingSetsOfAlarms(manager, 2, 1); validateEvents(); assertEquals("Map should not be changed for same alarm", critical1cleared1, manager.getAlarmCounts()); assertEquals("Map should not be changed for same alarm", critical1cleared1, manager.getAlarmCounts(DEVICE_ID)); providerService.updateAlarmList(DEVICE_ID, ImmutableSet.of(updated, ALARM_A_WITHSRC)); verifyGettingSetsOfAlarms(manager, 2, 2); validateEvents(AlarmEvent.Type.UPDATED); Map<Alarm.SeverityLevel, Long> critical2cleared1 = new CountsMapBuilder().with(CRITICAL, 2L).create(); assertEquals("A critical should be present", critical2cleared1, manager.getAlarmCounts()); assertEquals("A critical should be present", critical2cleared1, manager.getAlarmCounts(DEVICE_ID)); providerService.updateAlarmList(DEVICE_ID, ImmutableSet.of()); verifyGettingSetsOfAlarms(manager, 2, 2); validateEvents(); assertEquals(new CountsMapBuilder().with(CRITICAL, 2L).create(), manager.getAlarmCounts(DEVICE_ID)); assertEquals("The counts should be empty for unknown devices", zeroAlarms, manager.getAlarmCounts(DeviceId.NONE)); assertEquals("The counts should be empty for unknown devices", zeroAlarms, manager.getAlarmCounts(DeviceId.deviceId("junk:junk"))); } private void verifyGettingSetsOfAlarms(AlarmManager am, int expectedTotal, int expectedActive) { assertEquals("Incorrect total alarms", expectedTotal, am.getAlarms().size()); assertEquals("Incorrect active alarms count", expectedActive, am.getActiveAlarms().size()); } /** * Method to validate that actual versus expected device key events were * received correctly. * * @param types expected device key events. */ private void validateEvents(Enum... types) { TestTools.assertAfter(100, () -> { int i = 0; assertEquals("wrong events received", types.length, listener.events.size()); for (Event event : listener.events) { assertEquals("incorrect event type", types[i], event.type()); i++; } listener.events.clear(); }); } private static class CountsMapBuilder { private final Map<Alarm.SeverityLevel, Long> map = new HashMap<>(); public CountsMapBuilder with(Alarm.SeverityLevel sev, Long count) { map.put(sev, count); return this; } public Map<Alarm.SeverityLevel, Long> create() { return Collections.unmodifiableMap(map); } } private class TestProvider extends AbstractProvider implements AlarmProvider { private DeviceId deviceReceived; private MastershipRole roleReceived; public TestProvider() { super(PID); } @Override public void triggerProbe(DeviceId deviceId) { } } /** * Test listener class to receive alarm events. */ private static class TestListener implements AlarmListener { protected List<AlarmEvent> events = Lists.newArrayList(); @Override public void event(AlarmEvent event) { events.add(event); } } }