package org.marketcetera.util.test;
import java.util.NoSuchElementException;
import org.apache.commons.lang.SystemUtils;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;
import static org.junit.Assert.*;
/**
* A log message test helper.
*
* @author tlerios@marketcetera.com
* @author anshul@marketcetera.com
* @since 2.0.0
* @version $Id: LogTestAssist.java 16154 2012-07-14 16:34:05Z colin $
*/
/* $License$ */
public class LogTestAssist
{
// INSTANCE DATA.
private final MemoryAppender mAppender=
new MemoryAppender();
// CONSTRUCTORS.
/**
* Creates a new helper which tracks the log events sent out to
* the logger with the given name at the given optional threshold
* level.
*
* @param name The logger name.
* @param level The level. It may be null, in which case logger's
* threshold level is not altered.
*/
public LogTestAssist
(String name,
Level level)
{
trackLogger(name,level);
}
/**
* Creates a new helper which tracks the log events sent out to
* the logger with the given name.
*
* @param name The logger name.
*/
public LogTestAssist
(String name)
{
this(name,null);
}
/**
* Creates a new helper which doesn't track any logger output. The
* helper can be configured to track logger output using {@link
* #trackLogger(String,org.apache.log4j.Level)}.
*/
public LogTestAssist() {}
// CLASS METHODS.
/**
* Sets the level of the root logger to the given level.
*
* @param level The level.
*/
public static void setDefaultLevel
(Level level)
{
Logger.getRootLogger().setLevel(level);
}
/**
* Sets the level of the logger with the given name to the given
* level.
*
* @param name The logger name.
* @param level The level.
*/
public static void setLevel
(String name,
Level level)
{
Logger.getLogger(name).setLevel(level);
}
/**
* Asserts that the contents of the given event match the given
* expected level, logger name, message, and location.
*
* @param event The event.
* @param level The expected level. Use null to indicate "don't
* care".
* @param logger The expected logger name. Use null to indicate
* "don't care".
* @param message The expected message. Use null to indicate
* "don't care".
* @param location The expected location. Use null to indicate
* "don't care".
*/
public static void assertEvent
(LoggingEvent event,
Level level,
String logger,
String message,
String location)
{
if (level!=null) {
assertEquals(level,event.getLevel());
}
if (logger!=null) {
assertEquals(logger,event.getLoggerName());
}
if (message!=null) {
assertEquals(message,event.getMessage());
}
if (location!=null) {
assertEquals
(location,event.getLocationInformation().getClassName());
}
}
// INSTANCE METHODS.
/**
* Starts tracking log events sent out to the logger with the
* given name at the given optional threshold level.
*
* @param name The logger name.
* @param level The level. It may be null, in which case logger's
* threshold level is not altered.
*/
public void trackLogger
(String name,
Level level)
{
Logger logger=Logger.getLogger(name);
logger.addAppender(getAppender());
if (level!=null) {
logger.setLevel(level);
}
}
/**
* Starts tracking log events sent out to the logger with the
* given name.
*
* @param name The logger name.
*/
public void trackLogger
(String name)
{
trackLogger(name,null);
}
/**
* Clears the contents of the receiver's collector.
*/
public void resetAppender()
{
getAppender().clear();
}
/**
* Returns a string with all the events of the receiver's
* collector.
*
* @return The string.
*/
public String getEventsAsString()
{
StringBuilder builder=new StringBuilder();
builder.append("Event count: "); //$NON-NLS-1$
builder.append(getAppender().getEvents().size());
int i=0;
for (LoggingEvent event:getAppender().getEvents()) {
builder.append(SystemUtils.LINE_SEPARATOR);
builder.append("Event "); //$NON-NLS-1$
builder.append(i++);
builder.append(": level: "); //$NON-NLS-1$
builder.append(event.getLevel());
builder.append("; logger: "); //$NON-NLS-1$
builder.append(event.getLoggerName());
builder.append("; message: "); //$NON-NLS-1$
builder.append(event.getMessage());
builder.append("; location: "); //$NON-NLS-1$
builder.append(event.getLocationInformation().getClassName());
}
return builder.toString();
}
/**
* Returns the receiver's collector (appender) of retained events.
*
* @return The appender.
*/
public MemoryAppender getAppender()
{
return mAppender;
}
/**
* Asserts that the receiver's collector contains the given number
* of events.
*
* @param count The number of events.
*/
public void assertEventCount
(int count)
{
if (getAppender().getEvents().size()==count) {
return;
}
StringBuilder builder=new StringBuilder();
builder.append("Incorrect event count; expected "); //$NON-NLS-1$
builder.append(count);
builder.append(" actual "); //$NON-NLS-1$
builder.append(SystemUtils.LINE_SEPARATOR);
builder.append(getEventsAsString());
fail(builder.toString());
}
/**
* Asserts that the receiver's collector contains no events.
*/
public void assertNoEvents()
{
assertEventCount(0);
}
/**
* Asserts that the contents of the receiver's collector's most
* recent event match the given expected level, logger name,
* message, and location. The assertion fails if the receiver has
* no events.
*
* @param level The expected level. Use null to indicate "don't
* care".
* @param logger The expected logger name. Use null to indicate
* "don't care".
* @param message The expected message. Use null to indicate
* "don't care".
* @param location The expected location. Use null to indicate
* "don't care".
*/
public void assertLastEvent
(Level level,
String logger,
String message,
String location)
{
LoggingEvent event=null;
try {
event=getAppender().getEvents().getLast();
} catch (NoSuchElementException ex) {
fail("List is empty"); //$NON-NLS-1$
}
assertEvent(event,level,logger,message,location);
}
/**
* Asserts that at least one of the receiver's collector's events
* matches the given expected level, logger name, message, and
* location. If the collector has no events, the assertion fails.
*
* @param level The expected level. Use null to indicate "don't
* care".
* @param logger The expected logger name. Use null to indicate
* "don't care".
* @param message The expected message. Use null to indicate
* "don't care".
* @param location The expected location. Use null to indicate
* "don't care".
*/
public void assertSomeEvent
(Level level,
String logger,
String message,
String location)
{
for (LoggingEvent event:getAppender().getEvents()) {
if (((level==null) ||
level.equals(event.getLevel())) &&
((logger==null) ||
logger.equals(event.getLoggerName())) &&
((message==null) ||
message.equals(event.getMessage())) &&
((location==null) ||
location.equals
(event.getLocationInformation().getClassName()))) {
return;
}
}
fail("No matches against given event. Events are:"+ //$NON-NLS-1$
SystemUtils.LINE_SEPARATOR+
getEventsAsString());
}
/**
* Asserts that the receiver's collector contains a single event,
* and that its contents match the given expected level, logger
* name, message, and location. The collector's list of retained
* events is cleared upon success.
*
* @param level The expected level. Use null to indicate "don't
* care".
* @param logger The expected logger name. Use null to indicate
* "don't care".
* @param message The expected message. Use null to indicate
* "don't care".
* @param location The expected location. Use null to indicate
* "don't care".
*/
public void assertSingleEvent
(Level level,
String logger,
String message,
String location)
{
assertEventCount(1);
assertLastEvent(level,logger,message,location);
resetAppender();
}
}