/* * ALMA - Atacama Large Millimiter Array * (c) European Southern Observatory, 2002 * Copyright by ESO (in the framework of the ALMA collaboration) * and Cosylab 2002, All rights reserved * * 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.acs.jlog.test; import java.util.Collection; import java.util.Vector; import java.util.concurrent.atomic.AtomicInteger; import com.cosylab.logging.engine.ExactFilter; import com.cosylab.logging.engine.Filter; import com.cosylab.logging.engine.FiltersVector; import com.cosylab.logging.engine.ACS.ACSLogConnectionListener; import com.cosylab.logging.engine.ACS.ACSRemoteErrorListener; import com.cosylab.logging.engine.ACS.ACSRemoteLogListener; import com.cosylab.logging.engine.ACS.ACSRemoteRawLogListener; import com.cosylab.logging.engine.ACS.LCEngine; import com.cosylab.logging.engine.log.ILogEntry; import com.cosylab.logging.engine.log.LogField; import com.cosylab.logging.engine.log.LogTypeHelper; import alma.acs.component.client.ComponentClientTestCase; import alma.acs.logging.AcsLogLevel; import alma.acs.logging.AcsLogger; import alma.acs.logging.config.LogConfig; /** * A class testing the filtering of logs in the engine. * * @author acaproni * */ public class EngineFilteringTest extends ComponentClientTestCase implements ACSLogConnectionListener, ACSRemoteLogListener, ACSRemoteRawLogListener, ACSRemoteErrorListener { // The engine to get logs from the logging service private LCEngine engine; // The received logs private Vector<ILogEntry> receivedLogs; // The number of XML logs received private AtomicInteger xmlLogsCount; // The number of INFO's in the XML private int xmlInfos=0; // The timeout (in secs) to decide when all the logs has been received private static final int TIMEOUT=60; // The number of logs generated for testing private static final int NUMBER_OF_LOGS =100; /** * Constructor * * @throws Exception */ public EngineFilteringTest() throws Exception { super("EngineFilteringTest"); } /** * Setup the environment by creating the engine with a null set of filters. * The engine is disconnected because some of the tests do not need the * connection alive. * * @see alma.acs.component.client.ComponentClientTestCase#setUp() */ @Override protected void setUp() throws Exception { super.setUp(); receivedLogs= new Vector<ILogEntry>(); assertNotNull(receivedLogs); receivedLogs.clear(); xmlLogsCount = new AtomicInteger(0); xmlInfos=0; assertNotNull(m_logger); AcsLogger acsLogger = m_logger; LogConfig config = new LogConfig(); acsLogger.configureLogging(config); engine = new LCEngine(); assertNotNull(engine); engine.addLogErrorListener(this); engine.addLogConnectionListener(this); engine.addLogListener(this); engine.addRawLogListener(this); } /** * @see alma.acs.component.client.ComponentClientTestCase#tearDown() */ @Override protected void tearDown() throws Exception { engine.disconnect(); super.tearDown(); } /* (non-Javadoc) * @see com.cosylab.logging.engine.ACS.ACSLogConnectionListener#acsLogConnConnecting() */ @Override public void acsLogConnConnecting() {} /** * Disconnected * * @see com.cosylab.logging.engine.ACS.ACSLogConnectionListener#acsLogConnDisconnected() */ @Override public void acsLogConnDisconnected() { System.out.println("Disconnected"); } /** * * @see com.cosylab.logging.engine.ACS.ACSLogConnectionListener#acsLogConnEstablished() */ @Override public void acsLogConnEstablished() {} /** * Connection lost: tat will show this situation * * @see com.cosylab.logging.engine.ACS.ACSLogConnectionListener#acsLogConnLost() */ @Override public void acsLogConnLost() { System.out.println("Connection lost!"); } /** * tat will show this situation * @see com.cosylab.logging.engine.ACS.ACSLogConnectionListener#acsLogConnSuspended() */ @Override public void acsLogConnSuspended() { System.out.println("Connection suspended"); } /* (non-Javadoc) * @see com.cosylab.logging.engine.ACS.ACSLogConnectionListener#acsLogsDelay() */ @Override public void acsLogsDelay() {} /* (non-Javadoc) * @see com.cosylab.logging.engine.ACS.ACSLogConnectionListener#reportStatus(java.lang.String) */ @Override public void reportStatus(String status) {} /** * Executed whenever a new log is received. * Filtering works here. * * The received log is added to the vector * * @see com.cosylab.logging.engine.ACS.ACSRemoteLogListener#logEntryReceived(com.cosylab.logging.engine.log.ILogEntry) */ @Override public void logEntryReceived(ILogEntry logEntry) { synchronized (receivedLogs) { receivedLogs.add(logEntry); } } /** * XML entries are not filtered! * * @see com.cosylab.logging.engine.ACS.ACSRemoteRawLogListener#xmlEntryReceived(java.lang.String) */ @Override public void xmlEntryReceived(String xmlLogString) { if (xmlLogString.contains("testFiltering")) { xmlLogsCount.incrementAndGet(); if (xmlLogString.contains("Info") && !xmlLogString.contains("Manager")) { xmlInfos++; } } } /** * Method executed in case of error: print a message in the stdout, * tat will show this error * * @see com.cosylab.logging.engine.ACS.ACSRemoteErrorListener#errorReceived(java.lang.String) */ @Override public void errorReceived(String xml) { System.out.println("ERROR: "+xml); } /** * Test the adding and clearing filters * * @throws Exception */ public void testAddFilter() throws Exception { // No filters defined: getFilters() return null assertNull(engine.getFilters()); // Create a filter Filter f = new ExactFilter(LogField.ENTRYTYPE,false,LogTypeHelper.INFO,false); assertNotNull(f); // Add the filter engine.addFilter(f); assertNotNull(engine.getFilters()); assertEquals("Sizes differ", 1, engine.getFilters().size()); // The filters has been added as active assertTrue(engine.getFilters().hasActiveFilters()); // Create and add another filter Filter f2 = new ExactFilter(LogField.ENTRYTYPE,false,LogTypeHelper.DEBUG,false); assertNotNull(f2); assertEquals("Sizes differ", 1, engine.getFilters().size()); // Clear the filters engine.clearFilters(); assertNull(engine.getFilters()); } /** * Test adding a FiltersVector */ public void testAddFiltersVector() throws Exception { // No filters defined: getFilters() return null assertNull(engine.getFilters()); // Create a filter Filter f = new ExactFilter(LogField.ENTRYTYPE,false,LogTypeHelper.INFO,false); assertNotNull(f); // Create and add another filter Filter f2 = new ExactFilter(LogField.ENTRYTYPE,false,LogTypeHelper.DEBUG,false); assertNotNull(f2); // Setup the filters vector FiltersVector filters = new FiltersVector(); assertNotNull(filters); filters.addFilter(f, true); filters.addFilter(f2, true); // Set the filters engine.setFilters(filters, false); assertNotNull(engine.getFilters()); assertEquals(filters.size(), engine.getFilters().size()); // Append the filters engine.setFilters(filters, true); assertNotNull(engine.getFilters()); assertEquals(filters.size()*2, engine.getFilters().size()); } /** * Set a filter and checks if the logs received are those passing a filters. * <P> * In this case we do not need to check the correctness of the logs received * in the listeners but only if they are received or not because it means that * the engine is using the filters. * <P> * For this example, the test defines 1 filter based on the type of the logs. * <P> * The correctness of the filtering is also tested in another test because the engine * uses the same filters used by the table. * * @throws Exception */ public void testFiltering() throws Exception { // Randomly generate the logs Collection<ILogEntry> logs = CacheUtils.generateLogs(NUMBER_OF_LOGS); assertNotNull(logs); assertEquals(NUMBER_OF_LOGS, logs.size()); Collection<ILogEntry> flushLogs = CacheUtils.generateLogsType(100, LogTypeHelper.NOTICE); // Create a filter for the type INFO Filter f = new ExactFilter(LogField.ENTRYTYPE,false,LogTypeHelper.INFO,false); assertNotNull(f); // And a filter for the source name Filter nameFilter = new ExactFilter(LogField.ROUTINE,false,getName(),false); assertNotNull(nameFilter); // No filters exists in the engine assertNull(engine.getFilters()); // Add the filters engine.addFilter(f); engine.addFilter(nameFilter); assertNotNull(engine.getFilters()); assertEquals("Size differ", 2, engine.getFilters().size()); // connect the engine engine.connect(); // wait until the engine is connected int iterCount=0; while (iterCount<TIMEOUT && !engine.isConnected()) { iterCount++; try { Thread.sleep(1000); } catch (Exception e) {} } assertTrue(engine.isConnected()); // publish all the logs and count the number of INFO logs int infos=0; for (ILogEntry log: logs) { AcsLogLevel level=AcsLogLevel.fromAcsCoreLevel(log.getType().acsCoreLevel); m_logger.log(level,(String)log.getField(LogField.LOGMESSAGE)); if (log.getType()==LogTypeHelper.INFO) { infos++; } } // publish some logs to flush the cache // // For a client it is not possible to configure the cache of logs through the CDB // and without sending some more logs the test sometimes fails because the logs are // cached. // Is it possible to change the parameters of the logging programmatically? // If it is possible then it is better this second option then sending logs.. try { Thread.sleep(1000); } catch (Exception e) {} System.out.println("Flushing"); for (ILogEntry log: flushLogs) { AcsLogLevel level=AcsLogLevel.fromAcsCoreLevel(log.getType().acsCoreLevel); m_logger.log(level,(String)log.getField(LogField.LOGMESSAGE)); } // wait till all the logs are received // // It additionally waits for TIMEOUT seconds after the last log has been // received to be sure there are no further logs delayed because of caching // or similar problems int elapsed =0; // The number of seconds after the last log has been received int count=0; // The number of logs at the previous iteration while (elapsed<TIMEOUT) { synchronized (receivedLogs) { if (receivedLogs.size()!=count) { count= receivedLogs.size(); elapsed=0; continue; } } // No new logs received try { Thread.sleep(1000); } catch (Exception e) {} elapsed++; } // If all the logs have been received then xmlLogsCount must be greater then NUMBER_OF_LOGS // Not equal because the xml logs are not filtered and there can be logs generated // outside of this object assertTrue("Received only " + xmlLogsCount.get() + " xml logs, when there should have been at least " + NUMBER_OF_LOGS, xmlLogsCount.get() >= NUMBER_OF_LOGS); // Check if the number of received logs is as expected assertEquals(infos,receivedLogs.size()); } }