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;
15  
16  import java.io.File;
17  import java.io.IOException;
18  import java.nio.channels.FileChannel;
19  
20  import org.junit.Before;
21  import org.junit.Ignore;
22  import org.junit.Test;
23  
24  import ch.qos.logback.core.contention.RunnableWithCounterAndDone;
25  import ch.qos.logback.core.encoder.EchoEncoder;
26  import ch.qos.logback.core.recovery.RecoveryCoordinator;
27  import ch.qos.logback.core.recovery.ResilientFileOutputStream;
28  import ch.qos.logback.core.status.OnConsoleStatusListener;
29  import ch.qos.logback.core.testUtil.CoreTestConstants;
30  import ch.qos.logback.core.testUtil.RandomUtil;
31  import ch.qos.logback.core.util.ResilienceUtil;
32  
33  public class FileAppenderResilienceTest {
34  
35      FileAppender<Object> fa = new FileAppender<Object>();
36      Context context = new ContextBase();
37      int diff = RandomUtil.getPositiveInt();
38      String outputDirStr = CoreTestConstants.OUTPUT_DIR_PREFIX + "resilience-" + diff + "/";
39  
40      // String outputDirStr = "\\\\192.168.1.3\\lbtest\\" + "resilience-"+ diff +
41      // "/";;
42      String logfileStr = outputDirStr + "output.log";
43  
44      @Before
45      public void setUp() throws InterruptedException {
46  
47          context.getStatusManager().add(new OnConsoleStatusListener());
48  
49          File outputDir = new File(outputDirStr);
50          outputDir.mkdirs();
51  
52          fa.setContext(context);
53          fa.setName("FILE");
54          fa.setEncoder(new EchoEncoder<Object>());
55          fa.setFile(logfileStr);
56          fa.start();
57      }
58  
59      @Test
60      @Ignore
61      public void manual() throws InterruptedException, IOException {
62          Runner runner = new Runner(fa);
63          Thread t = new Thread(runner);
64          t.start();
65  
66          while (true) {
67              Thread.sleep(110);
68          }
69      }
70  
71      @Test
72      public void smoke() throws InterruptedException, IOException {
73          Runner runner = new Runner(fa);
74          Thread t = new Thread(runner);
75          t.start();
76  
77          double delayCoefficient = 2.0;
78          for (int i = 0; i < 5; i++) {
79              Thread.sleep((int) (RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN * delayCoefficient));
80              closeLogFileOnPurpose();
81          }
82          runner.setDone(true);
83          t.join();
84  
85          double bestCaseSuccessRatio = 1 / delayCoefficient;
86          // expect to loose at most 35% of the events
87          double lossinessFactor = 0.35;
88          double resilianceFactor = (1 - lossinessFactor);
89  
90          ResilienceUtil.verify(logfileStr, "^hello (\\d{1,5})$", runner.getCounter(), bestCaseSuccessRatio * resilianceFactor);
91      }
92  
93      private void closeLogFileOnPurpose() throws IOException {
94          ResilientFileOutputStream resilientFOS = (ResilientFileOutputStream) fa.getOutputStream();
95          FileChannel fileChannel = resilientFOS.getChannel();
96          fileChannel.close();
97      }
98  }
99  
100 class Runner extends RunnableWithCounterAndDone {
101     FileAppender<Object> fa;
102 
103     Runner(FileAppender<Object> fa) {
104         this.fa = fa;
105     }
106 
107     public void run() {
108         while (!isDone()) {
109             counter++;
110             fa.doAppend("hello " + counter);
111             if (counter % 128 == 0) {
112                 try {
113                     Thread.sleep(10);
114                 } catch (InterruptedException e) {
115                 }
116             }
117         }
118     }
119 
120 }