View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.io.output;
18  
19  import static org.junit.jupiter.api.Assertions.assertFalse;
20  import static org.junit.jupiter.api.Assertions.assertNotNull;
21  import static org.junit.jupiter.api.Assertions.assertThrows;
22  import static org.junit.jupiter.api.Assertions.assertTrue;
23  import static org.junit.jupiter.api.Assertions.fail;
24  
25  import java.io.File;
26  import java.io.IOException;
27  import java.nio.charset.StandardCharsets;
28  import java.nio.charset.UnsupportedCharsetException;
29  
30  import org.apache.commons.io.FileUtils;
31  import org.junit.jupiter.api.BeforeEach;
32  import org.junit.jupiter.api.Test;
33  import org.junit.jupiter.api.io.TempDir;
34  
35  /**
36   * Tests {@link LockableFileWriter}.
37   * <p>
38   * Tests that files really lock, although no writing is done as the locking is tested only on construction.
39   * </p>
40   */
41  public class LockableFileWriterTest {
42  
43      @TempDir
44      public File temporaryFolder;
45  
46      private File file;
47      private File lockDir;
48      private File lockFile;
49      private File altLockDir;
50      private File altLockFile;
51  
52      @BeforeEach
53      public void setUp() {
54          file = new File(temporaryFolder, "testlockfile");
55          lockDir = FileUtils.getTempDirectory();
56          lockFile = new File(lockDir, file.getName() + ".lck");
57          altLockDir = temporaryFolder;
58          altLockFile = new File(altLockDir, file.getName() + ".lck");
59      }
60  
61      @Test
62      public void testAlternateLockDir() throws IOException {
63          // open a valid lockable writer
64          try (LockableFileWriter lfw1 = new LockableFileWriter(file, StandardCharsets.UTF_8, true, altLockDir.getAbsolutePath())) {
65              testAlternateLockDir(lfw1);
66          }
67          assertTrue(file.exists());
68          assertFalse(altLockFile.exists());
69          //
70          // open a valid lockable writer
71          // @formatter:off
72          try (LockableFileWriter lfw1 = LockableFileWriter.builder()
73                  .setFile(file)
74                  .setCharset(StandardCharsets.UTF_8)
75                  .setAppend(true)
76                  .setLockDirectory(altLockDir)
77                  .get()) {
78              // @formatter:on
79              testAlternateLockDir(lfw1);
80          }
81          assertTrue(file.exists());
82          assertFalse(altLockFile.exists());
83      }
84  
85      private void testAlternateLockDir(final LockableFileWriter lfw1) {
86          assertNotNull(lfw1);
87          assertTrue(file.exists());
88          assertTrue(altLockFile.exists());
89  
90          // try to open a second writer
91          try (LockableFileWriter lfw2 = new LockableFileWriter(file, StandardCharsets.UTF_8, true, altLockDir.getAbsolutePath())) {
92              fail("Somehow able to open a locked file. ");
93          } catch (final IOException ioe) {
94              final String msg = ioe.getMessage();
95              assertTrue(msg.startsWith("Can't write file, lock "), "Exception message does not start correctly. ");
96              assertTrue(file.exists());
97              assertTrue(altLockFile.exists());
98          }
99      }
100 
101     @Test
102     public void testConstructor_File_directory() {
103         assertThrows(IOException.class, () -> new LockableFileWriter(temporaryFolder));
104         assertFalse(file.exists());
105         assertFalse(lockFile.exists());
106         // again
107         assertFalse(file.exists());
108         assertFalse(lockFile.exists());
109     }
110 
111     @Test
112     public void testConstructor_File_encoding_badEncoding() {
113         assertThrows(UnsupportedCharsetException.class, () -> new LockableFileWriter(file, "BAD-ENCODE"));
114         assertFalse(file.exists());
115         assertFalse(lockFile.exists());
116         // again
117         assertFalse(file.exists());
118         assertFalse(lockFile.exists());
119         //
120         assertThrows(UnsupportedCharsetException.class, () -> LockableFileWriter.builder().setFile(file).setCharset("BAD-ENCODE").get());
121         assertFalse(file.exists());
122         assertFalse(lockFile.exists());
123         // again
124         assertFalse(file.exists());
125         assertFalse(lockFile.exists());
126     }
127 
128     @Test
129     public void testConstructor_File_nullFile() {
130         assertThrows(NullPointerException.class, () -> new LockableFileWriter((File) null));
131         assertFalse(file.exists());
132         assertFalse(lockFile.exists());
133         // again
134         assertFalse(file.exists());
135         assertFalse(lockFile.exists());
136         //
137         assertThrows(IllegalStateException.class, () -> LockableFileWriter.builder().get());
138         assertFalse(file.exists());
139         assertFalse(lockFile.exists());
140         // again
141         assertFalse(file.exists());
142         assertFalse(lockFile.exists());
143 
144     }
145 
146     @Test
147     public void testConstructor_fileName_nullFile() {
148         assertThrows(NullPointerException.class, () -> new LockableFileWriter((String) null));
149         assertFalse(file.exists());
150         assertFalse(lockFile.exists());
151         // again
152         assertFalse(file.exists());
153         assertFalse(lockFile.exists());
154     }
155 
156     @Test
157     public void testFileLocked() throws IOException {
158 
159         // open a valid lockable writer
160         try (LockableFileWriter lfw1 = new LockableFileWriter(file)) {
161             assertTrue(file.exists());
162             assertTrue(lockFile.exists());
163 
164             // try to open a second writer
165             try (LockableFileWriter lfw2 = new LockableFileWriter(file)) {
166                 fail("Somehow able to open a locked file. ");
167             } catch (final IOException ioe) {
168                 final String msg = ioe.getMessage();
169                 assertTrue(msg.startsWith("Can't write file, lock "), "Exception message does not start correctly. ");
170                 assertTrue(file.exists());
171                 assertTrue(lockFile.exists());
172             }
173 
174             // try to open a third writer
175             try (LockableFileWriter lfw3 = new LockableFileWriter(file)) {
176                 fail("Somehow able to open a locked file. ");
177             } catch (final IOException ioe) {
178                 final String msg = ioe.getMessage();
179                 assertTrue(msg.startsWith("Can't write file, lock "), "Exception message does not start correctly. ");
180                 assertTrue(file.exists());
181                 assertTrue(lockFile.exists());
182             }
183         }
184         assertTrue(file.exists());
185         assertFalse(lockFile.exists());
186     }
187 
188     @Test
189     public void testFileNotLocked() throws IOException {
190         // open a valid lockable writer
191         try (LockableFileWriter lfw1 = new LockableFileWriter(file)) {
192             assertTrue(file.exists());
193             assertTrue(lockFile.exists());
194         }
195         assertTrue(file.exists());
196         assertFalse(lockFile.exists());
197 
198         // open a second valid writer on the same file
199         try (LockableFileWriter lfw2 = new LockableFileWriter(file)) {
200             assertTrue(file.exists());
201             assertTrue(lockFile.exists());
202         }
203         assertTrue(file.exists());
204         assertFalse(lockFile.exists());
205     }
206 
207 }