1   package ch.qos.logback.classic.spi;
2   
3   import static org.junit.Assert.assertEquals;
4   import static org.junit.Assert.assertNotNull;
5   import static org.junit.Assert.assertNull;
6   
7   import java.io.ByteArrayInputStream;
8   import java.io.ByteArrayOutputStream;
9   import java.io.IOException;
10  import java.io.ObjectInputStream;
11  import java.io.ObjectOutputStream;
12  import java.util.Map;
13  
14  import org.junit.After;
15  import org.junit.Before;
16  import org.junit.Test;
17  import org.slf4j.MDC;
18  
19  import ch.qos.logback.classic.Level;
20  import ch.qos.logback.classic.Logger;
21  import ch.qos.logback.classic.LoggerContext;
22  
23  public class LoggingEventSerializationTest {
24  
25    LoggerContext lc;
26    Logger logger;
27  
28    ByteArrayOutputStream bos;
29    ObjectOutputStream oos;
30    ObjectInputStream inputStream;
31  
32    @Before
33    public void setUp() throws Exception {
34      lc = new LoggerContext();
35      lc.setName("testContext");
36      logger = lc.getLogger(LoggerContext.ROOT_NAME);
37      // create the byte output stream
38      bos = new ByteArrayOutputStream();
39      oos = new ObjectOutputStream(bos);
40    }
41  
42    @After
43    public void tearDown() throws Exception {
44      lc = null;
45      logger = null;
46      oos.close();
47    }
48  
49    @Test
50    public void smoke() throws Exception {
51      LoggingEvent event = createLoggingEvent();
52      LoggingEvent remoteEvent = writeAndRead(event);
53      checkForEquality(event, remoteEvent);
54    }
55  
56    @Test
57    public void context() throws Exception {
58      lc.putProperty("testKey", "testValue");
59      LoggingEvent event = createLoggingEvent();
60      LoggingEvent remoteEvent = writeAndRead(event);
61      checkForEquality(event, remoteEvent);
62  
63      LoggerRemoteView loggerRemoteView = remoteEvent.getLoggerRemoteView();
64      assertNotNull(loggerRemoteView);
65      assertEquals("root", loggerRemoteView.getName());
66  
67      LoggerContextRemoteView loggerContextRemoteView = loggerRemoteView
68          .getLoggerContextView();
69      assertNotNull(loggerContextRemoteView);
70      assertEquals("testContext", loggerContextRemoteView.getName());
71      Map<String, String> props = loggerContextRemoteView.getPropertyMap();
72      assertNotNull(props);
73      assertEquals("testValue", props.get("testKey"));
74    }
75  
76    @Test
77    public void MDC() throws Exception {
78      MDC.put("key", "testValue");
79      LoggingEvent event = createLoggingEvent();
80      LoggingEvent remoteEvent = writeAndRead(event);
81      checkForEquality(event, remoteEvent);
82      Map<String, String> MDCPropertyMap = remoteEvent.getMDCPropertyMap();
83      assertEquals("testValue", MDCPropertyMap.get("key"));
84    }
85  
86    @Test
87    public void updatedMDC() throws Exception {
88      MDC.put("key", "testValue");
89      LoggingEvent event1 = createLoggingEvent();
90      oos.writeObject(event1);
91  
92      MDC.put("key", "updatedTestValue");
93      LoggingEvent event2 = createLoggingEvent();
94      oos.writeObject(event2);
95  
96      // create the input stream based on the ouput stream
97      ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
98      inputStream = new ObjectInputStream(bis);
99  
100     // skip over one object
101     inputStream.readObject();
102     LoggingEvent remoteEvent2 = (LoggingEvent) inputStream.readObject();
103 
104     // We observe the second logging event. It should provide us with
105     // the updated MDC property.
106     Map<String, String> MDCPropertyMap = remoteEvent2.getMDCPropertyMap();
107     assertEquals("updatedTestValue", MDCPropertyMap.get("key"));
108   }
109 
110   @Test
111   public void nonSerializableParameters() throws Exception {
112     LoggingEvent event = createLoggingEvent();
113     LuckyCharms lucky0 = new LuckyCharms(0);
114     event.setArgumentArray(new Object[] { lucky0, null });
115     LoggingEvent remoteEvent = writeAndRead(event);
116     checkForEquality(event, remoteEvent);
117     
118     Object[] aa = remoteEvent.getArgumentArray();
119     assertNotNull(aa);
120     assertEquals(2, aa.length);
121     assertEquals("LC(0)", aa[0]);
122     assertNull(aa[1]);
123   }
124 
125   @Test
126   public void _Throwable() throws Exception {
127     LoggingEvent event = createLoggingEvent();
128     Throwable throwable = new Throwable("just testing");
129     ThrowableProxy tp = new ThrowableProxy(throwable);
130     event.setThrowableProxy(tp);
131     LoggingEvent remoteEvent = writeAndRead(event);
132     checkForEquality(event, remoteEvent);
133   }
134 
135   @Test
136   public void extendendeThrowable() throws Exception {
137     LoggingEvent event = createLoggingEvent();
138     Throwable throwable = new Throwable("just testing");
139     ThrowableProxy tp = new ThrowableProxy(throwable);
140     event.setThrowableProxy(tp);
141     tp.calculatePackagingData();
142 
143     LoggingEvent remoteEvent = writeAndRead(event);
144     checkForEquality(event, remoteEvent);
145   }
146   
147   
148   @Test
149   public void serializeLargeArgs() throws Exception {
150     
151     StringBuffer buffer = new StringBuffer();
152     for (int i = 0; i < 100000; i++) {
153       buffer.append("X");
154     }
155     String largeString = buffer.toString();
156     Object[] argArray = new Object[] {new LuckyCharms(2),
157         largeString };
158     
159     LoggingEvent event = createLoggingEvent();
160     event.setArgumentArray(argArray);
161     
162     LoggingEvent remoteEvent = writeAndRead(event);
163     checkForEquality(event, remoteEvent);
164     Object[] aa = remoteEvent.getArgumentArray();
165     assertNotNull(aa);
166     assertEquals(2, aa.length);
167     String stringBack = (String) aa[1];
168     assertEquals(largeString, stringBack);
169   }
170 
171   private LoggingEvent createLoggingEvent() {
172     LoggingEvent le = new LoggingEvent(this.getClass().getName(), logger,
173         Level.DEBUG, "test message", null, null);
174     return le;
175   }
176 
177   private void checkForEquality(LoggingEvent original,
178       LoggingEvent afterSerialization) {
179     assertEquals(original.getLevel(), afterSerialization.getLevel());
180     assertEquals(original.getFormattedMessage(), afterSerialization
181         .getFormattedMessage());
182     assertEquals(original.getMessage(), afterSerialization.getMessage());
183     
184     System.out.println();
185     
186     assertEquals(original.getThrowableProxy(), afterSerialization
187         .getThrowableProxy());
188 
189   }
190 
191   private LoggingEvent writeAndRead(LoggingEvent event) throws IOException,
192       ClassNotFoundException {
193     oos.writeObject(event);
194     ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
195     inputStream = new ObjectInputStream(bis);
196 
197     return (LoggingEvent) inputStream.readObject();
198   }
199 
200 }