View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.core.rolling;
15  
16  import static org.junit.Assert.assertFalse;
17  
18  import java.io.File;
19  import java.io.IOException;
20  import java.util.Date;
21  import java.util.List;
22  import java.util.concurrent.ExecutionException;
23  
24  import org.junit.Before;
25  import org.junit.Test;
26  
27  import ch.qos.logback.core.encoder.EchoEncoder;
28  import ch.qos.logback.core.rolling.testUtil.ScaffoldingForRollingTests;
29  import ch.qos.logback.core.status.InfoStatus;
30  import ch.qos.logback.core.status.StatusManager;
31  import ch.qos.logback.core.testUtil.StatusChecker;
32  import ch.qos.logback.core.util.FileSize;
33  
34  public class SizeAndTimeBasedFNATP_Test extends ScaffoldingForRollingTests {
35      private SizeAndTimeBasedFNATP<Object> sizeAndTimeBasedFNATP = null;
36      private RollingFileAppender<Object> rfa1 = new RollingFileAppender<Object>();
37      private TimeBasedRollingPolicy<Object> tbrp1 = new TimeBasedRollingPolicy<Object>();
38      private RollingFileAppender<Object> rfa2 = new RollingFileAppender<Object>();
39      private TimeBasedRollingPolicy<Object> tbrp2 = new TimeBasedRollingPolicy<Object>();
40  
41      private EchoEncoder<Object> encoder = new EchoEncoder<Object>();
42      int fileSize = 0;
43      int fileIndexCounter = 0;
44      int sizeThreshold = 0;
45  
46      @Before
47      public void setUp() {
48          super.setUp();
49      }
50  
51      private void initRollingFileAppender(RollingFileAppender<Object> rfa, String filename) {
52          rfa.setContext(context);
53          rfa.setEncoder(encoder);
54          if (filename != null) {
55              rfa.setFile(filename);
56          }
57      }
58  
59      private void initPolicies(RollingFileAppender<Object> rfa, TimeBasedRollingPolicy<Object> tbrp, String filenamePattern, int sizeThreshold, long givenTime,
60                      long lastCheck) {
61          sizeAndTimeBasedFNATP = new SizeAndTimeBasedFNATP<Object>();
62          tbrp.setContext(context);
63          sizeAndTimeBasedFNATP.setMaxFileSize(new FileSize(sizeThreshold));
64          tbrp.setTimeBasedFileNamingAndTriggeringPolicy(sizeAndTimeBasedFNATP);
65          tbrp.setFileNamePattern(filenamePattern);
66          tbrp.setParent(rfa);
67          tbrp.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(givenTime);
68          rfa.setRollingPolicy(tbrp);
69          tbrp.start();
70          rfa.start();
71      }
72  
73      private void addExpectedFileNamedIfItsTime(String randomOutputDir, String testId, String msg, String compressionSuffix) {
74          fileSize = fileSize + msg.getBytes().length;
75          if (passThresholdTime(nextRolloverThreshold)) {
76              fileIndexCounter = 0;
77              fileSize = 0;
78              addExpectedFileName_ByFileIndexCounter(randomOutputDir, testId, getMillisOfCurrentPeriodsStart(), fileIndexCounter, compressionSuffix);
79              recomputeRolloverThreshold(currentTime);
80              return;
81          }
82  
83          // windows can delay file size changes, so we only allow for fileIndexCounter 0
84          if ((fileIndexCounter == 0) && fileSize > sizeThreshold) {
85              addExpectedFileName_ByFileIndexCounter(randomOutputDir, testId, getMillisOfCurrentPeriodsStart(), fileIndexCounter, compressionSuffix);
86              fileIndexCounter = fileIndexCounter + 1;
87              fileSize = 0;
88          }
89      }
90  
91      void generic(String testId, String stem, boolean withSecondPhase, String compressionSuffix) throws IOException, InterruptedException, ExecutionException {
92          String file = (stem != null) ? randomOutputDir + stem : null;
93          initRollingFileAppender(rfa1, file);
94          sizeThreshold = 300;
95  
96          initPolicies(rfa1, tbrp1, randomOutputDir + testId + "-%d{" + DATE_PATTERN_WITH_SECONDS + "}-%i.txt" + compressionSuffix, sizeThreshold, currentTime, 0);
97          addExpectedFileName_ByFileIndexCounter(randomOutputDir, testId, getMillisOfCurrentPeriodsStart(), fileIndexCounter, compressionSuffix);
98          incCurrentTime(100);
99          tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
100         int runLength = 100;
101         String prefix = "Hello -----------------";
102 
103         for (int i = 0; i < runLength; i++) {
104             String msg = prefix + i;
105             rfa1.doAppend(msg);
106             addExpectedFileNamedIfItsTime(randomOutputDir, testId, msg, compressionSuffix);
107             incCurrentTime(20);
108             tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
109             add(tbrp1.compressionFuture);
110             add(tbrp1.cleanUpFuture);
111         }
112 
113         if (withSecondPhase) {
114             secondPhase(testId, file, stem, compressionSuffix, runLength, prefix);
115             runLength = runLength * 2;
116         }
117 
118         if (stem != null)
119             massageExpectedFilesToCorresponToCurrentTarget(file, true);
120 
121         Thread.yield();
122         // wait for compression to finish
123         waitForJobsToComplete();
124 
125         // StatusPrinter.print(context);
126         existenceCheck(expectedFilenameList);
127         sortedContentCheck(randomOutputDir, runLength, prefix);
128     }
129 
130     void secondPhase(String testId, String file, String stem, String compressionSuffix, int runLength, String prefix) {
131         rfa1.stop();
132 
133         if (stem != null) {
134             File f = new File(file);
135             f.setLastModified(currentTime);
136         }
137 
138         StatusManager sm = context.getStatusManager();
139         sm.add(new InfoStatus("Time when rfa1 is stopped: " + new Date(currentTime), this));
140         sm.add(new InfoStatus("currentTime%1000=" + (currentTime % 1000), this));
141 
142         initRollingFileAppender(rfa2, file);
143         initPolicies(rfa2, tbrp2, randomOutputDir + testId + "-%d{" + DATE_PATTERN_WITH_SECONDS + "}-%i.txt" + compressionSuffix, sizeThreshold, currentTime, 0);
144 
145         for (int i = runLength; i < runLength * 2; i++) {
146             incCurrentTime(100);
147             tbrp2.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
148             String msg = prefix + i;
149             rfa2.doAppend(msg);
150             addExpectedFileNamedIfItsTime(randomOutputDir, testId, msg, compressionSuffix);
151         }
152     }
153 
154     static final boolean FIRST_PHASE_ONLY = false;
155     static final boolean WITH_SECOND_PHASE = true;
156     static final String DEFAULT_COMPRESSION_SUFFIX = "";
157 
158     @Test
159     public void noCompression_FileSet_NoRestart_1() throws InterruptedException, ExecutionException, IOException {
160         generic("test1", "toto.log", FIRST_PHASE_ONLY, DEFAULT_COMPRESSION_SUFFIX);
161     }
162 
163     @Test
164     public void noCompression_FileBlank_NoRestart_2() throws Exception {
165         generic("test2", null, FIRST_PHASE_ONLY, DEFAULT_COMPRESSION_SUFFIX);
166     }
167 
168     @Test
169     public void noCompression_FileBlank_WithStopStart_3() throws Exception {
170         generic("test3", null, WITH_SECOND_PHASE, DEFAULT_COMPRESSION_SUFFIX); 
171     }
172 
173     @Test
174     public void noCompression_FileSet_WithStopStart_4() throws Exception {
175         generic("test4", "test4.log", WITH_SECOND_PHASE, DEFAULT_COMPRESSION_SUFFIX);
176     }
177 
178     @Test
179     public void withGZCompression_FileSet_NoRestart_5() throws Exception {
180         generic("test5", "toto.log", FIRST_PHASE_ONLY, ".gz");
181     }
182 
183     @Test
184     public void withGZCompression_FileBlank_NoRestart_6() throws Exception {
185         generic("test6", null, FIRST_PHASE_ONLY, ".gz");
186     }
187 
188     @Test
189     public void withZipCompression_FileSet_NoRestart_7() throws Exception {
190         generic("test7", "toto.log", FIRST_PHASE_ONLY, ".zip");
191         List<String> zipFiles = filterElementsInListBySuffix(".zip");
192         checkZipEntryMatchesZipFilename(zipFiles);
193     }
194 
195     @Test
196     public void checkMissingIntToken() {
197         String stem = "toto.log";
198         String testId = "checkMissingIntToken";
199         String compressionSuffix = "gz";
200 
201         String file = (stem != null) ? randomOutputDir + stem : null;
202         initRollingFileAppender(rfa1, file);
203         sizeThreshold = 300;
204         initPolicies(rfa1, tbrp1, randomOutputDir + testId + "-%d{" + DATE_PATTERN_WITH_SECONDS + "}.txt" + compressionSuffix, sizeThreshold, currentTime, 0);
205 
206         // StatusPrinter.print(context);
207         assertFalse(rfa1.isStarted());
208         StatusChecker checker = new StatusChecker(context);
209         checker.assertContainsMatch("Missing integer token");
210     }
211 
212     @Test
213     public void checkDateCollision() {
214         String stem = "toto.log";
215         String testId = "checkDateCollision";
216         String compressionSuffix = "gz";
217 
218         String file = (stem != null) ? randomOutputDir + stem : null;
219         initRollingFileAppender(rfa1, file);
220         sizeThreshold = 300;
221         initPolicies(rfa1, tbrp1, randomOutputDir + testId + "-%d{EE}.txt" + compressionSuffix, sizeThreshold, currentTime, 0);
222 
223         // StatusPrinter.print(context);
224         assertFalse(rfa1.isStarted());
225         StatusChecker checker = new StatusChecker(context);
226         checker.assertContainsMatch("The date format in FileNamePattern");
227     }
228 
229     // @Test
230     // public void testHistoryAsFileCount() throws IOException {
231     // String testId = "testHistoryAsFileCount";
232     // int maxHistory = 10;
233     // initRollingFileAppender(rfa1, randomOutputDir + "~" + testId);
234     // sizeThreshold = 50;
235     // System.out.println("testHistoryAsFileCount started on "+new Date(currentTime));
236     // initPolicies(rfa1, tbrp1, randomOutputDir + testId + "-%d{" + DATE_PATTERN_WITH_SECONDS + "}-%i.txt",
237     // sizeThreshold, currentTime, 0, maxHistory, true);
238     //
239     // incCurrentTime(100);
240     // tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
241     // int runLength = 1000;
242     //
243     // for (int i = 0; i < runLength; i++) {
244     // String msg = "" + i;
245     // rfa1.doAppend(msg);
246     // incCurrentTime(20);
247     // tbrp1.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime);
248     // add(tbrp1.future);
249     // }
250     //
251     // Thread.yield();
252     // // wait for compression to finish
253     // waitForJobsToComplete();
254     //
255     // assertEquals(maxHistory + 1, getFilesInDirectory(randomOutputDir).length);
256     // sortedContentCheck(randomOutputDir, 1000, "", 863);
257     // }
258 }