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.FileInputStream;
18  import java.io.IOException;
19  
20  import ch.qos.logback.core.testUtil.EnvUtilForTests;
21  import org.junit.jupiter.api.AfterEach;
22  import org.junit.jupiter.api.BeforeEach;
23  import org.junit.jupiter.api.Disabled;
24  
25  import ch.qos.logback.core.encoder.EchoEncoder;
26  import ch.qos.logback.core.testUtil.RandomUtil;
27  import ch.qos.logback.core.util.ResilienceUtil;
28  import ch.qos.logback.core.util.StatusPrinter;
29  import org.junit.jupiter.api.Test;
30  
31  @Disabled
32  public class FileAppenderResilience_AS_ROOT_Test {
33  
34      static String MOUNT_POINT = "/mnt/loop/";
35  
36      static String LONG_STR = " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
37  
38      static String PATH_LOOPFS_SCRIPT = "/home/ceki/java/logback/logback-core/src/test/loopfs.sh";
39  
40      enum LoopFSCommand {
41          setup, shake, teardown;
42      }
43  
44      Context context = new ContextBase();
45      int diff = RandomUtil.getPositiveInt();
46      String outputDirStr = MOUNT_POINT + "resilience-" + diff + "/";
47      String logfileStr = outputDirStr + "output.log";
48  
49      FileAppender<Object> fa = new FileAppender<Object>();
50  
51      static boolean isConformingHost() {
52          return EnvUtilForTests.isLocalHostNameInList(new String[] { "haro" });
53      }
54  
55      @BeforeEach
56      public void setUp() throws IOException, InterruptedException {
57          if (!isConformingHost()) {
58              return;
59          }
60          Process p = runLoopFSScript(LoopFSCommand.setup);
61          p.waitFor();
62  
63          dump("/tmp/loopfs.log");
64  
65          fa.setContext(context);
66          File outputDir = new File(outputDirStr);
67          outputDir.mkdirs();
68          System.out.println("FileAppenderResilienceTest output dir [" + outputDirStr + "]");
69  
70          fa.setName("FILE");
71          fa.setEncoder(new EchoEncoder<Object>());
72          fa.setFile(logfileStr);
73          fa.start();
74      }
75  
76      void dump(String file) throws IOException {
77          FileInputStream fis = null;
78          try {
79              fis = new FileInputStream(file);
80              int r;
81              while ((r = fis.read()) != -1) {
82                  char c = (char) r;
83                  System.out.print(c);
84              }
85          } finally {
86              if (fis != null) {
87                  fis.close();
88              }
89          }
90      }
91  
92      @AfterEach
93      public void tearDown() throws IOException, InterruptedException {
94          if (!isConformingHost()) {
95              return;
96          }
97          StatusPrinter.print(context);
98          fa.stop();
99          Process p = runLoopFSScript(LoopFSCommand.teardown);
100         p.waitFor();
101         System.out.println("Tearing down");
102     }
103 
104     static int TOTAL_DURATION = 5000;
105     static int NUM_STEPS = 500;
106     static int DELAY = TOTAL_DURATION / NUM_STEPS;
107 
108     @Test
109     public void go() throws IOException, InterruptedException {
110         if (!isConformingHost()) {
111             return;
112         }
113         Process p = runLoopFSScript(LoopFSCommand.shake);
114         for (int i = 0; i < NUM_STEPS; i++) {
115             fa.append(String.valueOf(i) + LONG_STR);
116             Thread.sleep(DELAY);
117         }
118         p.waitFor();
119         // the external script has the file system ready for IO 50% of the time
120         double bestCase = 0.5;
121         ResilienceUtil.countLines(logfileStr, "^(\\d{1,3}) x*$");
122         System.out.println("Done go");
123     }
124 
125     // the loopfs script is tightly coupled with the host machine
126     // it needs to be Unix, with sudo privileges granted to the script
127     Process runLoopFSScript(LoopFSCommand cmd) throws IOException, InterruptedException {
128         // causing a NullPointerException is better than locking the whole
129         // machine which the next operation can and will do.
130         if (!isConformingHost()) {
131             return null;
132         }
133         ProcessBuilder pb = new ProcessBuilder();
134         pb.command("/usr/bin/sudo", PATH_LOOPFS_SCRIPT, cmd.toString());
135         return pb.start();
136     }
137 }