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    *      https://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  
18  package org.apache.commons.io.file;
19  
20  import static org.apache.commons.io.file.CounterAssertions.assertCounts;
21  import static org.junit.jupiter.api.Assertions.assertFalse;
22  import static org.junit.jupiter.api.Assertions.assertThrows;
23  import static org.junit.jupiter.api.Assertions.assertTrue;
24  import static org.junit.jupiter.api.Assumptions.assumeFalse;
25  
26  import java.io.IOException;
27  import java.nio.file.Files;
28  import java.nio.file.LinkOption;
29  import java.nio.file.NoSuchFileException;
30  import java.nio.file.Path;
31  import java.nio.file.Paths;
32  
33  import org.apache.commons.io.file.Counters.PathCounters;
34  import org.apache.commons.lang3.SystemUtils;
35  import org.junit.jupiter.api.Test;
36  
37  /**
38   * Tests {@link DeletingPathVisitor}.
39   */
40  class PathUtilsDeleteFileTest extends AbstractTempDirTest {
41  
42      @Test
43      void testDeleteBrokenSymbolicLink() throws IOException {
44          assumeFalse(SystemUtils.IS_OS_WINDOWS);
45          final Path missingFile = tempDirPath.resolve("missing.txt");
46          final Path brokenLink = tempDirPath.resolve("broken.txt");
47          Files.createSymbolicLink(brokenLink, missingFile);
48          assertTrue(Files.exists(brokenLink, LinkOption.NOFOLLOW_LINKS));
49          assertFalse(Files.exists(missingFile, LinkOption.NOFOLLOW_LINKS));
50          PathUtils.deleteFile(brokenLink);
51          assertFalse(Files.exists(brokenLink, LinkOption.NOFOLLOW_LINKS), "Symbolic link not removed");
52      }
53  
54      /**
55       * Tests a directory with one file of size 0.
56       */
57      @Test
58      void testDeleteFileDirectory1FileSize0() throws IOException {
59          final String fileName = "file-size-0.bin";
60          PathUtils.copyFileToDirectory(Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-0/" + fileName), tempDirPath);
61          assertCounts(0, 1, 0, PathUtils.deleteFile(tempDirPath.resolve(fileName)));
62          // This will throw if not empty.
63          Files.deleteIfExists(tempDirPath);
64      }
65  
66      /**
67       * Tests a directory with one file of size 1.
68       */
69      @Test
70      void testDeleteFileDirectory1FileSize1() throws IOException {
71          final String fileName = "file-size-1.bin";
72          PathUtils.copyFileToDirectory(Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-1/" + fileName), tempDirPath);
73          assertCounts(0, 1, 1, PathUtils.deleteFile(tempDirPath.resolve(fileName)));
74          // This will throw if not empty.
75          Files.deleteIfExists(tempDirPath);
76      }
77  
78      /**
79       * Tests a file that does not exist.
80       */
81      @Test
82      void testDeleteFileDoesNotExist() throws IOException {
83          testDeleteFileEmpty(PathUtils.deleteFile(tempDirPath.resolve("file-does-not-exist.bin")));
84          // This will throw if not empty.
85          Files.deleteIfExists(tempDirPath);
86      }
87  
88      private void testDeleteFileEmpty(final PathCounters pathCounts) {
89          assertCounts(0, 0, 0, pathCounts);
90      }
91  
92      /**
93       * Tests an empty folder.
94       */
95      @Test
96      void testDeleteFileEmptyDirectory() throws IOException {
97          assertThrows(NoSuchFileException.class, () -> testDeleteFileEmpty(PathUtils.deleteFile(tempDirPath)));
98          // This will throw if not empty.
99          Files.deleteIfExists(tempDirPath);
100     }
101 
102     /**
103      * Tests a directory with one file of size 1.
104      */
105     @Test
106     void testDeleteReadOnlyFileDirectory1FileSize1() throws IOException {
107         final String fileName = "file-size-1.bin";
108         PathUtils.copyFileToDirectory(Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-1/" + fileName), tempDirPath);
109         final Path resolved = tempDirPath.resolve(fileName);
110         PathUtils.setReadOnly(resolved, true);
111         if (SystemUtils.IS_OS_WINDOWS) {
112             // Fails on Windows's Ubuntu subsystem.
113             assertFalse(Files.isWritable(resolved));
114             assertThrows(IOException.class, () -> PathUtils.deleteFile(resolved));
115         }
116         assertCounts(0, 1, 1, PathUtils.deleteFile(resolved, StandardDeleteOption.OVERRIDE_READ_ONLY));
117         // This will throw if not empty.
118         Files.deleteIfExists(tempDirPath);
119     }
120 
121     /**
122      * Tests a directory with one file of size 1.
123      */
124     @Test
125     void testSetReadOnlyFileDirectory1FileSize1() throws IOException {
126         final String fileName = "file-size-1.bin";
127         PathUtils.copyFileToDirectory(Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-1/" + fileName), tempDirPath);
128         final Path resolved = tempDirPath.resolve(fileName);
129         PathUtils.setReadOnly(resolved, true);
130         if (SystemUtils.IS_OS_WINDOWS) {
131             // Fails on Windows's Ubuntu subsystem.
132             assertFalse(Files.isWritable(resolved));
133             assertThrows(IOException.class, () -> PathUtils.deleteFile(resolved));
134         }
135         PathUtils.setReadOnly(resolved, false);
136         PathUtils.deleteFile(resolved);
137         // This will throw if not empty.
138         Files.deleteIfExists(tempDirPath);
139     }
140 }