/**
* Logback: the reliable, generic, fast and flexible logging framework.
* Copyright (C) 1999-2013, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
package ch.qos.logback.classic.spi;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.MDC;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.net.LoggingEventPreSerializationTransformer;
import ch.qos.logback.core.spi.PreSerializationTransformer;
public class LoggingEventSerializationTest {
LoggerContext lc;
Logger logger;
ByteArrayOutputStream bos;
ObjectOutputStream oos;
ObjectInputStream inputStream;
PreSerializationTransformer<ILoggingEvent> pst = new LoggingEventPreSerializationTransformer();
@Before
public void setUp() throws Exception {
lc = new LoggerContext();
lc.setName("testContext");
logger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
// create the byte output stream
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
}
@After
public void tearDown() throws Exception {
lc = null;
logger = null;
oos.close();
}
@Test
public void smoke() throws Exception {
ILoggingEvent event = createLoggingEvent();
ILoggingEvent remoteEvent = writeAndRead(event);
checkForEquality(event, remoteEvent);
}
@Test
public void context() throws Exception {
lc.putProperty("testKey", "testValue");
ILoggingEvent event = createLoggingEvent();
ILoggingEvent remoteEvent = writeAndRead(event);
checkForEquality(event, remoteEvent);
assertNotNull(remoteEvent.getLoggerName());
assertEquals(Logger.ROOT_LOGGER_NAME, remoteEvent.getLoggerName());
LoggerContextVO loggerContextRemoteView = remoteEvent.getLoggerContextVO();
assertNotNull(loggerContextRemoteView);
assertEquals("testContext", loggerContextRemoteView.getName());
Map<String, String> props = loggerContextRemoteView.getPropertyMap();
assertNotNull(props);
assertEquals("testValue", props.get("testKey"));
}
@Test
public void MDC() throws Exception {
MDC.put("key", "testValue");
ILoggingEvent event = createLoggingEvent();
ILoggingEvent remoteEvent = writeAndRead(event);
checkForEquality(event, remoteEvent);
Map<String, String> MDCPropertyMap = remoteEvent.getMDCPropertyMap();
assertEquals("testValue", MDCPropertyMap.get("key"));
}
@Test
public void updatedMDC() throws Exception {
MDC.put("key", "testValue");
ILoggingEvent event1 = createLoggingEvent();
Serializable s1 = pst.transform(event1);
oos.writeObject(s1);
MDC.put("key", "updatedTestValue");
ILoggingEvent event2 = createLoggingEvent();
Serializable s2 = pst.transform(event2);
oos.writeObject(s2);
// create the input stream based on the ouput stream
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
inputStream = new ObjectInputStream(bis);
// skip over one object
inputStream.readObject();
ILoggingEvent remoteEvent2 = (ILoggingEvent) inputStream.readObject();
// We observe the second logging event. It should provide us with
// the updated MDC property.
Map<String, String> MDCPropertyMap = remoteEvent2.getMDCPropertyMap();
assertEquals("updatedTestValue", MDCPropertyMap.get("key"));
}
@Test
public void nonSerializableParameters() throws Exception {
LoggingEvent event = createLoggingEvent();
LuckyCharms lucky0 = new LuckyCharms(0);
event.setArgumentArray(new Object[] { lucky0, null });
ILoggingEvent remoteEvent = writeAndRead(event);
checkForEquality(event, remoteEvent);
Object[] aa = remoteEvent.getArgumentArray();
assertNotNull(aa);
assertEquals(2, aa.length);
assertEquals("LC(0)", aa[0]);
assertNull(aa[1]);
}
@Test
public void _Throwable() throws Exception {
LoggingEvent event = createLoggingEvent();
Throwable throwable = new Throwable("just testing");
ThrowableProxy tp = new ThrowableProxy(throwable);
event.setThrowableProxy(tp);
ILoggingEvent remoteEvent = writeAndRead(event);
checkForEquality(event, remoteEvent);
}
@Test
public void extendendeThrowable() throws Exception {
LoggingEvent event = createLoggingEvent();
Throwable throwable = new Throwable("just testing");
ThrowableProxy tp = new ThrowableProxy(throwable);
event.setThrowableProxy(tp);
tp.calculatePackagingData();
ILoggingEvent remoteEvent = writeAndRead(event);
checkForEquality(event, remoteEvent);
}
@Test
public void serializeLargeArgs() throws Exception {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < 100000; i++) {
buffer.append("X");
}
String largeString = buffer.toString();
Object[] argArray = new Object[] { new LuckyCharms(2), largeString };
LoggingEvent event = createLoggingEvent();
event.setArgumentArray(argArray);
ILoggingEvent remoteEvent = writeAndRead(event);
checkForEquality(event, remoteEvent);
Object[] aa = remoteEvent.getArgumentArray();
assertNotNull(aa);
assertEquals(2, aa.length);
String stringBack = (String) aa[1];
assertEquals(largeString, stringBack);
}
private LoggingEvent createLoggingEvent() {
return new LoggingEvent(this.getClass().getName(), logger,
Level.DEBUG, "test message", null, null);
}
private void checkForEquality(ILoggingEvent original,
ILoggingEvent afterSerialization) {
assertEquals(original.getLevel(), afterSerialization.getLevel());
assertEquals(original.getFormattedMessage(), afterSerialization
.getFormattedMessage());
assertEquals(original.getMessage(), afterSerialization.getMessage());
System.out.println();
ThrowableProxyVO witness = ThrowableProxyVO.build(original
.getThrowableProxy());
assertEquals(witness, afterSerialization.getThrowableProxy());
}
private ILoggingEvent writeAndRead(ILoggingEvent event) throws IOException,
ClassNotFoundException {
Serializable ser = pst.transform(event);
oos.writeObject(ser);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
inputStream = new ObjectInputStream(bis);
return (ILoggingEvent) inputStream.readObject();
}
}