1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.classic;
15
16 import java.io.ByteArrayInputStream;
17 import java.io.ByteArrayOutputStream;
18 import java.io.FileInputStream;
19 import java.io.IOException;
20 import java.io.ObjectOutputStream;
21 import java.util.ArrayList;
22 import java.util.List;
23
24 import org.junit.jupiter.api.AfterEach;
25 import org.junit.jupiter.api.BeforeEach;
26 import org.junit.jupiter.api.Test;
27 import org.slf4j.LoggerFactory;
28
29 import ch.qos.logback.classic.net.server.HardenedLoggingEventInputStream;
30 import ch.qos.logback.core.net.HardenedObjectInputStream;
31 import ch.qos.logback.core.testUtil.CoreTestConstants;
32
33 import static org.junit.jupiter.api.Assertions.assertEquals;
34 import static org.junit.jupiter.api.Assertions.assertTrue;
35
36 public class LoggerSerializationTest {
37
38 static final String SERIALIZATION_PREFIX = CoreTestConstants.TEST_INPUT_PREFIX + "/serialization/";
39
40
41 org.slf4j.Logger unused = LoggerFactory.getLogger(this.getClass());
42 LoggerContext lc;
43 Logger logger;
44
45 ByteArrayOutputStream bos;
46 ObjectOutputStream oos;
47 HardenedLoggingEventInputStream hardenedLoggingEventInputStream;
48 List<String> whitelist = new ArrayList<String>();
49
50 @BeforeEach
51 public void setUp() throws Exception {
52 lc = new LoggerContext();
53 lc.setName("testContext");
54 logger = lc.getLogger(LoggerSerializationTest.class);
55
56 bos = new ByteArrayOutputStream();
57 oos = new ObjectOutputStream(bos);
58 whitelist.add(Foo.class.getName());
59 }
60
61 @AfterEach
62 public void tearDown() throws Exception {
63 lc = null;
64 logger = null;
65 }
66
67 @Test
68 public void basicSerialization() throws IOException, ClassNotFoundException {
69 Foo foo = new Foo(logger);
70 foo.doFoo();
71 Foo fooBack = writeAndRead(foo);
72 fooBack.doFoo();
73 }
74
75 @Test
76 public void deepTreeSerialization() throws IOException {
77
78 Logger a = lc.getLogger("aaaaaaaa");
79 lc.getLogger("aaaaaaaa.a");
80 lc.getLogger("aaaaaaaa.a.a");
81 lc.getLogger("aaaaaaaa.a.b");
82 lc.getLogger("aaaaaaaa.a.c");
83 lc.getLogger("aaaaaaaa.a.d");
84
85 lc.getLogger("aaaaaaaa.b");
86 lc.getLogger("aaaaaaaa.b.a");
87 lc.getLogger("aaaaaaaa.b.b");
88 lc.getLogger("aaaaaaaa.b.c");
89 lc.getLogger("aaaaaaaa.b.d");
90
91 lc.getLogger("aaaaaaaa.c");
92 lc.getLogger("aaaaaaaa.c.a");
93 lc.getLogger("aaaaaaaa.c.b");
94 lc.getLogger("aaaaaaaa.c.c");
95 lc.getLogger("aaaaaaaa.c.d");
96
97 lc.getLogger("aaaaaaaa.d");
98 lc.getLogger("aaaaaaaa.d.a");
99 lc.getLogger("aaaaaaaa.d.b");
100 lc.getLogger("aaaaaaaa.d.c");
101 lc.getLogger("aaaaaaaa.d.d");
102
103 Logger b = lc.getLogger("b");
104
105 writeObject(oos, a);
106 oos.close();
107 int sizeA = bos.size();
108
109 bos = new ByteArrayOutputStream();
110 oos = new ObjectOutputStream(bos);
111
112 writeObject(oos, b);
113 oos.close();
114 int sizeB = bos.size();
115
116 assertTrue(sizeA < 100, "serialized logger should be less than 100 bytes");
117
118 assertTrue((sizeA - sizeB) < 10,
119 "serialized loggers should be nearly the same size a:" + sizeA + ", sizeB:" + sizeB);
120 }
121
122 private Foo writeAndRead(Foo foo) throws IOException, ClassNotFoundException {
123 writeObject(oos, foo);
124 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
125 hardenedLoggingEventInputStream = new HardenedLoggingEventInputStream(bis, whitelist);
126 Foo fooBack = readFooObject(hardenedLoggingEventInputStream);
127 hardenedLoggingEventInputStream.close();
128 return fooBack;
129 }
130
131 Foo readFooObject(HardenedObjectInputStream inputStream) throws IOException, ClassNotFoundException {
132 return (Foo) readObject(inputStream);
133 }
134
135 private Object readObject(HardenedObjectInputStream inputStream) throws IOException, ClassNotFoundException {
136 return inputStream.readObject();
137 }
138
139 private void writeObject(ObjectOutputStream oos, Object o) throws IOException {
140 oos.writeObject(o);
141 oos.flush();
142 oos.close();
143 }
144
145 @Test
146 public void testCompatibilityWith_v1_0_11() throws IOException, ClassNotFoundException {
147 FileInputStream fis = new FileInputStream(SERIALIZATION_PREFIX + "logger_v1.0.11.ser");
148 HardenedObjectInputStream ois = new HardenedLoggingEventInputStream(fis);
149
150
151 Logger a = (Logger) ois.readObject();
152 ois.close();
153 assertEquals("a", a.getName());
154 }
155
156
157
158
159
160
161 @Test
162 public void testCompatibilityWith_v1_0_12() throws IOException, ClassNotFoundException {
163 FileInputStream fis = new FileInputStream(SERIALIZATION_PREFIX + "logger_v1.0.12.ser");
164 HardenedObjectInputStream ois = new HardenedObjectInputStream(fis, new String[]{Logger.class.getName()});
165 Logger a = (Logger) ois.readObject();
166 ois.close();
167 assertEquals("a", a.getName());
168 }
169
170 }