svn commit: r2419 - in logback/trunk/logback-core/src: main/java/ch/qos/logback/core/rolling main/java/ch/qos/logback/core/rolling/helper test/java/ch/qos/logback/core/rolling test/java/ch/qos/logback/core/rolling/helper

Author: ceki Date: Fri Aug 7 18:30:50 2009 New Revision: 2419 Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DatePatternToRegexUtil.java - copied, changed from r2417, /logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DatePatternToSRegexUtil.java logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/SizeAndTimeBasedArchiveRemover.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithArchiveRemovalTest.java - copied, changed from r2418, /logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithHistoryCleanTest.java Removed: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DatePatternToSRegexUtil.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithHistoryCleanTest.java Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicyBase.java logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP.java logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DateTokenConverter.java logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DefaultArchiveRemover.java logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileFilterUtil.java logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/SequenceToRegex4SDF.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/PackageTest.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/DatePatternToRegexTest.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java Log: - FileNamePattern now slashifies its pattern argument at construction time This eliminates the need to slashify regular expression at a later time (since the original pattern is already slashified) - While cleaning archived log files, empty fodlers are taken into account, especially if they are in cronolog-style "/var/tmp/2009/08/04/foo.log". - old archives are cleaned for time-based triggering as well as size-and-time-based triggering - relevant test cases Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicyBase.java ============================================================================== --- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicyBase.java (original) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicyBase.java Fri Aug 7 18:30:50 2009 @@ -11,6 +11,7 @@ import ch.qos.logback.core.FileAppender; import ch.qos.logback.core.rolling.helper.CompressionMode; +import ch.qos.logback.core.rolling.helper.FileFilterUtil; import ch.qos.logback.core.rolling.helper.FileNamePattern; import ch.qos.logback.core.spi.ContextAwareBase; @@ -24,6 +25,7 @@ RollingPolicy { protected CompressionMode compressionMode = CompressionMode.NONE; protected FileNamePattern fileNamePattern; + // fileNamePatternStr is always slashified, see setter protected String fileNamePatternStr; private FileAppender parent; @@ -76,7 +78,6 @@ } public void setParent(FileAppender appender) { - addInfo("Adding parent to RollingPolicy: " + appender.getName()); this.parent = appender; } Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP.java ============================================================================== --- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP.java (original) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP.java Fri Aug 7 18:30:50 2009 @@ -14,6 +14,7 @@ import ch.qos.logback.core.joran.spi.NoAutoStart; import ch.qos.logback.core.rolling.helper.FileFilterUtil; +import ch.qos.logback.core.rolling.helper.SizeAndTimeBasedArchiveRemover; import ch.qos.logback.core.util.FileSize; @NoAutoStart @@ -30,12 +31,14 @@ // in super.start() super.start(); + archiveRemover = new SizeAndTimeBasedArchiveRemover(tbrp.fileNamePattern, rc); + // we need to get the correct value of currentPeriodsCounter. // usually the value is 0, unless the appender or the application // is stopped and restarted within the same period if (tbrp.getParentsRawFileProperty() == null) { - String slashifiedRegex = tbrp.fileNamePattern.toSRegex(dateInCurrentPeriod); - String stemRegex = FileFilterUtil.afterLastSlash(slashifiedRegex); + String regex = tbrp.fileNamePattern.toRegex(dateInCurrentPeriod); + String stemRegex = FileFilterUtil.afterLastSlash(regex); computeCurrentPeriodsHighestCounterValue(stemRegex); } started = true; @@ -79,9 +82,11 @@ } if (activeFile.length() >= maxFileSize.getSize()) { + System.out.println("Size based trigger, currentPeriodsCounter="+currentPeriodsCounter); elapsedPeriodsFileName = tbrp.fileNamePatternWCS .convertMultipleArguments(dateInCurrentPeriod, currentPeriodsCounter); currentPeriodsCounter++; + System.out.println("Size based trigger, currentPeriodsCounter="+currentPeriodsCounter); return true; } Copied: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DatePatternToRegexUtil.java (from r2417, /logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DatePatternToSRegexUtil.java) ============================================================================== --- /logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DatePatternToSRegexUtil.java (original) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DatePatternToRegexUtil.java Fri Aug 7 18:30:50 2009 @@ -21,21 +21,21 @@ * @author Ceki Gülcü * */ -public class DatePatternToSRegexUtil { +public class DatePatternToRegexUtil { final String datePattern; final int length; - DatePatternToSRegexUtil(String datePattern) { + DatePatternToRegexUtil(String datePattern) { this.datePattern = datePattern; length = datePattern.length(); } - String toSRegex() { + String toRegex() { List<SequenceToRegex4SDF> sequenceList = tokenize(); StringBuilder sb = new StringBuilder(); for (SequenceToRegex4SDF seq : sequenceList) { - sb.append(seq.toSRegex()); + sb.append(seq.toRegex()); } return sb.toString(); } Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DateTokenConverter.java ============================================================================== --- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DateTokenConverter.java (original) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DateTokenConverter.java Fri Aug 7 18:30:50 2009 @@ -67,8 +67,8 @@ return (o instanceof Date); } - public String toSRegex() { - DatePatternToSRegexUtil toRegex = new DatePatternToSRegexUtil(datePattern); - return toRegex.toSRegex(); + public String toRegex() { + DatePatternToRegexUtil toRegex = new DatePatternToRegexUtil(datePattern); + return toRegex.toRegex(); } } Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DefaultArchiveRemover.java ============================================================================== --- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DefaultArchiveRemover.java (original) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/DefaultArchiveRemover.java Fri Aug 7 18:30:50 2009 @@ -13,16 +13,55 @@ import java.io.File; import java.util.Date; +import ch.qos.logback.core.pattern.Converter; +import ch.qos.logback.core.pattern.LiteralConverter; + public class DefaultArchiveRemover implements ArchiveRemover { - FileNamePattern fileNamePattern; - RollingCalendar rc; + final FileNamePattern fileNamePattern; + final RollingCalendar rc; int maxHistory; int periodOffset; - - public DefaultArchiveRemover(FileNamePattern fileNamePattern, RollingCalendar rc) { + final boolean parentClean; + + public DefaultArchiveRemover(FileNamePattern fileNamePattern, + RollingCalendar rc) { this.fileNamePattern = fileNamePattern; this.rc = rc; + this.parentClean = computeParentCleaningFlag(fileNamePattern); + } + + boolean computeParentCleaningFlag(FileNamePattern fileNamePattern) { + DateTokenConverter dtc = fileNamePattern.getDateTokenConverter(); + // if the date pattern has a /, then we need parent cleaning + if(dtc.getDatePattern().indexOf('/') != -1) { + return true; + } + // if the literal string subsequent to the dtc contains a /, we also need + // parent cleaning + + Converter<Object> p = fileNamePattern.headTokenConverter; + + // find the date converter + while(p != null) { + if(p instanceof DateTokenConverter) { + break; + } + p = p.getNext(); + } + + while(p != null) { + if(p instanceof LiteralConverter) { + String s = p.convert(null); + if(s.indexOf('/') != -1) { + return true; + } + } + p = p.getNext(); + } + + // no /, so we don't need parent cleaning + return false; } public void clean(Date now) { @@ -34,12 +73,34 @@ if (file2Delete.exists() && file2Delete.isFile()) { file2Delete.delete(); + if (parentClean) { + removeFolderIfEmpty(file2Delete.getParentFile(), 0); + } + } + } + + /** + * Will remove the directory passed as parameter if empty. After that, if the + * parent is also becomes empty, remove the parent dir as well but at most 3 + * times. + * + * @param dir + * @param recursivityCount + */ + void removeFolderIfEmpty(File dir, int recursivityCount) { + // we should never go more than 3 levels higher + if (recursivityCount >= 3) { + return; + } + if (dir.isDirectory() && FileFilterUtil.isEmptyDirectory(dir)) { + dir.delete(); + removeFolderIfEmpty(dir.getParentFile(), recursivityCount + 1); } } public void setMaxHistory(int maxHistory) { this.maxHistory = maxHistory; - this.periodOffset = -maxHistory -1; + this.periodOffset = -maxHistory - 1; } } Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileFilterUtil.java ============================================================================== --- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileFilterUtil.java (original) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileFilterUtil.java Fri Aug 7 18:30:50 2009 @@ -48,6 +48,18 @@ } } + static public boolean isEmptyDirectory(File dir) { + if (!dir.isDirectory()) { + throw new IllegalArgumentException("[" + dir + "] must be a directory"); + } + String[] filesInDir = dir.list(); + if (filesInDir == null || filesInDir.length == 0) { + return true; + } else { + return false; + } + } + /** * Return the set of files matching the stemRegex as found in 'directory'. A * stemRegex does not contain any slash characters or any folder seperators. @@ -87,7 +99,20 @@ return counter; } - static String slashify(String in) { + public static String slashify(String in) { return in.replace('\\', '/'); } + + public static void removeEmptyParentDirectories(File file, + int recursivityCount) { + // we should never go more than 3 levels higher + if (recursivityCount >= 3) { + return; + } + File parent = file.getParentFile(); + if (parent.isDirectory() && FileFilterUtil.isEmptyDirectory(parent)) { + parent.delete(); + removeEmptyParentDirectories(parent, recursivityCount + 1); + } + } } Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java ============================================================================== --- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java (original) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java Fri Aug 7 18:30:50 2009 @@ -46,7 +46,8 @@ Converter<Object> headTokenConverter; public FileNamePattern(String patternArg, Context contextArg) { - setPattern(patternArg); + // the pattern is slashified + setPattern(FileFilterUtil.slashify(patternArg)); setContext(contextArg); parse(); ConverterUtil.startConverters(this.headTokenConverter); @@ -141,20 +142,20 @@ } /** - * Given date, convert this instance to a slashified regular expression. A + * Given date, convert this instance to a regular expression. A * slashified regex, is a regex with naturally occurring forward slash * characters replaced by back slashes. */ - public String toSRegex(Date date) { + public String toRegex(Date date) { StringBuilder buf = new StringBuilder(); Converter<Object> p = headTokenConverter; while (p != null) { if (p instanceof LiteralConverter) { - buf.append(FileFilterUtil.slashify(p.convert(null))); + buf.append(p.convert(null)); } else if (p instanceof IntegerTokenConverter) { buf.append("(\\d{1,2})"); } else if (p instanceof DateTokenConverter) { - buf.append(FileFilterUtil.slashify(p.convert(date))); + buf.append(p.convert(date)); } p = p.getNext(); } @@ -162,19 +163,19 @@ } /** - * Given date, convert this instance to a slashified regular expression + * Given date, convert this instance to a regular expression */ - public String toSRegex() { + public String toRegex() { StringBuilder buf = new StringBuilder(); Converter<Object> p = headTokenConverter; while (p != null) { if (p instanceof LiteralConverter) { - buf.append(FileFilterUtil.slashify(p.convert(null))); + buf.append(p.convert(null)); } else if (p instanceof IntegerTokenConverter) { buf.append("\\d{1,2}"); } else if (p instanceof DateTokenConverter) { DateTokenConverter<Object> dtc = (DateTokenConverter<Object>) p; - buf.append(dtc.toSRegex()); + buf.append(dtc.toRegex()); } p = p.getNext(); } Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/SequenceToRegex4SDF.java ============================================================================== --- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/SequenceToRegex4SDF.java (original) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/SequenceToRegex4SDF.java Fri Aug 7 18:30:50 2009 @@ -29,8 +29,7 @@ occurrences++; } - // slashified regex - String toSRegex() { + String toRegex() { switch (c) { case 'G': return ".*"; @@ -64,12 +63,8 @@ return "(\\+|-)\\d{4}"; case '.': return "\\."; - case '\\': // slashify - String s = ""; - for(int i = 0; i < occurrences;i++) { - s += "/"; - } - return s; + case '\\': + throw new IllegalStateException("Forward slashes are not allowed"); default: if (occurrences == 1) { return "" + c; Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/SizeAndTimeBasedArchiveRemover.java ============================================================================== --- (empty file) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/SizeAndTimeBasedArchiveRemover.java Fri Aug 7 18:30:50 2009 @@ -0,0 +1,45 @@ +/** + * Logback: the generic, reliable, fast and flexible logging framework. + * + * Copyright (C) 2000-2009, QOS.ch + * + * This library is free software, you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation. + */ + +package ch.qos.logback.core.rolling.helper; + +import java.io.File; +import java.util.Date; + +public class SizeAndTimeBasedArchiveRemover extends DefaultArchiveRemover { + + public SizeAndTimeBasedArchiveRemover(FileNamePattern fileNamePattern, + RollingCalendar rc) { + super(fileNamePattern, rc); + } + + @Override + public void clean(Date now) { + Date dateOfPeriodToClean = rc.getRelativeDate(now, periodOffset); + + String regex = fileNamePattern.toRegex(dateOfPeriodToClean); + String stemRegex = FileFilterUtil.afterLastSlash(regex); + File archive0 = new File(fileNamePattern.convertMultipleArguments( + dateOfPeriodToClean, 0)); + + File parentDir = archive0.getParentFile(); + File[] matchingFileArray = FileFilterUtil.filesInFolderMatchingStemRegex( + parentDir, stemRegex); + + for (File f : matchingFileArray) { + f.delete(); + } + + if (parentClean) { + removeFolderIfEmpty(parentDir, 0); + } + } + +} Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/PackageTest.java ============================================================================== --- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/PackageTest.java (original) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/PackageTest.java Fri Aug 7 18:30:50 2009 @@ -5,7 +5,7 @@ @RunWith(Suite.class) @Suite.SuiteClasses( { RenamingTest.class, SizeBasedRollingTest.class, - TimeBasedRollingTest.class, TimeBasedRollingWithHistoryCleanTest.class, + TimeBasedRollingTest.class, TimeBasedRollingWithArchiveRemovalTest.class, MultiThreadedRollingTest.class, SizeAndTimeBasedFNATP_Test.class, ch.qos.logback.core.rolling.helper.PackageTest.class }) Copied: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithArchiveRemovalTest.java (from r2418, /logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithHistoryCleanTest.java) ============================================================================== --- /logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithHistoryCleanTest.java (original) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithArchiveRemovalTest.java Fri Aug 7 18:30:50 2009 @@ -3,7 +3,9 @@ import static org.junit.Assert.assertEquals; import java.io.File; -import java.io.FilenameFilter; +import java.io.FileFilter; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.TimeUnit; import org.junit.After; @@ -13,59 +15,117 @@ import ch.qos.logback.core.Context; import ch.qos.logback.core.ContextBase; import ch.qos.logback.core.layout.EchoLayout; +import ch.qos.logback.core.testUtil.RandomUtil; import ch.qos.logback.core.util.CoreTestConstants; -public class TimeBasedRollingWithHistoryCleanTest { +public class TimeBasedRollingWithArchiveRemovalTest { Context context = new ContextBase(); EchoLayout<Object> layout = new EchoLayout<Object>(); static final String MONTHLY_DATE_PATTERN = "yyyy-MM"; + static final String MONTHLY_CROLOLOG_DATE_PATTERN = "yyyy/MM"; + static final String DAILY_DATE_PATTERN = "yyyy-MM-dd"; + static final String DAILY_CROLOLOG_DATE_PATTERN = "yyyy/MM/dd"; static final long MILLIS_IN_MINUTE = 60 * 1000; static final long MILLIS_IN_HOUR = 60 * MILLIS_IN_MINUTE; static final long MILLIS_IN_DAY = 24 * MILLIS_IN_HOUR; static final long MILLIS_IN_MONTH = 30 * MILLIS_IN_DAY; + int diff = RandomUtil.getPositiveInt(); + protected String randomOutputDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + + "/"; + int slashCount; + + // by default tbfnatp is an instance of + // DefaultTimeBasedFileNamingAndTriggeringPolicy + TimeBasedFileNamingAndTriggeringPolicy<Object> tbfnatp = new DefaultTimeBasedFileNamingAndTriggeringPolicy<Object>(); + @Before public void setUp() throws Exception { context.setName("test"); - - // remove all files containing the string 'clean' - File dir = new File(CoreTestConstants.OUTPUT_DIR_PREFIX); - if (dir.isDirectory()) { - File[] toDelete = dir.listFiles(new FilenameFilter() { - public boolean accept(File dir, String name) { - return name.contains("clean"); - } - }); - for (File f : toDelete) { - System.out.println(f); - f.delete(); - } - } } @After public void tearDown() throws Exception { } + int computeSlashCount(String datePattern) { + int fromIndex = 0; + int count = 0; + while (true) { + int i = datePattern.indexOf('/', fromIndex); + if (i == -1) { + break; + } else { + count++; + fromIndex = i + 1; + if (fromIndex >= datePattern.length()) { + break; + } + } + } + return count; + } + @Test public void montlyRollover() throws Exception { - doRollover(CoreTestConstants.OUTPUT_DIR_PREFIX + "clean-%d{" + MONTHLY_DATE_PATTERN - + "}.txt", MILLIS_IN_MONTH, 20); + slashCount = computeSlashCount(MONTHLY_DATE_PATTERN); + // large maxPeriod, a 3 times as many number of periods to simulate + doRollover(randomOutputDir + "clean-%d{" + MONTHLY_DATE_PATTERN + "}.txt", + MILLIS_IN_MONTH, 20, 20 * 3, expectedCountWithoutDirs(20)); + } + @Test + public void montlyRolloverOverManyPeriods() throws Exception { + // small maxHistory, many periods + slashCount = computeSlashCount(MONTHLY_CROLOLOG_DATE_PATTERN); + doRollover(randomOutputDir + "/%d{" + MONTHLY_CROLOLOG_DATE_PATTERN + + "}/clean.txt.zip", MILLIS_IN_MONTH, 5, 40, expectedCountWithDirs(5)); } @Test public void dailyRollover() throws Exception { - doRollover(CoreTestConstants.OUTPUT_DIR_PREFIX + "clean-%d{" + DAILY_DATE_PATTERN - + "}.txt.zip", MILLIS_IN_DAY, 5); + slashCount = computeSlashCount(DAILY_DATE_PATTERN); + doRollover( + randomOutputDir + "clean-%d{" + DAILY_DATE_PATTERN + "}.txt.zip", + MILLIS_IN_DAY, 5, 5 * 3, expectedCountWithoutDirs(5)); } - void doRollover(String fileNamePattern, long delay, int maxHistory) - throws Exception { + @Test + public void dailyCronologRollover() throws Exception { + slashCount = computeSlashCount(DAILY_CROLOLOG_DATE_PATTERN); + doRollover(randomOutputDir + "/%d{" + DAILY_CROLOLOG_DATE_PATTERN + + "}/clean.txt.zip", MILLIS_IN_DAY, 8, 8 * 3, expectedCountWithDirs(8)); + } + + @Test + public void dailySizeBasedRollover() throws Exception { + SizeAndTimeBasedFNATP<Object> sizeAndTimeBasedFNATP = new SizeAndTimeBasedFNATP<Object>(); + sizeAndTimeBasedFNATP.setMaxFileSize("1"); + tbfnatp = sizeAndTimeBasedFNATP; + + slashCount = computeSlashCount(DAILY_DATE_PATTERN); + doRollover(randomOutputDir + "/%d{" + DAILY_DATE_PATTERN + + "}-clean.%i.zip", MILLIS_IN_DAY, 5, 5 * 4, expectedCountWithoutDirs(5)); + } + + + @Test + public void dailyChronologSizeBasedRollover() throws Exception { + SizeAndTimeBasedFNATP<Object> sizeAndTimeBasedFNATP = new SizeAndTimeBasedFNATP<Object>(); + sizeAndTimeBasedFNATP.setMaxFileSize("1"); + tbfnatp = sizeAndTimeBasedFNATP; + + slashCount = computeSlashCount(DAILY_CROLOLOG_DATE_PATTERN); + doRollover(randomOutputDir + "/%d{" + DAILY_DATE_PATTERN + + "}/clean.%i.zip", MILLIS_IN_DAY, 5, 5 * 4, xexpectedCountWithDirs_NoSlash(5)); + } + + void doRollover(String fileNamePattern, long periodDurationInMillis, + int maxHistory, int simulatedNumberOfPeriods, int expectedCount) throws Exception { long currentTime = System.currentTimeMillis(); RollingFileAppender<Object> rfa = new RollingFileAppender<Object>(); @@ -78,36 +138,71 @@ tbrp.setMaxHistory(maxHistory); tbrp.setParent(rfa); - tbrp.timeBasedTriggering = new DefaultTimeBasedFileNamingAndTriggeringPolicy<Object>(); + tbrp.timeBasedTriggering = tbfnatp; tbrp.timeBasedTriggering.setCurrentTime(currentTime); tbrp.start(); rfa.setRollingPolicy(tbrp); rfa.start(); - for (int i = 0; i < maxHistory * 3; i++) { + int ticksPerPeriod = 64; + long runLength = simulatedNumberOfPeriods * ticksPerPeriod; + + for (long i = 0; i < runLength; i++) { rfa.doAppend("Hello---" + i); - tbrp.timeBasedTriggering.setCurrentTime(addTime(tbrp.timeBasedTriggering.getCurrentTime(), delay / 2)); + tbrp.timeBasedTriggering.setCurrentTime(addTime(tbrp.timeBasedTriggering + .getCurrentTime(), periodDurationInMillis / ticksPerPeriod)); + if (tbrp.future != null) { tbrp.future.get(200, TimeUnit.MILLISECONDS); } } rfa.stop(); - check(maxHistory + 1); + check(expectedCount); } - void check(int expectedCount) { - // remove all files containing the string 'clean' - File dir = new File(CoreTestConstants.OUTPUT_DIR_PREFIX); + void recursiveDirectoryDescent(File dir, List<File> fileList, + final String pattern) { if (dir.isDirectory()) { - File[] match = dir.listFiles(new FilenameFilter() { - public boolean accept(File dir, String name) { - return name.contains("clean"); + File[] match = dir.listFiles(new FileFilter() { + public boolean accept(File f) { + if (f.isDirectory()) { + return true; + } else { + return f.getName().contains(pattern); + } } }); - //System.out.println(Arrays.toString(match)); - assertEquals(expectedCount, match.length); + for (File f : match) { + fileList.add(f); + if (f.isDirectory()) { + recursiveDirectoryDescent(f, fileList, pattern); + } + } } + } + int expectedCountWithoutDirs(int maxHistory) { + // maxHistory plus the currently active file + return maxHistory+1; + } + + int expectedCountWithDirs(int maxHistory) { + // each slash adds a new directory + // + one file and one directory per archived log file + return (maxHistory + 1) * 2 + slashCount; + } + + int xexpectedCountWithDirs_NoSlash(int maxHistory) { + // each slash adds a new directory + // + one file and one directory per archived log file + return (maxHistory + 1) * 2; + } + + void check(int expectedCount) { + File dir = new File(randomOutputDir); + List<File> fileList = new ArrayList<File>(); + recursiveDirectoryDescent(dir, fileList, "clean"); + assertEquals(expectedCount, fileList.size()); } static long addTime(long currentTime, long timeToWait) { Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/DatePatternToRegexTest.java ============================================================================== --- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/DatePatternToRegexTest.java (original) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/DatePatternToRegexTest.java Fri Aug 7 18:30:50 2009 @@ -46,10 +46,6 @@ doTest("yyyy-MMMM-dd", CAL_2009_08_3_NIGHT); } - @Test - public void slash() { - doTest("yyyy\\MMM\\dd", CAL_2009_08_3_NIGHT, true); - } @Test public void dot() { @@ -93,7 +89,7 @@ if(slashified) { expected = expected.replace('\\', '/'); } - String regex = dtc.toSRegex(); + String regex = dtc.toRegex(); //System.out.println("expected="+expected); //System.out.println(regex); assertTrue("[" + expected + "] does not match regex [" + regex + "]", Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java ============================================================================== --- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java (original) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java Fri Aug 7 18:30:50 2009 @@ -28,19 +28,12 @@ @Test public void testSmoke() { - // System.out.println("Testing [t]"); FileNamePattern pp = new FileNamePattern("t", context); assertEquals("t", pp.convertInt(3)); - // System.out.println("Testing [foo]"); pp = new FileNamePattern("foo", context); assertEquals("foo", pp.convertInt(3)); - // System.out.println("Testing [foo%]"); - // pp = new FileNamePattern("foo%", context); - // StatusPrinter.print(context.getStatusManager()); - // assertEquals("foo%", pp.convertInt(3)); - pp = new FileNamePattern("%i foo", context); assertEquals("3 foo", pp.convertInt(3)); @@ -54,11 +47,11 @@ pp = new FileNamePattern("foo.%i.log", context); assertEquals("foo.3.log", pp.convertInt(3)); - pp = new FileNamePattern("%i.foo\\%", context); - assertEquals("3.foo%", pp.convertInt(3)); + //pp = new FileNamePattern("%i.foo\\%", context); + //assertEquals("3.foo%", pp.convertInt(3)); - pp = new FileNamePattern("\\%foo", context); - assertEquals("%foo", pp.convertInt(3)); + //pp = new FileNamePattern("\\%foo", context); + //assertEquals("%foo", pp.convertInt(3)); } @Test @@ -94,7 +87,7 @@ @Test public void withBackslash() { FileNamePattern pp = new FileNamePattern("c:\\foo\\bar.%i", context); - assertEquals("c:\\foo\\bar.3", pp.convertInt(3)); + assertEquals("c:/foo/bar.3", pp.convertInt(3)); } @Test @@ -116,13 +109,13 @@ { FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM.dd}-%i.txt", context); - String regex = fnp.toSRegex(cal.getTime()); + String regex = fnp.toRegex(cal.getTime()); assertEquals("foo-2003.05.20-(\\d{1,2}).txt", regex); } { FileNamePattern fnp = new FileNamePattern("\\toto\\foo-%d{yyyy\\MM\\dd}-%i.txt", context); - String regex = fnp.toSRegex(cal.getTime()); + String regex = fnp.toRegex(cal.getTime()); assertEquals("/toto/foo-2003/05/20-(\\d{1,2}).txt", regex); } } @@ -133,7 +126,7 @@ cal.set(2003, 4, 20, 17, 55); FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM.dd}-%i.txt", context); - String regex = fnp.toSRegex(); + String regex = fnp.toRegex(); assertEquals("foo-\\d{4}\\.\\d{2}\\.\\d{2}-\\d{1,2}.txt", regex); }
participants (1)
-
noreply.ceki@qos.ch