/******************************************************************************* * ALMA - Atacama Large Millimeter Array * Copyright (c) COSYLAB - Control System Laboratory, 2011 * (in the framework of the ALMA collaboration). * 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 com.cosylab.logging; import java.text.FieldPosition; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.Set; import com.cosylab.logging.client.cache.LogCache; import com.cosylab.logging.engine.log.ILogEntry; import com.cosylab.logging.engine.log.LogField; import alma.acs.logging.engine.parser.ACSLogParser; import alma.acs.logging.engine.parser.ACSLogParserFactory; import alma.acs.util.IsoDateFormat; /** * The class to test the LogFileCache and the LogCache * * @author acaproni * * @see junit.framework.TestCase */ public class CacheTest extends junit.framework.TestCase { // The cache to stress private LogCache cache; // Number of logs generated dynamically // Its value is returned by the fillCache methods private long logsGenerated; public CacheTest(String str) { super(str); } /** * This execute for each test and we want to have * a cache with some logs * * @see junit.framework.TestCase */ protected void setUp() throws Exception { try { cache = new LogCache(); } catch (Exception e) { System.out.println("Error creating the cache "+e.getMessage()); throw e; } logsGenerated=fillCache(); } /** * @see junit.framework.TestCase * */ protected void tearDown() { try { cache.clear(); } catch (Exception e) { System.out.println("Exception while clearing the cache"+e.getMessage()); e.printStackTrace(); } cache=null; } /** * Fill the cache with dynamically generated logs * The number of logs inserted in the list is greater than the * memory cache size to stress the disk cache also. * * @return The number of logs inserted in the cache * * @throws Exception */ private long fillCache() throws Exception { ACSLogParser parser = ACSLogParserFactory.getParser(); String logMsg = "Test log nr. "; long now = Calendar.getInstance().getTimeInMillis()-1000*60*60*24; // Yesterday SimpleDateFormat df = new IsoDateFormat(); cache.clear(); long logToInsert = 2*cache.getCacheSize(); for (int t=0; t<logToInsert; t++) { Date dt = new Date(now+t*1000); StringBuffer dateSB = new StringBuffer(); FieldPosition pos = new FieldPosition(0); df.format(dt,dateSB,pos); String newLogMsg=logMsg+"t"; StringBuilder logStr = new StringBuilder("<Info TimeStamp=\""); logStr.append(dateSB.toString()); logStr.append("\" Routine=\"CacheTest::testGet\" Host=\"this\" Process=\"test\" Thread=\"main\" Context=\"\"><![CDATA["); logStr.append(newLogMsg); logStr.append("]]></Info>"); ILogEntry newLog = parser.parse(logStr.toString()); cache.add(newLog); } return logToInsert; } /** * It checks if all the logs in the file are in the cache * * @throws Exception */ public void testSize() throws Exception { assertEquals("Error loading logs",logsGenerated,(long)cache.getSize()); } /** * Get all the logs in cache to check the get method * * @throws Exception */ public void testGet() throws Exception { ILogEntry log; for (int t=0; t<cache.getSize(); t++) { log = cache.getLog(0); assertNotNull("Error getting the log "+t,log); } } /** * Check the add method by inserting and reading a log * */ public void testAddLog() throws Exception { ACSLogParser parser = ACSLogParserFactory.getParser(); int oldSize = cache.getSize(); String logMsg = "Test log"; String logStr = "<Info TimeStamp=\"2005-11-29T15:33:10.592\" Routine=\"CacheTest::testGet\" Host=\"this\" Process=\"test\" Thread=\"main\" Context=\"\"><![CDATA["+logMsg+"]]></Info>"; ILogEntry newLog = parser.parse(logStr); cache.add(newLog); assertEquals("Error adding a log",cache.getSize(),oldSize+1); ILogEntry log = cache.getLog(cache.getSize()-1); String msg = (String)log.getField(LogField.LOGMESSAGE); assertEquals("Error adding a log",logMsg,msg); } /** * Test the replacement of a log * */ public void testReplace() throws Exception { ACSLogParser parser = ACSLogParserFactory.getParser(); String logMsg = "Replaced test log"; String logStr = "<Info TimeStamp=\"2005-11-29T16:00:00.000\" Routine=\"CacheTest::testReplace\" Host=\"this\" Process=\"test\" Thread=\"main\" Context=\"\"><![CDATA["+logMsg+"]]></Info>"; ILogEntry newLog = parser.parse(logStr); // Replace the first log cache.replaceLog(0,newLog); assertEquals("Error replacing log "+0,logMsg,(String)cache.getLog(0).getField(LogField.LOGMESSAGE)); // Replace the last log cache.replaceLog(cache.getSize()-1,newLog); assertEquals("Error replacing log "+(cache.getSize()-1),logMsg,(String)cache.getLog(cache.getSize()-1).getField(LogField.LOGMESSAGE)); // Replace a log in the middle int pos = cache.getSize()/2; cache.replaceLog(pos,newLog); assertEquals("Error replacing log "+pos,logMsg,(String)cache.getLog(pos).getField(LogField.LOGMESSAGE)); } /** * test if a cleared cache contains exactly 0 logs * * @throws Exception */ public void testClear() throws Exception { cache.clear(); assertEquals("Error clearing the cache",(long)cache.getSize(),0L); } /** * It is deifficult to test LogCache... * This is better then nothing * * The test is done by reading all the cache sequentially. * The first, middle and last logs acquired in the beginning are * compared with those retrieved with the sequential scan. * */ public void testMemoryCache() throws Exception { int first = 0; String firstMsg = (String)cache.getLog(first).getField(LogField.LOGMESSAGE); int last = cache.getSize()-1; String lastMsg = (String)cache.getLog(last).getField(LogField.LOGMESSAGE); int pos = cache.getSize()/2; String posMsg = (String)cache.getLog(pos).getField(LogField.LOGMESSAGE); // Scans the list for (int t=0; t<last; t++) { cache.getLog(t); ILogEntry firstLog = cache.getLog(first); assertEquals("Error in mem cache pos "+first,firstMsg, firstLog.getField(LogField.LOGMESSAGE)); ILogEntry lastLog = cache.getLog(last); assertEquals("Error in mem cache pos "+last,lastMsg, lastLog.getField(LogField.LOGMESSAGE)); ILogEntry posLog = cache.getLog(pos); assertEquals("Error in mem cache pos "+pos,posMsg, posLog.getField(LogField.LOGMESSAGE)); } } /** * Check the calculation of the time frame * * @throws Exception */ public void testTimeFrameCalc() throws Exception { ACSLogParser parser = ACSLogParserFactory.getParser(); // Create some logs with a time frame of 10sec String logStr1 = "<Info TimeStamp=\"2005-11-29T15:33:10.000\" Routine=\"CacheTest::testGet\" Host=\"this\" Process=\"test\" Thread=\"main\" Context=\"\"><![CDATA[Test1]]></Info>"; String logStr2 = "<Info TimeStamp=\"2005-11-29T15:33:20.000\" Routine=\"CacheTest::testGet\" Host=\"this\" Process=\"test\" Thread=\"main\" Context=\"\"><![CDATA[Test2]]></Info>"; String logStr3 = "<Info TimeStamp=\"2005-11-29T15:33:15.000\" Routine=\"CacheTest::testGet\" Host=\"this\" Process=\"test\" Thread=\"main\" Context=\"\"><![CDATA[Test3]]></Info>"; String logStr4 = "<Info TimeStamp=\"2005-11-29T15:33:12.000\" Routine=\"CacheTest::testGet\" Host=\"this\" Process=\"test\" Thread=\"main\" Context=\"\"><![CDATA[Test4]]></Info>"; cache.clear(); cache.add(parser.parse(logStr1)); cache.add(parser.parse(logStr2)); cache.add(parser.parse(logStr3)); cache.add(parser.parse(logStr4)); Calendar cal=cache.getTimeFrame(); assertEquals("The time frame is wrong",10*1000,cal.getTimeInMillis()); } /** * Check if the method returning the logs exceeding the time frame is * working as expected. * * @throws Exception */ public void testLogExceedingTimeFrame() throws Exception { ACSLogParser parser = ACSLogParserFactory.getParser(); // Create some logs // The important fields here are the times (we'll test against a time frame of 30 secs) // It is also important the message that is used to check which messages // are added in the collection and which not String logStr1 = "<Info TimeStamp=\"2005-11-29T15:33:55.000\" Routine=\"CacheTest::testGet\" Host=\"this\" Process=\"test\" Thread=\"main\" Context=\"\"><![CDATA[Test1]]></Info>"; String logStr2 = "<Info TimeStamp=\"2005-11-29T15:33:20.000\" Routine=\"CacheTest::testGet\" Host=\"this\" Process=\"test\" Thread=\"main\" Context=\"\"><![CDATA[Test2]]></Info>"; String logStr3 = "<Info TimeStamp=\"2005-11-29T15:33:10.000\" Routine=\"CacheTest::testGet\" Host=\"this\" Process=\"test\" Thread=\"main\" Context=\"\"><![CDATA[Test3]]></Info>"; String logStr4 = "<Info TimeStamp=\"2005-11-29T15:34:15.000\" Routine=\"CacheTest::testGet\" Host=\"this\" Process=\"test\" Thread=\"main\" Context=\"\"><![CDATA[Test4]]></Info>"; String logStr5 = "<Info TimeStamp=\"2005-11-29T15:33:12.000\" Routine=\"CacheTest::testGet\" Host=\"this\" Process=\"test\" Thread=\"main\" Context=\"\"><![CDATA[Test5]]></Info>"; String logStr6 = "<Info TimeStamp=\"2005-11-29T15:34:05.000\" Routine=\"CacheTest::testGet\" Host=\"this\" Process=\"test\" Thread=\"main\" Context=\"\"><![CDATA[Test6]]></Info>"; String logStr7 = "<Info TimeStamp=\"2005-11-29T15:34:15.000\" Routine=\"CacheTest::testGet\" Host=\"this\" Process=\"test\" Thread=\"main\" Context=\"\"><![CDATA[Test7]]></Info>"; String logStr8 = "<Info TimeStamp=\"2005-11-29T15:34:10.000\" Routine=\"CacheTest::testGet\" Host=\"this\" Process=\"test\" Thread=\"main\" Context=\"\"><![CDATA[Test8]]></Info>"; String logStr9 = "<Info TimeStamp=\"2005-11-29T15:33:25.000\" Routine=\"CacheTest::testGet\" Host=\"this\" Process=\"test\" Thread=\"main\" Context=\"\"><![CDATA[Test9]]></Info>"; cache.clear(); cache.add(parser.parse(logStr1)); cache.add(parser.parse(logStr2)); cache.add(parser.parse(logStr3)); cache.add(parser.parse(logStr4)); cache.add(parser.parse(logStr5)); cache.add(parser.parse(logStr6)); cache.add(parser.parse(logStr7)); cache.add(parser.parse(logStr8)); cache.add(parser.parse(logStr9)); assertEquals("Wrong cache size",9,cache.getSize()); // An array of boolean: the items marked as true should appear in the Collection boolean[] b = { true, false, false, true, false, true, true, true, false }; // Get the logs exceeding a time frame of 30 secs Collection<Integer> logs = cache.getLogExceedingTimeFrame(30*1000); assertEquals("Wrong number of logs exceeding time frame",5,logs.size()); // Check if the logs returned by getLogExceedingTimeFrame are ok boolean[] returned = new boolean[9]; for (int t=0; t<returned.length; t++) { returned[t]=false; // Init all as false } // Mark as true the logs in the Collection for (Integer logN: logs) { ILogEntry log = cache.getLog(logN); String msg = (String)log.getField(LogField.LOGMESSAGE); msg=msg.replaceFirst("Test",""); Integer pos = Integer.parseInt(msg); returned[pos-1]=true; } // Compare the expected array (b) with the returned values (returned) for (int t=0; t<b.length; t++) { assertEquals("The log "+t+" is/isn't in the Collection of logs",b[t],returned[t]); } } public void testGetFirstLog() throws Exception { Integer firstLog = cache.getFirstLog(); assertEquals("The key of the first log is wrong",firstLog,new Integer(0)); } public void testGetLastLog() throws Exception { Integer lastLog=cache.getLastLog(); assertEquals("The key of the last log is wrong",lastLog,new Integer((int)logsGenerated-1)); } public void testGetLogs() throws Exception { ArrayList<Integer> keys = new ArrayList<Integer>(); int n = cache.getFirstLogs(1024,keys); assertEquals("Wrong number of keys",1024,n); for (Integer t=0; t<1024; t++) { assertEquals("Wrong key",t,keys.get(t)); } } /** * Test the keys returned by keyset * * @throws Exception */ public void testKeySet() throws Exception { // Check the number of the keys assertEquals("The logs in cache and the number of keys differ",cache.getSize(),cache.keySet().size()); // Get all the logs with the keys returned by keySet Set<Integer> keys = cache.keySet(); for (Integer key: keys) { ILogEntry log = cache.getLog(key); assertNotNull("Got a null log!",log); } } }