1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.core.rolling;
15
16 import static ch.qos.logback.core.CoreConstants.DAILY_DATE_PATTERN;
17 import static ch.qos.logback.core.CoreConstants.STRICT_ISO8601_PATTERN;
18 import static org.junit.jupiter.api.Assertions.assertEquals;
19 import static org.junit.jupiter.api.Assertions.assertTrue;
20 import java.io.File;
21 import java.io.FileFilter;
22 import java.time.Instant;
23 import java.time.LocalDateTime;
24 import java.time.ZoneId;
25 import java.time.ZonedDateTime;
26 import java.time.format.DateTimeFormatter;
27 import java.util.ArrayList;
28 import java.util.Calendar;
29 import java.util.Collections;
30 import java.util.Comparator;
31 import java.util.Date;
32 import java.util.HashSet;
33 import java.util.List;
34 import java.util.Set;
35 import java.util.stream.Stream;
36
37 import java.util.concurrent.atomic.LongAdder;
38 import java.util.regex.Matcher;
39 import java.util.regex.Pattern;
40 import java.time.temporal.ChronoUnit;
41
42 import ch.qos.logback.core.rolling.testUtil.ParentScaffoldingForRollingTests;
43 import ch.qos.logback.core.status.OnConsoleStatusListener;
44 import ch.qos.logback.core.util.StatusPrinter;
45 import org.junit.jupiter.api.BeforeEach;
46 import org.junit.jupiter.api.Disabled;
47 import org.junit.jupiter.api.Test;
48 import org.junit.jupiter.params.provider.MethodSource;
49 import org.junit.jupiter.params.ParameterizedTest;
50
51 import ch.qos.logback.core.CoreConstants;
52 import ch.qos.logback.core.pattern.SpacePadder;
53 import ch.qos.logback.core.rolling.helper.RollingCalendar;
54 import ch.qos.logback.core.status.testUtil.StatusChecker;
55 import ch.qos.logback.core.util.FileSize;
56 import ch.qos.logback.core.util.FixedRateInvocationGate;
57
58 public class TimeBasedRollingWithArchiveRemoval_Test extends ParentScaffoldingForRollingTests {
59 String MONTHLY_DATE_PATTERN = "yyyy-MM";
60 String MONTHLY_CRONOLOG_DATE_PATTERN = "yyyy/MM";
61 final String DAILY_CRONOLOG_DATE_PATTERN = "yyyy/MM/dd";
62
63 RollingFileAppender<Object> rfa = new RollingFileAppender<Object>();
64 TimeBasedRollingPolicy<Object> tbrp = new TimeBasedRollingPolicy<Object>();
65
66 DateTimeFormatter STRICT_DATE_PARSER = DateTimeFormatter.ofPattern(STRICT_ISO8601_PATTERN);
67
68
69
70
71 TimeBasedFileNamingAndTriggeringPolicy<Object> tbfnatp = new DefaultTimeBasedFileNamingAndTriggeringPolicy<Object>();
72
73 StatusChecker checker = new StatusChecker(context);
74
75 static long MILLIS_IN_MINUTE = 60 * 1000;
76 static long MILLIS_IN_HOUR = 60 * MILLIS_IN_MINUTE;
77 static long MILLIS_IN_DAY = 24 * MILLIS_IN_HOUR;
78 static long MILLIS_IN_MONTH = (long) ((365.242199 / 12) * MILLIS_IN_DAY);
79 static int MONTHS_IN_YEAR = 12;
80
81 public static final String DAILY_HOUR_PATTERN = "yyyy-MM-dd-HH";
82
83
84 static final long WED_2016_03_23_T_230705_CET = 1458770825333L;
85 static final long THU_2016_03_17_T_230330_CET = 1458252210975L;
86
87 int slashCount = 0;
88 int ticksPerPeriod = 216;
89
90 ConfigParameters cp;
91 FixedRateInvocationGate fixedRateInvocationGate = new FixedRateInvocationGate(ticksPerPeriod / 2);
92
93 @BeforeEach
94 public void setUp() {
95 super.setUp();
96 this.cp = new ConfigParameters(currentTime);
97 }
98
99 private int computeSlashCount(String datePattern) {
100 if (datePattern == null)
101 return 0;
102 else {
103 int count = 0;
104 for (int i = 0; i < datePattern.length(); i++) {
105 char c = datePattern.charAt(i);
106 if (c == '/')
107 count++;
108 }
109 return count;
110 }
111 }
112
113
114
115
116 @Test
117 public void monthlyRolloverOverManyPeriods() {
118 this.slashCount = computeSlashCount(MONTHLY_CRONOLOG_DATE_PATTERN);
119 int maxHistory = 2;
120 int simulatedNumberOfPeriods = 30;
121 String fileNamePattern = randomOutputDir + "/%d{" + MONTHLY_CRONOLOG_DATE_PATTERN + "}/clean.txt.zip";
122
123 cp.maxHistory(maxHistory).fileNamePattern(fileNamePattern).simulatedNumberOfPeriods(simulatedNumberOfPeriods)
124 .periodDurationInMillis(MILLIS_IN_MONTH);
125
126 long startTime = currentTime;
127 long endTime = logOverMultiplePeriods(cp);
128 System.out.println("randomOutputDir:" + randomOutputDir);
129 System.out.println("start:" + startTime + ", end=" + endTime);
130 int differenceInMonths = RollingCalendar.diffInMonths(startTime, endTime);
131 System.out.println("differenceInMonths:" + differenceInMonths);
132 Calendar startTimeAsCalendar = Calendar.getInstance();
133 startTimeAsCalendar.setTimeInMillis(startTime);
134 int indexOfStartPeriod = startTimeAsCalendar.get(Calendar.MONTH);
135 boolean withExtraFolder = extraFolder(differenceInMonths, MONTHS_IN_YEAR, indexOfStartPeriod, maxHistory);
136
137 checkFileCount(expectedCountWithFolders(maxHistory, withExtraFolder));
138 }
139
140 long generateDailyRollover(ConfigParameters cp) {
141 this.slashCount = computeSlashCount(DAILY_DATE_PATTERN);
142 cp.fileNamePattern(randomOutputDir + "clean-%d{" + DAILY_DATE_PATTERN + "}.txt");
143 return logOverMultiplePeriods(cp);
144 }
145
146 long generateDailyRolloverAndCheckFileCount(ConfigParameters cp) {
147 long millisAtEnd = generateDailyRollover(cp);
148 int periodBarriersCrossed = computeCrossedDayBarriers(currentTime, millisAtEnd);
149
150 checkFileCount(expectedCountWithoutFoldersWithInactivity(cp.maxHistory, periodBarriersCrossed,
151 cp.startInactivity + cp.numInactivityPeriods));
152 return millisAtEnd;
153 }
154
155 @Test
156 public void checkCrossedPeriodsWithDSTBarrier() {
157 long SAT_2016_03_26_T_230705_CET = WED_2016_03_23_T_230705_CET + 3 * CoreConstants.MILLIS_IN_ONE_DAY;
158 long MON_2016_03_28_T_000705_CET = SAT_2016_03_26_T_230705_CET + CoreConstants.MILLIS_IN_ONE_DAY;
159
160 long result = computeCrossedDayBarriers(SAT_2016_03_26_T_230705_CET, MON_2016_03_28_T_000705_CET, "CET");
161 assertEquals(2, result);
162 }
163
164 private int computeCrossedDayBarriers(long currentTime, long millisAtEnd) {
165 return computeCrossedDayBarriers(currentTime, millisAtEnd, null);
166 }
167
168 private int computeCrossedDayBarriers(long currentTime, long millisAtEnd, String timeZoneID) {
169 ZoneId dateTimeZone = ZoneId.systemDefault();
170 if (timeZoneID != null) {
171 dateTimeZone = ZoneId.of(timeZoneID);
172 }
173
174 Instant startInstant = Instant.ofEpochMilli(currentTime);
175 ZonedDateTime startZDT = startInstant.atZone(dateTimeZone);
176
177 ZonedDateTime startZDT0 = startZDT.truncatedTo(ChronoUnit.DAYS);
178
179 Instant endInstant = Instant.ofEpochMilli(millisAtEnd);
180 ZonedDateTime endZDT = endInstant.atZone(dateTimeZone);
181
182 ZonedDateTime endZDT0 = endZDT.truncatedTo(ChronoUnit.DAYS);
183
184
185 long dayCount = ChronoUnit.DAYS.between(startZDT0, endZDT0);
186 return (int) dayCount;
187 }
188
189 @Test
190 public void checkCleanupForBasicDailyRollover() {
191 cp.maxHistory(20).simulatedNumberOfPeriods(20 * 3).startInactivity(0).numInactivityPeriods(0);
192 generateDailyRolloverAndCheckFileCount(cp);
193 }
194
195 @ParameterizedTest
196 @MethodSource
197 public void checkCleanupForBasicDailyRolloverWithSizeCap(Long injectedCurrentTime) {
198 this.currentTime = injectedCurrentTime;
199
200 long bytesOutputPerPeriod = 16500;
201 int sizeInUnitsOfBytesPerPeriod = 2;
202
203 long sizeCap = sizeInUnitsOfBytesPerPeriod * bytesOutputPerPeriod + 1000;
204
205
206
207 cp.maxHistory(5).simulatedNumberOfPeriods(10)
208 .sizeCap(sizeCap);
209 generateDailyRollover(cp);
210
211 checkFileCount(sizeInUnitsOfBytesPerPeriod + 1);
212 }
213
214 static Stream<Long> checkCleanupForBasicDailyRolloverWithSizeCap() {
215
216
217 return Stream.of(1760822446333L, System.currentTimeMillis());
218 }
219 @Test
220 public void checkThatSmallTotalSizeCapLeavesAtLeastOneArhcive() {
221 long WED_2016_03_23_T_131345_CET = WED_2016_03_23_T_230705_CET - 10 * CoreConstants.MILLIS_IN_ONE_HOUR;
222
223
224
225
226
227 cp = new ConfigParameters(WED_2016_03_23_T_131345_CET);
228 final int verySmallCapSize = 1;
229 cp.maxHistory(5).simulatedNumberOfPeriods(3).sizeCap(verySmallCapSize);
230 generateDailyRollover(cp);
231
232 checkFileCountAtMost(1);
233
234 }
235
236 @Test
237 public void checkCleanupForBasicDailyRolloverWithMaxSize() {
238 cp.maxHistory(6).simulatedNumberOfPeriods(30).startInactivity(10).numInactivityPeriods(1);
239 generateDailyRolloverAndCheckFileCount(cp);
240 }
241
242
243
244
245 @Test
246 public void checkCleanupForDailyRollover_15Periods() {
247 cp.maxHistory(5).simulatedNumberOfPeriods(15).startInactivity(6).numInactivityPeriods(3);
248 generateDailyRolloverAndCheckFileCount(cp);
249 }
250
251 @Test
252 public void checkCleanupForDailyRolloverWithInactivity_30Periods() {
253
254 cp.maxHistory(2).simulatedNumberOfPeriods(30).startInactivity(3).numInactivityPeriods(1);
255 generateDailyRolloverAndCheckFileCount(cp);
256 }
257
258 @Test
259 public void checkCleanupForDailyRolloverWithInactivity_10Periods() {
260 this.currentTime = THU_2016_03_17_T_230330_CET;
261 cp.maxHistory(6).simulatedNumberOfPeriods(10).startInactivity(2).numInactivityPeriods(2);
262 generateDailyRolloverAndCheckFileCount(cp);
263 }
264
265 @Test
266 public void checkCleanupForDailyRolloverWithSecondPhase() {
267 slashCount = computeSlashCount(DAILY_DATE_PATTERN);
268 int maxHistory = 5;
269 String fileNamePattern = randomOutputDir + "clean-%d{" + DAILY_DATE_PATTERN + "}.txt";
270
271 ConfigParameters cp0 = new ConfigParameters(currentTime).maxHistory(maxHistory).fileNamePattern(fileNamePattern)
272 .simulatedNumberOfPeriods(maxHistory * 2);
273 long endTime = logOverMultiplePeriods(cp0);
274
275 ConfigParameters cp1 = new ConfigParameters(endTime + MILLIS_IN_DAY * 10).maxHistory(maxHistory)
276 .fileNamePattern(fileNamePattern).simulatedNumberOfPeriods(maxHistory);
277 logOverMultiplePeriods(cp1);
278 checkFileCount(expectedCountWithoutFolders(maxHistory));
279 }
280
281 @Test
282 public void dailyRolloverWithCronologPattern() {
283 this.slashCount = computeSlashCount(DAILY_CRONOLOG_DATE_PATTERN);
284 String fileNamePattern = randomOutputDir + "/%d{" + DAILY_CRONOLOG_DATE_PATTERN + "}/clean.txt.zip";
285 cp.maxHistory(8).fileNamePattern(fileNamePattern).simulatedNumberOfPeriods(8 * 3);
286 logOverMultiplePeriods(cp);
287 int expectedDirMin = 9 + slashCount;
288 int expectDirMax = expectedDirMin + 1 + 1;
289 expectedFileAndDirCount(9, expectedDirMin, expectDirMax);
290 }
291
292 @Test
293 public void dailySizeBasedRolloverWithoutCap() {
294 SizeAndTimeBasedFileNamingAndTriggeringPolicy<Object> sizeAndTimeBasedFNATP = new SizeAndTimeBasedFileNamingAndTriggeringPolicy<Object>();
295
296
297 sizeAndTimeBasedFNATP.setMaxFileSize(new FileSize(10000));
298 tbfnatp = sizeAndTimeBasedFNATP;
299 this.slashCount = computeSlashCount(DAILY_DATE_PATTERN);
300 String fileNamePattern = randomOutputDir + "/%d{" + DAILY_DATE_PATTERN + "}-clean.%i.zip";
301 cp.maxHistory(5).fileNamePattern(fileNamePattern).simulatedNumberOfPeriods(5 * 4);
302 logOverMultiplePeriods(cp);
303 checkPatternCompliance(5 + 1 + slashCount, "\\d{4}-\\d{2}-\\d{2}-clean(\\.\\d)(.zip)?");
304 }
305
306 @Test
307 public void dailySizeBasedRolloverWithSizeCap() {
308 SizeAndTimeBasedFileNamingAndTriggeringPolicy<Object> sizeAndTimeBasedFNATP = new SizeAndTimeBasedFileNamingAndTriggeringPolicy<Object>();
309
310 long fileSize = 3400;
311 int expectedFileCount = 10;
312 long sizeCap = expectedFileCount * fileSize;
313 sizeAndTimeBasedFNATP.setMaxFileSize(new FileSize(fileSize));
314 tbfnatp = sizeAndTimeBasedFNATP;
315 this.slashCount = computeSlashCount(DAILY_DATE_PATTERN);
316
317
318
319 long simulatedTime = getSimulatedTimeFromString("2016-03-05T00:14:39,186");
320
321 ConfigParameters params = new ConfigParameters(simulatedTime);
322 String fileNamePattern = randomOutputDir + "/%d{" + DAILY_DATE_PATTERN + "}-clean.%i";
323 params.maxHistory(60).fileNamePattern(fileNamePattern).simulatedNumberOfPeriods(10).sizeCap(sizeCap);
324 logOverMultiplePeriods(params);
325
326 List<File> foundFiles = findFilesByPattern("\\d{4}-\\d{2}-\\d{2}-clean(\\.\\d)");
327 Collections.sort(foundFiles, new Comparator<File>() {
328 public int compare(File f0, File f1) {
329 String s0 = f0.getName();
330 String s1 = f1.getName();
331 return s0.compareTo(s1);
332 }
333 });
334
335 StatusPrinter.print(context);
336 foundFiles.forEach(f -> System.out.println(""+f+ " "+f.length()));
337 LongAdder la = new LongAdder();
338 foundFiles.forEach(f -> la.add(f.length()));
339 System.out.println("Sum: "+la.sum());
340
341
342 assertTrue(la.sum() < sizeCap);
343
344 checkFileCount(expectedFileCount + 1);
345 }
346
347
348
349
350
351
352 private long getSimulatedTimeFromString(String dateStr) {
353 LocalDateTime localDateTime = LocalDateTime.parse(dateStr, STRICT_DATE_PARSER);
354 long simulatedTime = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
355 return simulatedTime;
356 }
357
358 @Test
359 public void dailyChronologSizeBasedRollover() {
360 SizeAndTimeBasedFileNamingAndTriggeringPolicy<Object> sizeAndTimeBasedFileNamingAndTriggeringPolicy = new SizeAndTimeBasedFileNamingAndTriggeringPolicy<Object>();
361 sizeAndTimeBasedFileNamingAndTriggeringPolicy.setMaxFileSize(new FileSize(10000));
362
363 tbfnatp = sizeAndTimeBasedFileNamingAndTriggeringPolicy;
364 slashCount = 1;
365 String fileNamePattern = randomOutputDir + "/%d{" + DAILY_DATE_PATTERN + "}/clean.%i.zip";
366 cp.maxHistory(5).fileNamePattern(fileNamePattern).simulatedNumberOfPeriods(5 * 3);
367 logOverMultiplePeriods(cp);
368 checkDirPatternCompliance(6);
369 }
370
371 @Test
372 public void dailyChronologSizeBasedRolloverWithSecondPhase() {
373 SizeAndTimeBasedFileNamingAndTriggeringPolicy<Object> sizeAndTimeBasedFileNamingAndTriggeringPolicy = new SizeAndTimeBasedFileNamingAndTriggeringPolicy<Object>();
374 sizeAndTimeBasedFileNamingAndTriggeringPolicy.setMaxFileSize(new FileSize(10000));
375
376 tbfnatp = sizeAndTimeBasedFileNamingAndTriggeringPolicy;
377 this.slashCount = 1;
378 String fileNamePattern = randomOutputDir + "/%d{" + DAILY_DATE_PATTERN + "}/clean.%i";
379 int maxHistory = 5;
380 cp.maxHistory(maxHistory).fileNamePattern(fileNamePattern).simulatedNumberOfPeriods(3);
381 long endTime = logOverMultiplePeriods(cp);
382
383 int simulatedNumberOfPeriods = maxHistory * 4;
384 ConfigParameters cp1 = new ConfigParameters(endTime + MILLIS_IN_DAY * 7).maxHistory(maxHistory)
385 .fileNamePattern(fileNamePattern).simulatedNumberOfPeriods(simulatedNumberOfPeriods);
386 logOverMultiplePeriods(cp1);
387 checkDirPatternCompliance(maxHistory + 1);
388 }
389
390 void logTwiceAndStop(long currentTime, String fileNamePattern, int maxHistory, long durationInMillis) {
391 ConfigParameters params = new ConfigParameters(currentTime).fileNamePattern(fileNamePattern)
392 .maxHistory(maxHistory);
393 configureRollingFileAppender(params, DO_CLEAN_HISTORY_ON_START);
394 rfa.doAppend("Hello ----------------------------------------------------------" + new Date(currentTime));
395 currentTime += durationInMillis / 2;
396 add(tbrp.compressionFuture);
397 add(tbrp.cleanUpFuture);
398 waitForJobsToComplete();
399 tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
400 rfa.doAppend("Hello ----------------------------------------------------------" + new Date(currentTime));
401 rfa.stop();
402 }
403
404
405 @Test
406 public void cleanHistoryOnStartWithHourPattern() {
407 long simulatedTime = WED_2016_03_23_T_230705_CET;
408 String fileNamePattern = randomOutputDir + "clean-%d{" + DAILY_HOUR_PATTERN + "}.txt";
409 int maxHistory = 3;
410 for (int i = 0; i <= 5; i++) {
411 logTwiceAndStop(simulatedTime, fileNamePattern, maxHistory, MILLIS_IN_HOUR);
412 simulatedTime += MILLIS_IN_HOUR;
413 }
414 checkFileCount(expectedCountWithoutFolders(maxHistory));
415 }
416
417 @Disabled
418 @Test
419
420
421
422
423
424 public void cleanHistoryOnStartWithHourPatternWithCollisions() {
425 long now = this.currentTime;
426 String fileNamePattern = randomOutputDir + "clean-%d{HH}.txt";
427 int maxHistory = 3;
428 for (int i = 0; i <= 5; i++) {
429 logTwiceAndStop(now, fileNamePattern, maxHistory, MILLIS_IN_DAY);
430 now = now + MILLIS_IN_HOUR;
431 }
432 checkFileCount(expectedCountWithoutFolders(maxHistory));
433 }
434
435 @Test
436 public void cleanHistoryOnStartWithDayPattern() {
437 long simulatedTime = WED_2016_03_23_T_230705_CET;
438 String fileNamePattern = randomOutputDir + "clean-%d{" + DAILY_DATE_PATTERN + "}.txt";
439 int maxHistory = 3;
440 for (int i = 0; i <= 5; i++) {
441 logTwiceAndStop(simulatedTime, fileNamePattern, maxHistory, MILLIS_IN_DAY);
442 simulatedTime += MILLIS_IN_DAY;
443 }
444 checkFileCount(expectedCountWithoutFolders(maxHistory));
445 }
446
447 @Test
448 public void cleanHistoryOnStartWithHourDayPattern() {
449 long simulatedTime = WED_2016_03_23_T_230705_CET;
450 String fileNamePattern = randomOutputDir + "clean-%d{yyyy-MM-dd-HH}.txt";
451 int maxHistory = 3;
452 for (int i = 0; i <= 5; i++) {
453 logTwiceAndStop(simulatedTime, fileNamePattern, maxHistory, MILLIS_IN_HOUR);
454 simulatedTime += MILLIS_IN_HOUR;
455 }
456 checkFileCount(expectedCountWithoutFolders(maxHistory));
457 }
458
459 int expectedCountWithoutFolders(int maxHistory) {
460 return maxHistory + 1;
461 }
462
463 int expectedCountWithFolders(int maxHistory, boolean withExtraFolder) {
464 int numLogFiles = (maxHistory + 1);
465 int numLogFilesAndFolders = numLogFiles * 2;
466 int result = numLogFilesAndFolders + slashCount;
467 if (withExtraFolder)
468 result += 1;
469 return result;
470 }
471
472 void configureRollingFileAppender(ConfigParameters cp, boolean cleanHistoryOnStart) {
473 rfa.setContext(context);
474 rfa.setEncoder(encoder);
475 tbrp.setContext(context);
476 tbrp.setFileNamePattern(cp.fileNamePattern);
477 tbrp.setMaxHistory(cp.maxHistory);
478 tbrp.setTotalSizeCap(new FileSize(cp.sizeCap));
479 tbrp.setParent(rfa);
480 tbrp.setCleanHistoryOnStart(cleanHistoryOnStart);
481 tbfnatp.setContext(context);
482 tbrp.timeBasedFileNamingAndTriggeringPolicy = tbfnatp;
483 tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(cp.simulatedTime);
484 tbrp.start();
485 rfa.setRollingPolicy(tbrp);
486 rfa.start();
487 }
488
489 boolean DO_CLEAN_HISTORY_ON_START = true;
490 boolean DO_NOT_CLEAN_HISTORY_ON_START = false;
491
492 long logOverMultiplePeriods(ConfigParameters cp) {
493
494
495 configureRollingFileAppender(cp, DO_NOT_CLEAN_HISTORY_ON_START);
496
497
498 int runLength = cp.simulatedNumberOfPeriods * ticksPerPeriod;
499 int startInactivityIndex = cp.startInactivity * ticksPerPeriod;
500 int endInactivityIndex = startInactivityIndex + cp.numInactivityPeriods * ticksPerPeriod;
501 long tickDuration = cp.periodDurationInMillis / ticksPerPeriod;
502
503 System.out.println("ticksPerPeriod=" + ticksPerPeriod);
504 System.out.println("cp.startInactivity="+cp.startInactivity);
505 System.out.println("cp.simulatedNumberOfPeriods="+cp.simulatedNumberOfPeriods);
506 System.out.println("cp.periodDurationInMillis="+cp.periodDurationInMillis);
507
508 System.out.println("runLength=" + runLength);
509
510 System.out.println("startInactivityIndex=" + startInactivityIndex);
511 System.out.println("endInactivityIndex=" + endInactivityIndex);
512 System.out.println("tickDuration=" + tickDuration);
513 System.out.println(" ");
514
515 for (int i = 0; i <= runLength; i++) {
516 long timeInMillis = tbrp.timeBasedFileNamingAndTriggeringPolicy.getCurrentTime();
517
518 Date currentDate = new Date(timeInMillis);
519
520 if (i < startInactivityIndex || i > endInactivityIndex) {
521 rfa.doAppend(buildMessageString(currentDate, i));
522 }
523
524 tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(addTime(timeInMillis, tickDuration));
525
526 add(tbrp.compressionFuture);
527 add(tbrp.cleanUpFuture);
528 waitForJobsToComplete();
529 }
530
531 try {
532 Thread.sleep(100);
533 } catch (InterruptedException e) {
534
535 e.printStackTrace();
536 }
537 rfa.stop();
538
539
540
541 return tbrp.timeBasedFileNamingAndTriggeringPolicy.getCurrentTime();
542 }
543
544 private void addOnConsoleStatusListenerForDebugging() {
545 OnConsoleStatusListener onConsoleStatusListener = new OnConsoleStatusListener();
546 onConsoleStatusListener.setContext(context);
547 onConsoleStatusListener.start();
548 context.getStatusManager().add(onConsoleStatusListener);
549 }
550
551 private static String buildMessageString(Date currentDate, int i) {
552 StringBuilder sb = new StringBuilder("Hello");
553 String currentDateStr = currentDate.toString();
554 String iAsString = Integer.toString(i);
555 sb.append(currentDateStr);
556 SpacePadder.spacePad(sb, 68 + (3 - iAsString.length() - currentDateStr.length() - CoreConstants.LINE_SEPARATOR_LEN));
557 sb.append(iAsString);
558 return sb.toString();
559 }
560
561 void fillWithChar(StringBuffer sb, char c, int count) {
562 for (int i = 0; i < count; i++) {
563 sb.append(c);
564 }
565 }
566
567 boolean extraFolder(int numPeriods, int periodsPerEra, int beginPeriod, int maxHistory) {
568 int valueOfLastMonth = ((beginPeriod) + numPeriods) % periodsPerEra;
569 return (valueOfLastMonth < maxHistory);
570 }
571
572 long addTime(long time, long timeToWait) {
573 return time + timeToWait;
574 }
575
576 void expectedFileAndDirCount(int expectedFileAndDirCount, int expectedDirCountMin, int expectedDirCountMax) {
577 File dir = new File(randomOutputDir);
578 List<File> fileList = new ArrayList<File>();
579 findFilesInFolderRecursivelyByPatterMatch(dir, fileList, "clean");
580 List<File> dirList = new ArrayList<File>();
581 findAllFoldersInFolderRecursively(dir, dirList);
582 String msg = "expectedDirCountMin=" + expectedDirCountMin + ", expectedDirCountMax=" + expectedDirCountMax
583 + " actual value=" + dirList.size();
584 assertTrue(expectedDirCountMin <= dirList.size() && dirList.size() <= expectedDirCountMax, msg);
585 }
586
587 void checkFileCount(int expectedCount) {
588 File dir = new File(randomOutputDir);
589 List<File> fileList = new ArrayList<File>();
590 findAllDirsOrStringContainsFilesRecursively(dir, fileList, "clean");
591 assertEquals(expectedCount, fileList.size());
592 }
593
594 void checkFileCountAtMost(int expectedCount) {
595 File dir = new File(randomOutputDir);
596 List<File> fileList = new ArrayList<File>();
597 findAllDirsOrStringContainsFilesRecursively(dir, fileList, "clean");
598 int fileListSize = fileList.size();
599
600 assertTrue(fileListSize <= expectedCount, "file list size " + fileListSize + ", expectedCount=" + expectedCount);
601 }
602
603 int expectedCountWithoutFoldersWithInactivity(int maxHistory, int totalPeriods, int endOfInactivity) {
604 int availableHistory = (totalPeriods + 1) - endOfInactivity;
605 int actualHistory = Math.min(availableHistory, maxHistory + 1);
606 return actualHistory;
607 }
608
609 void genericFindMatching(final FileMatchFunction matchFunc, File dir, List<File> fileList, final String pattern,
610 boolean includeDirs) {
611 if (dir.isDirectory()) {
612 File[] matchArray = dir.listFiles(new FileFilter() {
613 public boolean accept(File f) {
614 return f.isDirectory() || matchFunc.match(f, pattern);
615 }
616 });
617 for (File f : matchArray) {
618 if (f.isDirectory()) {
619 if (includeDirs)
620 fileList.add(f);
621 genericFindMatching(matchFunc, f, fileList, pattern, includeDirs);
622 } else
623 fileList.add(f);
624 }
625 }
626 }
627
628 private void findAllFoldersInFolderRecursively(File dir, List<File> fileList) {
629 FileMatchFunction alwaysFalse = new FileMatchFunction() {
630 public boolean match(File f, String pattern) {
631 return false;
632 }
633 };
634 genericFindMatching(alwaysFalse, dir, fileList, null, true);
635 }
636
637 private void findAllDirsOrStringContainsFilesRecursively(File dir, List<File> fileList, String pattern) {
638 FileMatchFunction matchFunction = new FileMatchFunction() {
639 public boolean match(File f, String pattern) {
640 return f.getName().contains(pattern);
641 }
642 };
643 genericFindMatching(matchFunction, dir, fileList, pattern, true);
644 }
645
646 void findFilesInFolderRecursivelyByPatterMatch(File dir, List<File> fileList, String pattern) {
647 FileMatchFunction matchByPattern = new FileMatchFunction() {
648 public boolean match(File f, String pattern) {
649 return f.getName().matches(pattern);
650 }
651 };
652 genericFindMatching(matchByPattern, dir, fileList, pattern, false);
653 }
654
655 Set<String> groupByClass(List<File> fileList, String regex) {
656 Pattern p = Pattern.compile(regex);
657 Set<String> set = new HashSet<String>();
658 for (File f : fileList) {
659 String n = f.getName();
660 Matcher m = p.matcher(n);
661 m.matches();
662 int begin = m.start(1);
663 String reduced = n.substring(0, begin);
664 set.add(reduced);
665 }
666 return set;
667 }
668
669 void checkPatternCompliance(int expectedClassCount, String regex) {
670 Set<String> set = findFilesByPatternClass(regex);
671 assertEquals(expectedClassCount, set.size());
672 }
673
674 private List<File> findFilesByPattern(String regex) {
675 File dir = new File(randomOutputDir);
676 List<File> fileList = new ArrayList<File>();
677 findFilesInFolderRecursivelyByPatterMatch(dir, fileList, regex);
678 return fileList;
679 }
680
681 private Set<String> findFilesByPatternClass(String regex) {
682 List<File> fileList = findFilesByPattern(regex);
683 Set<String> set = groupByClass(fileList, regex);
684 return set;
685 }
686
687 void checkDirPatternCompliance(int expectedClassCount) {
688 File dir = new File(randomOutputDir);
689 List<File> fileList = new ArrayList<File>();
690 findAllFoldersInFolderRecursively(dir, fileList);
691 for (File f : fileList) {
692 assertTrue(f.list().length >= 1);
693 }
694 assertEquals(expectedClassCount, fileList.size());
695 }
696 }