1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.core.rolling;
15
16 import java.io.File;
17 import java.io.IOException;
18 import java.nio.file.Files;
19 import java.nio.file.Paths;
20 import java.text.SimpleDateFormat;
21 import java.util.Date;
22 import java.util.List;
23 import java.util.concurrent.ExecutionException;
24 import java.util.function.UnaryOperator;
25
26 import ch.qos.logback.core.CoreConstants;
27 import ch.qos.logback.core.util.CachingDateFormatter;
28 import ch.qos.logback.core.util.Duration;
29 import ch.qos.logback.core.util.StatusPrinter;
30 import org.junit.jupiter.api.BeforeEach;
31 import org.junit.jupiter.api.Test;
32
33 import ch.qos.logback.core.encoder.EchoEncoder;
34 import ch.qos.logback.core.rolling.testUtil.ScaffoldingForRollingTests;
35 import ch.qos.logback.core.status.InfoStatus;
36 import ch.qos.logback.core.status.StatusManager;
37 import ch.qos.logback.core.status.testUtil.StatusChecker;
38 import ch.qos.logback.core.util.FileSize;
39
40 import static org.junit.jupiter.api.Assertions.assertEquals;
41 import static org.junit.jupiter.api.Assertions.assertFalse;
42
43 public class SizeAndTimeBasedFNATP_Test extends ScaffoldingForRollingTests {
44 private SizeAndTimeBasedFileNamingAndTriggeringPolicy<Object> sizeAndTimeBasedFNATP = null;
45 private RollingFileAppender<Object> rfa1 = new RollingFileAppender<Object>();
46 private TimeBasedRollingPolicy<Object> tbrp1 = new TimeBasedRollingPolicy<Object>();
47 private RollingFileAppender<Object> rfa2 = new RollingFileAppender<Object>();
48 private TimeBasedRollingPolicy<Object> tbrp2 = new TimeBasedRollingPolicy<Object>();
49
50 private EchoEncoder<Object> encoder = new EchoEncoder<Object>();
51 int fileSize = 0;
52 int fileIndexCounter = 0;
53 int sizeThreshold = 0;
54
55 @BeforeEach
56 public void setUp() {
57 super.setUp();
58 }
59
60 private void initRollingFileAppender(RollingFileAppender<Object> rfa, String filename) {
61 rfa.setContext(context);
62 rfa.setEncoder(encoder);
63 if (filename != null) {
64 rfa.setFile(filename);
65 }
66 }
67
68 private void initPolicies(RollingFileAppender<Object> rfa, TimeBasedRollingPolicy<Object> tbrp,
69 String filenamePattern, int sizeThreshold, long givenTime, long lastCheck) {
70 sizeAndTimeBasedFNATP = new SizeAndTimeBasedFileNamingAndTriggeringPolicy<Object>();
71 sizeAndTimeBasedFNATP.setContext(context);
72 sizeAndTimeBasedFNATP.setCheckIncrement(Duration.buildByMilliseconds(10));
73 tbrp.setContext(context);
74 sizeAndTimeBasedFNATP.setMaxFileSize(new FileSize(sizeThreshold));
75 tbrp.setTimeBasedFileNamingAndTriggeringPolicy(sizeAndTimeBasedFNATP);
76 tbrp.setFileNamePattern(filenamePattern);
77 tbrp.setParent(rfa);
78 tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(givenTime);
79 rfa.setRollingPolicy(tbrp);
80 tbrp.start();
81 rfa.start();
82 }
83
84 private void addExpectedFileNamedIfItsTime(String randomOutputDir, String testId, String msg,
85 String compressionSuffix) {
86 fileSize = fileSize + msg.getBytes().length;
87 if (passThresholdTime(nextRolloverThreshold)) {
88 fileIndexCounter = 0;
89 fileSize = 0;
90 addExpectedFileName_ByFileIndexCounter(randomOutputDir, testId, getMillisOfCurrentPeriodsStart(),
91 fileIndexCounter, compressionSuffix);
92 recomputeRolloverThreshold(currentTime);
93 return;
94 }
95
96
97 if ((fileIndexCounter == 0) && fileSize > sizeThreshold) {
98 addExpectedFileName_ByFileIndexCounter(randomOutputDir, testId, getMillisOfCurrentPeriodsStart(),
99 fileIndexCounter, compressionSuffix);
100 fileIndexCounter = fileIndexCounter + 1;
101 fileSize = 0;
102 }
103 }
104
105 void generic(String testId, UnaryOperator<String> filenameFunction, boolean withSecondPhase,
106 String compressionSuffix) throws IOException, InterruptedException, ExecutionException {
107 String file = filenameFunction.apply(testId);
108 initRollingFileAppender(rfa1, file);
109 sizeThreshold = 300;
110
111 initPolicies(rfa1, tbrp1,
112 randomOutputDir + testId + "-%d{" + DATE_PATTERN_WITH_SECONDS + "}-%i.txt" + compressionSuffix,
113 sizeThreshold, currentTime, 0);
114 addExpectedFileName_ByFileIndexCounter(randomOutputDir, testId, getMillisOfCurrentPeriodsStart(),
115 fileIndexCounter, compressionSuffix);
116 incCurrentTime(100);
117 tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
118 int runLength = 100;
119 String prefix = "Hello -----------------";
120
121 for (int i = 0; i < runLength; i++) {
122 String msg = prefix + i;
123 rfa1.doAppend(msg);
124 addExpectedFileNamedIfItsTime(randomOutputDir, testId, msg, compressionSuffix);
125 incCurrentTime(20);
126 tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
127 add(tbrp1.compressionFuture);
128 add(tbrp1.cleanUpFuture);
129 }
130
131 if (withSecondPhase) {
132 secondPhase(testId, filenameFunction, compressionSuffix, runLength, prefix);
133 runLength = runLength * 2;
134 }
135
136 if (file != null)
137 massageExpectedFilesToCorresponToCurrentTarget(testId, this::testId2FileName);
138
139 Thread.yield();
140
141 waitForJobsToComplete();
142
143
144 existenceCheck(expectedFilenameList);
145 sortedContentCheck(randomOutputDir, runLength, prefix);
146 }
147
148 void secondPhase(String testId, UnaryOperator<String> filenameFunction, String compressionSuffix, int runLength,
149 String prefix) {
150 rfa1.stop();
151
152 String filename = filenameFunction.apply(testId);
153 if (filename != null) {
154 File f = new File(filename);
155 f.setLastModified(currentTime);
156 }
157
158 StatusManager sm = context.getStatusManager();
159 sm.add(new InfoStatus("Time when rfa1 is stopped: " + new Date(currentTime), this));
160 sm.add(new InfoStatus("currentTime%1000=" + (currentTime % 1000), this));
161
162 initRollingFileAppender(rfa2, filename);
163 initPolicies(rfa2, tbrp2,
164 randomOutputDir + testId + "-%d{" + DATE_PATTERN_WITH_SECONDS + "}-%i.txt" + compressionSuffix,
165 sizeThreshold, currentTime, 0);
166
167 for (int i = runLength; i < runLength * 2; i++) {
168 incCurrentTime(100);
169 tbrp2.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
170 String msg = prefix + i;
171 rfa2.doAppend(msg);
172 addExpectedFileNamedIfItsTime(randomOutputDir, testId, msg, compressionSuffix);
173 }
174 }
175
176 static final boolean FIRST_PHASE_ONLY = false;
177 static final boolean WITH_SECOND_PHASE = true;
178 static final String DEFAULT_COMPRESSION_SUFFIX = "";
179
180 @Test
181 public void noCompression_FileSet_NoRestart_1() throws InterruptedException, ExecutionException, IOException {
182 generic("test1", this::testId2FileName, FIRST_PHASE_ONLY, DEFAULT_COMPRESSION_SUFFIX);
183 }
184
185 @Test
186 public void noCompression_FileBlank_NoRestart_2() throws Exception {
187 generic("test2", this::nullFileName, FIRST_PHASE_ONLY, DEFAULT_COMPRESSION_SUFFIX);
188 }
189
190 @Test
191 public void noCompression_FileBlank_WithStopStart_3() throws Exception {
192 generic("test3", this::nullFileName, WITH_SECOND_PHASE, DEFAULT_COMPRESSION_SUFFIX);
193 }
194
195 @Test
196 public void noCompression_FileSet_WithStopStart_4() throws Exception {
197 generic("test4", this::testId2FileName, WITH_SECOND_PHASE, DEFAULT_COMPRESSION_SUFFIX);
198 }
199
200 @Test
201 public void withGZCompression_FileSet_NoRestart_5() throws Exception {
202 generic("test5", this::testId2FileName, FIRST_PHASE_ONLY, ".gz");
203 }
204
205 @Test
206 public void withGZCompression_FileBlank_NoRestart_6() throws Exception {
207 generic("test6", this::nullFileName, FIRST_PHASE_ONLY, ".gz");
208 }
209
210 @Test
211 public void withZipCompression_FileSet_NoRestart_7() throws Exception {
212 generic("test7", this::testId2FileName, FIRST_PHASE_ONLY, ".zip");
213 List<String> zipFiles = filterElementsInListBySuffix(".zip");
214 checkZipEntryMatchesZipFilename(zipFiles);
215 }
216
217 @Test
218 public void checkMissingIntToken() {
219 String stem = "toto.log";
220 String testId = "checkMissingIntToken";
221 String compressionSuffix = "gz";
222
223 String file = (stem != null) ? randomOutputDir + stem : null;
224 initRollingFileAppender(rfa1, file);
225 sizeThreshold = 300;
226 initPolicies(rfa1, tbrp1,
227 randomOutputDir + testId + "-%d{" + DATE_PATTERN_WITH_SECONDS + "}.txt" + compressionSuffix,
228 sizeThreshold, currentTime, 0);
229
230
231 assertFalse(rfa1.isStarted());
232 StatusChecker checker = new StatusChecker(context);
233 checker.assertContainsMatch("Missing integer token");
234 }
235
236 @Test
237 public void checkDateCollision() {
238 String stem = "toto.log";
239 String testId = "checkDateCollision";
240 String compressionSuffix = "gz";
241
242 String file = (stem != null) ? randomOutputDir + stem : null;
243 initRollingFileAppender(rfa1, file);
244 sizeThreshold = 300;
245 initPolicies(rfa1, tbrp1, randomOutputDir + testId + "-%d{EE}.txt" + compressionSuffix, sizeThreshold,
246 currentTime, 0);
247
248
249 assertFalse(rfa1.isStarted());
250 StatusChecker checker = new StatusChecker(context);
251 checker.assertContainsMatch("The date format in FileNamePattern");
252 }
253
254 @Test
255 public void checkInitialFileSize_withFile() throws IOException {
256 String stem = "foo.log";
257 String testId = "checkDateCollision";
258 String fixedContent = "Hello world";
259 byte[] fixedContentBytes = fixedContent.getBytes();
260
261 String fileProperty = randomOutputDir + stem;
262 Files.createDirectories(Paths.get(randomOutputDir));
263 Files.write(Paths.get(fileProperty), fixedContentBytes);
264
265 initRollingFileAppender(rfa1, fileProperty);
266 sizeThreshold = 300;
267 initPolicies(rfa1, tbrp1, randomOutputDir + testId + "-%d-%i.txt", sizeThreshold,
268 currentTime, 0);
269
270
271
272 assertEquals(fixedContentBytes.length, tbrp1.getLengthCounter().getLength());
273 }
274
275
276 @Test
277 public void checkInitialFileSize_withoutFile() throws IOException {
278 String testId = "checkInitialFileSize_withoutFile";
279 String fixedContent = "Hello world";
280 byte[] fixedContentBytes = fixedContent.getBytes();
281
282
283 CachingDateFormatter cdf = new CachingDateFormatter(CoreConstants.DAILY_DATE_PATTERN);
284 String nowString = cdf.format(currentTime);
285 String pathToFirstFile = randomOutputDir + testId + "-"+nowString+"-0.txt";
286
287 Files.createDirectories(Paths.get(randomOutputDir));
288 Files.write(Paths.get(pathToFirstFile), fixedContentBytes);
289
290
291 initRollingFileAppender(rfa1, null);
292 sizeThreshold = 300;
293 initPolicies(rfa1, tbrp1, randomOutputDir + testId + "-%d-%i.txt", sizeThreshold,
294 currentTime, 0);
295
296 StatusPrinter.print(context);
297
298 assertEquals(fixedContentBytes.length, tbrp1.getLengthCounter().getLength());
299 }
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332 }