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 ch.qos.logback.core.Context;
17  import ch.qos.logback.core.ContextBase;
18  import ch.qos.logback.core.encoder.EchoEncoder;
19  import ch.qos.logback.core.encoder.Encoder;
20  import ch.qos.logback.core.rolling.helper.RenameUtil;
21  import ch.qos.logback.core.testUtil.CoreTestConstants;
22  import ch.qos.logback.core.testUtil.RandomUtil;
23  import ch.qos.logback.core.status.testUtil.StatusChecker;
24  import ch.qos.logback.core.util.EnvUtil;
25  import ch.qos.logback.core.util.StatusPrinter;
26  
27  import ch.qos.logback.core.util.StatusPrinter2;
28  import org.junit.jupiter.api.BeforeEach;
29  import org.junit.jupiter.api.Disabled;
30  import org.junit.jupiter.api.Test;
31  
32  import java.io.File;
33  import java.io.FileInputStream;
34  import java.io.FileNotFoundException;
35  import java.io.FileOutputStream;
36  import java.io.IOException;
37  import java.nio.channels.FileLock;
38  
39  import static org.junit.jupiter.api.Assertions.assertEquals;
40  import static org.junit.jupiter.api.Assertions.assertTrue;
41  
42  public class RenameUtilTest {
43  
44      Encoder<Object> encoder;
45      Context context = new ContextBase();
46      StatusChecker statusChecker = new StatusChecker(context);
47      StatusPrinter2 statusPrinter2 = new StatusPrinter2();
48  
49      long currentTime = System.currentTimeMillis();
50      int diff = RandomUtil.getPositiveInt();
51      protected String randomOutputDirAsStr = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + "/";
52      protected File randomOutputDir = new File(randomOutputDirAsStr);
53  
54      @BeforeEach
55      public void setUp() throws Exception {
56          encoder = new EchoEncoder<Object>();
57          // if this the fist test run after 'build clean up' then the
58          // OUTPUT_DIR_PREFIX might be not yet created
59          randomOutputDir.mkdirs();
60      }
61  
62      @Test
63      public void renameToNonExistingDirectory() throws IOException, RolloverFailure {
64          RenameUtil renameUtil = new RenameUtil();
65          renameUtil.setContext(context);
66  
67          int diff2 = RandomUtil.getPositiveInt();
68          File fromFile = File.createTempFile("from" + diff, "test", randomOutputDir);
69  
70          String randomTARGETDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff2;
71  
72          renameUtil.rename(fromFile.toString(), new File(randomTARGETDir + "/to.test").toString());
73          statusPrinter2.printInCaseOfErrorsOrWarnings(context);
74          assertTrue(statusChecker.isErrorFree(0));
75      }
76  
77      @Test // LOGBACK-1054
78      public void renameLockedAbstractFile_LOGBACK_1054() throws IOException, RolloverFailure {
79  
80          // this tests only works on windows
81          if(!EnvUtil.isWindows()) {
82              return;
83          }
84  
85          RenameUtil renameUtil = new RenameUtil();
86          renameUtil.setContext(context);
87  
88          String abstractFileName = "abstract_pathname-" + diff;
89  
90          String src = CoreTestConstants.OUTPUT_DIR_PREFIX + abstractFileName;
91          String target = abstractFileName + ".target";
92  
93          makeFile(src);
94  
95          // open file in a way preventing simple rename in order to force call to
96          // areOnDifferentVolumes() method. This only works on Windows
97  
98          FileInputStream fis = new FileInputStream(src);
99          renameUtil.rename(src, target);
100         // release the lock
101         fis.close();
102 
103         statusPrinter2.print(context);
104         assertEquals(0, statusChecker.matchCount("Parent of target file ." + target + ". is null"));
105     }
106 
107     @Test
108     @Disabled
109     public void MANUAL_renamingOnDifferentVolumesOnLinux() throws IOException, RolloverFailure {
110         RenameUtil renameUtil = new RenameUtil();
111         renameUtil.setContext(context);
112 
113         String src = "/tmp/ramdisk/foo.txt";
114         makeFile(src);
115 
116         renameUtil.rename(src, "/tmp/foo" + diff + ".txt");
117         statusPrinter2.print(context);
118     }
119 
120     @Test
121     @Disabled
122     public void MANUAL_renamingOnDifferentVolumesOnWindows() throws IOException, RolloverFailure {
123         RenameUtil renameUtil = new RenameUtil();
124         renameUtil.setContext(context);
125 
126         String src = "c:/tmp/foo.txt";
127         makeFile(src);
128 
129         renameUtil.rename(src, "d:/tmp/foo" + diff + ".txt");
130         statusPrinter2.print(context);
131         assertTrue(statusChecker.isErrorFree(0));
132     }
133 
134     private void makeFile(String src) throws FileNotFoundException, IOException {
135 
136         FileOutputStream fos = new FileOutputStream(src);
137         fos.write(("hello" + diff).getBytes());
138         fos.close();
139     }
140 
141 }