/* ALMA - Atacama Large Millimiter Array * Copyright (c) European Southern Observatory, 2013 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package alma.alarmsystem.clients.test; import java.sql.Timestamp; import java.util.Vector; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import cern.laser.client.data.Alarm; import cern.laser.client.services.selection.AlarmSelectionListener; import cern.laser.client.services.selection.LaserSelectionException; import cern.laser.source.alarmsysteminterface.FaultState; import alma.acs.component.client.ComponentClientTestCase; import alma.alarmsystem.clients.AlarmCategoryClient; import alma.alarmsystem.source.ACSAlarmSystemInterface; import alma.alarmsystem.source.ACSAlarmSystemInterfaceFactory; import alma.alarmsystem.source.ACSFaultState; import alma.alarmsystem.clients.alarm.AlarmFilter; import alma.alarmsystem.clients.test.utils.AlarmListenerForTesting; import alma.alarmsystem.clients.test.utils.AlrmStatListenerForTesting;; /** * This test is basically an extension of {@link CategoryClientTest} to test AlarmCategoryClient * <P> * The test is done using 2 listener2, one that gets only the alarms having a defined fault code ({@link #filteredLister}) * and another one that gets all the alarms (the object itself). * <P> * The alarms received by the filtered listener are printed to the stdout (@see {@link AlarmListenerForTesting#onAlarm(Alarm)}) * <P> * Notification of statistics are printed in the stdout (@see {@link AlrmStatListenerForTesting}). * @author acaproni * @since ACS-12.2 * */ public class AlarmCategoryClientTest extends ComponentClientTestCase implements AlarmSelectionListener { /** * The definition of the alarms as we expect they arrive from * the alarm system * * @author acaproni * */ public enum AlarmsFromCDB { M1_1A("TEST", "TEST_MEMBER1", 1, true,2,"The cause","Run and fix quickly","Test alarm 1","A disaster"), M1_2A("TEST", "TEST_MEMBER1", 2, true,3,null,null,"Test alarm 2",null), M2_1A("TEST", "TEST_MEMBER2", 1, true,2,"The cause","Run and fix quickly","Test alarm 1","A disaster"), M2_2A("TEST", "TEST_MEMBER2", 2, true,3,null,null,"Test alarm 2",null), M1_1I("TEST", "TEST_MEMBER1", 1, false,2,"The cause","Run and fix quickly","Test alarm 1","A disaster"), M1_2I("TEST", "TEST_MEMBER1", 2, false,3,null,null,"Test alarm 2",null), M2_1I("TEST", "TEST_MEMBER2", 1, false,2,"The cause","Run and fix quickly","Test alarm 1","A disaster"), M2_2I("TEST", "TEST_MEMBER2", 2, false,3,null,null,"Test alarm 2",null); public final String FF; public final String FM; public final Integer FC; public boolean state; public final String cause; public final String action; public final String consequence; public final String description; public final Integer priority; private AlarmsFromCDB( String FF, String FM, int code, boolean status, int pri, String cause, String action, String desc, String consequence) { this.FF=FF; this.FM=FM; this.FC=code; this.state=status; this.priority=pri; this.consequence=consequence; this.description=desc; this.cause=cause; this.action=action; } /** * Return the alarm with the given triplet * * @param FF Fault Family * @param FM Fault Member * @param code Fault Code * @return The alarm with the given triplet * null if the triplet does not exist */ public static AlarmsFromCDB getCDBAlarm(String FF, String FM, int code) { for (AlarmsFromCDB alarm: AlarmsFromCDB.values()) { if (alarm.FF.equals(FF) && alarm.FM.equals(FM) && alarm.FC==code) { return alarm; } } return null; } } /** * The categoryClient to test */ private AlarmCategoryClient categoryClient; /** * A filtered listener of Alarms */ private AlarmListenerForTesting filteredLister; /** * */ private AlrmStatListenerForTesting statListener; /** * The vector with the alarms received */ private Vector<Alarm> alarmsReceived; /** * <code>latch</code> signals when all the alarms have been received */ private CountDownLatch latch = new CountDownLatch(8); /** * Max number of seconds to wait for the messages */ private static final int MAX_TIMEOUT = 120; /** * Constructor * * @throws Exception */ public AlarmCategoryClientTest() throws Exception{ super("AlarmCategoryClientTest"); } /** * @see extends ComponentClientTestCase */ public void setUp() throws Exception { super.setUp(); categoryClient = new AlarmCategoryClient(getContainerServices()); assertNotNull(categoryClient); AlarmFilter filter = new AlarmFilter(null, null, 2, 2); filteredLister = new AlarmListenerForTesting("Filtered_listener"); assertNotNull(filteredLister); categoryClient.addAlarmListener(this); categoryClient.addAlarmListener(filteredLister, filter); statListener = new AlrmStatListenerForTesting(); assertNotNull(statListener); categoryClient.addStatsListener(statListener); alarmsReceived=new Vector<Alarm>(); } /** * @see extends ComponentClientTestCase */ public void tearDown() throws Exception { categoryClient.close(); alarmsReceived.clear(); super.tearDown(); } /** * @see AlarmSelectionListener */ public void onAlarm(Alarm alarm) { synchronized (alarmsReceived) { alarmsReceived.add(alarm); latch.countDown(); } } /** * @see AlarmSelectionListener */ public void onException(LaserSelectionException e) { System.err.println("onException: "+e.getMessage()); e.printStackTrace(System.err); } /** * Sends a couple of alarms and check if they arrive from the client * @throws Exception */ public void testAlarmReception() throws Exception { categoryClient.connect(); // Send the alarms send_alarm("TEST", "TEST_MEMBER1", 1, true); send_alarm("TEST", "TEST_MEMBER1", 2, true); send_alarm("TEST", "TEST_MEMBER2", 1, true); send_alarm("TEST", "TEST_MEMBER2", 2, true); /// Clear the alarms try { Thread.sleep(5000); } catch (Exception e) {} send_alarm("TEST", "TEST_MEMBER1", 1, false); send_alarm("TEST", "TEST_MEMBER1", 2, false); send_alarm("TEST", "TEST_MEMBER2", 1, false); send_alarm("TEST", "TEST_MEMBER2", 2, false); // Wait for all the messages assertTrue("TIMEOUT: not all the alarms have been received",waitForMessages(latch)); // Check the correctness of the messages for (Alarm alarm: alarmsReceived) { assertEquals("Wrong responsible person in "+alarm,"Alex", alarm.getResponsiblePerson().getFirstName()); assertEquals("123456", alarm.getResponsiblePerson().getGsmNumber()); assertEquals("http://tempuri.org", alarm.getHelpURL().toString()); AlarmsFromCDB cdbAlarm = AlarmsFromCDB.getCDBAlarm( alarm.getTriplet().getFaultFamily(), alarm.getTriplet().getFaultMember(), alarm.getTriplet().getFaultCode()); String alarmDesc = "<"+alarm.getTriplet().getFaultFamily()+", "+alarm.getTriplet().getFaultMember()+", "+alarm.getTriplet().getFaultCode()+ "> "; assertEquals(alarmDesc+"Priority",cdbAlarm.priority,alarm.getPriority()); assertEquals(alarmDesc+"Cause",cdbAlarm.cause,alarm.getCause()); assertEquals(alarmDesc+"Description",cdbAlarm.description,alarm.getProblemDescription()); assertEquals(alarmDesc+"Consequence",cdbAlarm.consequence,alarm.getConsequence()); assertEquals(alarmDesc+"Action",cdbAlarm.action,alarm.getAction()); } } /** * Push an alarm * * @param active If true the alarm is active */ private void send_alarm(String family, String member, int code, boolean active) throws Exception { ACSAlarmSystemInterface alarmSource; alarmSource = ACSAlarmSystemInterfaceFactory.createSource(member); ACSFaultState fs = ACSAlarmSystemInterfaceFactory.createFaultState(family, member, code); if (active) { fs.setDescriptor(FaultState.ACTIVE); } else { fs.setDescriptor(FaultState.TERMINATE); } fs.setUserTimestamp(new Timestamp(System.currentTimeMillis())); alarmSource.push(fs); } /** * Wait for the messages from the alarm system. * * @param signal The {@link CountDownLatch} to know when all the alarms * have been received * @return <code>true</code> if all the messages are received; * <code>false</code> in case of timeout (i.e. not all the messages received * in MAX_TIMEOUT seconds) * @throws InterruptedException */ private boolean waitForMessages(CountDownLatch signal) throws InterruptedException { if (!signal.await(MAX_TIMEOUT, TimeUnit.SECONDS)) { return false; } int timeout =0; // Wait 10 more senconds until all alarms for filtered arrive // It can happen that the signal arrived before the filtered listener receives the last // alarm while (filteredLister.numAlarms!=4 && timeout<20) { Thread.sleep(500); timeout++; } assertEquals("Not all the filtered alarms have been received", 4,filteredLister.numAlarms ); return true; } }