001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v1.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.core.rolling;
015
016import java.io.File;
017import java.io.FileOutputStream;
018import java.io.IOException;
019
020import org.junit.After;
021import org.junit.Before;
022import org.junit.Test;
023
024import ch.qos.logback.core.encoder.EchoEncoder;
025import ch.qos.logback.core.rolling.testUtil.ScaffoldingForRollingTests;
026import ch.qos.logback.core.testUtil.EnvUtilForTests;
027import ch.qos.logback.core.util.StatusPrinter;
028
029/**
030 * A rather exhaustive set of tests. Tests include leaving the file option
031 * blank, or setting it, with and without compression, and tests with or without
032 * stopping/restarting the RollingFileAppender.
033 * <p>
034 * The regression tests log a few times using a RollingFileAppender. Then, they
035 * predict the names of the files which should be generated and compare them
036 * with witness files.
037 * <p>
038 * <pre>
039 *                Compression     file option    Stop/Restart
040 *     Test1      NO              BLANK           NO
041 *     Test2      YES             BLANK           NO
042 *     Test3      NO              BLANK           YES
043 *     Test4      NO              SET             YES
044 *     Test5      NO              SET             NO
045 *     Test6      YES             SET             NO
046 * </pre>
047 *
048 * @author Ceki G&uuml;lc&uuml;
049 */
050public class TimeBasedRollingTest extends ScaffoldingForRollingTests {
051
052    static final int NO_RESTART = 0;
053    static final int WITH_RESTART = 1;
054    static final int WITH_RESTART_AND_LONG_WAIT = 2000;
055
056    static final boolean FILE_OPTION_SET = true;
057    static final boolean FILE_OPTION_BLANK = false;
058
059    RollingFileAppender<Object> rfa1 = new RollingFileAppender<Object>();
060    TimeBasedRollingPolicy<Object> tbrp1 = new TimeBasedRollingPolicy<Object>();
061
062    RollingFileAppender<Object> rfa2 = new RollingFileAppender<Object>();
063    TimeBasedRollingPolicy<Object> tbrp2 = new TimeBasedRollingPolicy<Object>();
064
065    EchoEncoder<Object> encoder = new EchoEncoder<Object>();
066
067    RolloverChecker rolloverChecker;
068
069    @Before
070    @Override
071    public void setUp() {
072        super.setUp();
073    }
074
075    @After
076    public void tearDown() {
077    }
078
079    void initRFA(RollingFileAppender<Object> rfa, String filename) {
080        rfa.setContext(context);
081        rfa.setEncoder(encoder);
082        if (filename != null) {
083            rfa.setFile(filename);
084        }
085    }
086
087    void initTRBP(RollingFileAppender<Object> rfa, TimeBasedRollingPolicy<Object> tbrp, String filenamePattern, long givenTime) {
088        tbrp.setContext(context);
089        tbrp.setFileNamePattern(filenamePattern);
090        tbrp.setParent(rfa);
091        tbrp.timeBasedFileNamingAndTriggeringPolicy = new DefaultTimeBasedFileNamingAndTriggeringPolicy<Object>();
092        tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(givenTime);
093        rfa.setRollingPolicy(tbrp);
094        tbrp.start();
095        rfa.start();
096    }
097
098    void genericTest(String testId, String patternPrefix, String compressionSuffix, boolean fileOptionIsSet, int waitDuration) throws IOException {
099        String fileName = fileOptionIsSet ? testId2FileName(testId) : null;
100        initRFA(rfa1, fileName);
101
102        String fileNamePatternStr = randomOutputDir + patternPrefix + "-%d{" + DATE_PATTERN_WITH_SECONDS + "}" + compressionSuffix;
103
104        initTRBP(rfa1, tbrp1, fileNamePatternStr, currentTime);
105
106        // compute the current filename
107        addExpectedFileName_ByDate(fileNamePatternStr, getMillisOfCurrentPeriodsStart());
108
109        incCurrentTime(1100);
110        tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
111
112        for (int i = 0; i < 3; i++) {
113            rfa1.doAppend("Hello---" + i);
114            addExpectedFileNamedIfItsTime_ByDate(fileNamePatternStr);
115            incCurrentTime(500);
116            tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
117            add(tbrp1.compressionFuture);
118            add(tbrp1.cleanUpFuture);
119        }
120        rfa1.stop();
121        waitForJobsToComplete();
122
123        if (waitDuration != NO_RESTART) {
124            doRestart(testId, patternPrefix, fileOptionIsSet, waitDuration);
125        }
126        waitForJobsToComplete();
127
128        massageExpectedFilesToCorresponToCurrentTarget(fileName, fileOptionIsSet);
129        StatusPrinter.print(context);
130        rolloverChecker.check(expectedFilenameList);
131    }
132
133    void defaultTest(String testId, String patternPrefix, String compressionSuffix, boolean fileOptionIsSet, int waitDuration) throws IOException {
134        boolean withCompression = compressionSuffix.length() > 0;
135        rolloverChecker = new DefaultRolloverChecker(testId, withCompression, compressionSuffix);
136        genericTest(testId, patternPrefix, compressionSuffix, fileOptionIsSet, waitDuration);
137    }
138
139    void doRestart(String testId, String patternPart, boolean fileOptionIsSet, int waitDuration) {
140        // change the timestamp of the currently actively file
141        File activeFile = new File(rfa1.getFile());
142        activeFile.setLastModified(currentTime);
143
144        incCurrentTime(waitDuration);
145
146        String filePatternStr = randomOutputDir + patternPart + "-%d{" + DATE_PATTERN_WITH_SECONDS + "}";
147
148        String fileName = fileOptionIsSet ? testId2FileName(testId) : null;
149        initRFA(rfa2, fileName);
150        initTRBP(rfa2, tbrp2, filePatternStr, currentTime);
151        for (int i = 0; i < 3; i++) {
152            rfa2.doAppend("World---" + i);
153            addExpectedFileNamedIfItsTime_ByDate(filePatternStr);
154            incCurrentTime(100);
155            tbrp2.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
156            add(tbrp2.compressionFuture);
157            add(tbrp1.cleanUpFuture);
158        }
159        rfa2.stop();
160    }
161
162    @Test
163    public void noCompression_FileBlank_NoRestart_1() throws IOException {
164        defaultTest("test1", "test1", "", FILE_OPTION_BLANK, NO_RESTART);
165    }
166
167    @Test
168    public void withCompression_FileBlank_NoRestart_2() throws IOException {
169        defaultTest("test2", "test2", ".gz", FILE_OPTION_BLANK, NO_RESTART);
170    }
171
172    @Test
173    public void noCompression_FileBlank_StopRestart_3() throws IOException {
174        defaultTest("test3", "test3", "", FILE_OPTION_BLANK, WITH_RESTART);
175    }
176
177    @Test
178    public void noCompression_FileSet_StopRestart_4() throws IOException {
179        defaultTest("test4", "test4", "", FILE_OPTION_SET, WITH_RESTART);
180    }
181
182    @Test
183    public void noCompression_FileSet_StopRestart_WithLongWait_4B() throws IOException {
184        defaultTest("test4B", "test4B", "", FILE_OPTION_SET, WITH_RESTART_AND_LONG_WAIT);
185    }
186
187    @Test
188    public void noCompression_FileSet_NoRestart_5() throws IOException {
189        defaultTest("test5", "test5", "", FILE_OPTION_SET, NO_RESTART);
190    }
191
192    @Test
193    public void withCompression_FileSet_NoRestart_6() throws IOException {
194        defaultTest("test6", "test6", ".gz", FILE_OPTION_SET, NO_RESTART);
195    }
196
197    // LOGBACK-168
198    @Test
199    public void withMissingTargetDirWithCompression() throws IOException {
200        defaultTest("test7", "%d{yyyy-MM-dd, aux}/test7", ".gz", FILE_OPTION_SET, NO_RESTART);
201    }
202
203    @Test
204    public void withMissingTargetDirWithZipCompression() throws IOException {
205        defaultTest("test8", "%d{yyyy-MM-dd, aux}/test8", ".zip", FILE_OPTION_SET, NO_RESTART);
206    }
207
208    @Test
209    public void failed_rename() throws IOException {
210        if (!EnvUtilForTests.isWindows())
211            return;
212
213        FileOutputStream fos = null;
214        try {
215            String fileName = testId2FileName("failed_rename");
216            File file = new File(fileName);
217            file.getParentFile().mkdirs();
218
219            fos = new FileOutputStream(fileName);
220
221            String testId = "failed_rename";
222            rolloverChecker = new ZRolloverChecker(testId);
223            genericTest(testId, "failed_rename", "", FILE_OPTION_SET, NO_RESTART);
224
225        } finally {
226            StatusPrinter.print(context);
227            if (fos != null)
228                fos.close();
229        }
230    }
231
232    
233    
234}