/*
* 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.text.FieldPosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Random;
import java.util.Vector;
import com.cosylab.logging.engine.log.ILogEntry;
import com.cosylab.logging.engine.log.LogTypeHelper;
import alma.acs.logging.engine.parser.ACSLogParser;
import alma.acs.logging.engine.parser.ACSLogParserFactory;
import alma.acs.util.IsoDateFormat;
/**
* A collection of methods to be used in the tests
*
* @author acaproni
*
*/
public class CacheUtils {
// The header and footer to create log to fill the caches
public static final String logHeaderStr = " TimeStamp=\"";
public static final String logBodyStr = "\" Routine=\"CacheTest::testGet\" Host=\"this\" Process=\"test\" Thread=\"main\" Context=\"\"><![CDATA[";
public static final String logFooterStr = "]]></";
// The parser
private static ACSLogParser parser;
/**
* Generate a random collection of keys.
*
* The size of the collection can be random or fixed.
* If it is random then the exact parameter must be false; in that case
* the number of elements returned is limited by size (inclusive)
* The number of elements in the collection is fixed if the exact parameter
* is true; in that case the number of elements returned is specified in size.
*
* If the size is random, the returned collection can be empty.
*
* If common is not null, each generated key must also be present in common.
* For this to work, the size of common is an upper limit for the size of the
* returned collection.
*
* @param size The upper limit of the number of elements in the collection
* or the number of elements in the returned collection depending
* on the value of the exact parameter
* @param exact If true the size of the returned collection is equal to
* size otherwise size is the maximum limit
* @param minValue The minimum allowed value of the keys in the collection (inclusive)
* @param maxValue The maximum allowed value of the keys in the collection (inclusive)
* @param common A collection of keys
* They key in the returned collection must be present
* in common too
* If common is null the keys are generated without constraints
* @return A posible empty collection of keys
*/
public static Collection<Integer> generateKeys(
int size,
boolean exact,
int minValue,
int maxValue,
Collection<Integer> common) {
if (size<=0) {
throw new IllegalArgumentException("Invalid size");
}
if (minValue<0 && maxValue<0) {
throw new IllegalArgumentException("Illegal min/max value below 0");
}
if (minValue>=maxValue) {
throw new IllegalArgumentException("minValue greater or equal to maxValue");
}
if (exact && size>common.size()) {
throw new IllegalArgumentException("Impossible to generate the keys against the passed collection");
}
int desiredLength=0;
Random rnd = new Random(System.currentTimeMillis());
if (!exact) {
// size is an upper limit (inclusive)
while (desiredLength==0) {
desiredLength=rnd.nextInt(size+1);
}
} else {
desiredLength=size;
}
if (maxValue-minValue+1<desiredLength) {
throw new IllegalArgumentException("Conflict between params: impossible to generate the keys with the given min/max");
}
Vector<Integer> v = new Vector<Integer>(desiredLength);
if (desiredLength==common.size()) {
// we have to return a collection with the same elements
// contained in common
for (Integer key: common) {
v.add(key);
}
} else {
Integer key=-1;
while (v.size()<desiredLength) {
// Generate the new key
while (key<minValue || key>maxValue) {
key = rnd.nextInt(maxValue+1);
if ((common!=null && !common.contains(key)) || v.contains(key)) {
key=-1;
}
}
v.add(key);
key=-1;
}
}
return v;
}
/**
* Generate a set of logs to be used for testing
* Each log has
* - a different time stamp.
* - the message contains the key of the log
* - the log type is random (all types but Trace because trace
* has no body)
*
* @param numOfLogs The number of logs to put in the collection
* @return The collection with the logs
*/
public static Collection<ILogEntry> generateLogs(int numOfLogs) throws Exception {
Random rnd = new Random(Calendar.getInstance().getTimeInMillis());
long now = Calendar.getInstance().getTimeInMillis()-1000*60*60*24; // Yesterday
SimpleDateFormat df = new IsoDateFormat();
Vector<ILogEntry> v = new Vector<ILogEntry>(numOfLogs);
for (int t=0; t<numOfLogs; t++) {
Date dt = new Date(now+t*1000);
StringBuffer dateSB = new StringBuffer();
FieldPosition pos = new FieldPosition(0);
df.format(dt,dateSB,pos);
StringBuilder logStr = new StringBuilder("<");
int typePos = rnd.nextInt(LogTypeHelper.values().length-1);
LogTypeHelper type = LogTypeHelper.values()[typePos];
if (type==LogTypeHelper.TRACE) {
type=LogTypeHelper.INFO;
}
logStr.append(type.logEntryType);
logStr.append(logHeaderStr);
logStr.append(dateSB.toString());
logStr.append(logBodyStr);
logStr.append(t);
logStr.append(logFooterStr);
logStr.append(type.logEntryType);
logStr.append('>');
if (parser==null) {
parser = ACSLogParserFactory.getParser();
}
ILogEntry log = parser.parse(logStr.toString());
v.add(log);
}
return v;
}
/**
* Generate a set of logs of a given type
* Each log has
* - a different time stamp.
* - the message contains the key of the log
*
* @param numOfLogs The number of logs to put in the collection
* @return The collection with the logs
*/
public static Collection<ILogEntry> generateLogsType(int numOfLogs, LogTypeHelper logType) throws Exception {
if (logType==LogTypeHelper.OFF) {
throw new IllegalArgumentException("Cannot publish logs with level OFF");
}
Random rnd = new Random(Calendar.getInstance().getTimeInMillis());
long now = Calendar.getInstance().getTimeInMillis()-1000*60*60*24; // Yesterday
SimpleDateFormat df = new IsoDateFormat();
Vector<ILogEntry> v = new Vector<ILogEntry>(numOfLogs);
for (int t=0; t<numOfLogs; t++) {
Date dt = new Date(now+t*1000);
StringBuffer dateSB = new StringBuffer();
FieldPosition pos = new FieldPosition(0);
df.format(dt,dateSB,pos);
StringBuilder logStr = new StringBuilder("<");
if (logType==LogTypeHelper.TRACE) {
logType=LogTypeHelper.INFO;
}
logStr.append(logType.logEntryType);
logStr.append(logHeaderStr);
logStr.append(dateSB.toString());
logStr.append(logBodyStr);
logStr.append(t);
logStr.append(logFooterStr);
logStr.append(logType.logEntryType);
logStr.append('>');
if (parser==null) {
parser = ACSLogParserFactory.getParser();
}
ILogEntry log = parser.parse(logStr.toString());
v.add(log);
}
return v;
}
}