1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.io;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertTrue;
22
23 import java.io.File;
24 import java.util.ArrayList;
25 import java.util.List;
26
27 import org.apache.commons.lang3.ArrayUtils;
28 import org.apache.commons.lang3.SystemProperties;
29 import org.junit.jupiter.api.Test;
30 import org.junit.jupiter.api.io.TempDir;
31
32
33
34
35
36 public class FileUtilsCleanSymlinksTest {
37
38 @TempDir
39 public File top;
40
41 private boolean setupSymlink(final File res, final File link) throws Exception {
42
43 final List<String> args = new ArrayList<>();
44 args.add("ln");
45 args.add("-s");
46
47 args.add(res.getAbsolutePath());
48 args.add(link.getAbsolutePath());
49
50 final Process proc;
51
52 proc = Runtime.getRuntime().exec(args.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
53 return proc.waitFor() == 0;
54 }
55
56 @Test
57 public void testCleanDirWithASymlinkDir() throws Exception {
58 if (SystemProperties.getOsName().startsWith("Win")) {
59
60 return;
61 }
62
63 final File realOuter = new File(top, "realouter");
64 assertTrue(realOuter.mkdirs());
65
66 final File realInner = new File(realOuter, "realinner");
67 assertTrue(realInner.mkdirs());
68
69 FileUtils.touch(new File(realInner, "file1"));
70 assertEquals(1, realInner.list().length);
71
72 final File randomDirectory = new File(top, "randomDir");
73 assertTrue(randomDirectory.mkdirs());
74
75 FileUtils.touch(new File(randomDirectory, "randomfile"));
76 assertEquals(1, randomDirectory.list().length);
77
78 final File symlinkDirectory = new File(realOuter, "fakeinner");
79 assertTrue(setupSymlink(randomDirectory, symlinkDirectory));
80
81 assertEquals(1, symlinkDirectory.list().length);
82
83
84 FileUtils.cleanDirectory(realOuter);
85 assertEquals(0, realOuter.list().length);
86
87
88 assertEquals(1, randomDirectory.list().length, "Contents of symbolic link should not have been removed");
89 }
90
91 @Test
92 public void testCleanDirWithParentSymlinks() throws Exception {
93 if (SystemProperties.getOsName().startsWith("Win")) {
94
95 return;
96 }
97
98 final File realParent = new File(top, "realparent");
99 assertTrue(realParent.mkdirs());
100
101 final File realInner = new File(realParent, "realinner");
102 assertTrue(realInner.mkdirs());
103
104 FileUtils.touch(new File(realInner, "file1"));
105 assertEquals(1, realInner.list().length);
106
107 final File randomDirectory = new File(top, "randomDir");
108 assertTrue(randomDirectory.mkdirs());
109
110 FileUtils.touch(new File(randomDirectory, "randomfile"));
111 assertEquals(1, randomDirectory.list().length);
112
113 final File symlinkDirectory = new File(realParent, "fakeinner");
114 assertTrue(setupSymlink(randomDirectory, symlinkDirectory));
115
116 assertEquals(1, symlinkDirectory.list().length);
117
118 final File symlinkParentDirectory = new File(top, "fakeouter");
119 assertTrue(setupSymlink(realParent, symlinkParentDirectory));
120
121
122
123 FileUtils.cleanDirectory(symlinkParentDirectory);
124 assertEquals(0, symlinkParentDirectory.list().length);
125 assertEquals(0, realParent.list().length);
126
127
128 assertEquals(1, randomDirectory.list().length, "Contents of symbolic link should not have been removed");
129 }
130
131 @Test
132 public void testCleanDirWithSymlinkFile() throws Exception {
133 if (SystemProperties.getOsName().startsWith("Win")) {
134
135 return;
136 }
137
138 final File realOuter = new File(top, "realouter");
139 assertTrue(realOuter.mkdirs());
140
141 final File realInner = new File(realOuter, "realinner");
142 assertTrue(realInner.mkdirs());
143
144 final File realFile = new File(realInner, "file1");
145 FileUtils.touch(realFile);
146 assertEquals(1, realInner.list().length);
147
148 final File randomFile = new File(top, "randomfile");
149 FileUtils.touch(randomFile);
150
151 final File symlinkFile = new File(realInner, "fakeinner");
152 assertTrue(setupSymlink(randomFile, symlinkFile));
153
154 assertEquals(2, realInner.list().length);
155
156
157 FileUtils.cleanDirectory(realOuter);
158 assertEquals(0, realOuter.list().length);
159
160
161 assertTrue(randomFile.exists());
162 assertFalse(symlinkFile.exists());
163 }
164
165 @Test
166 public void testCorrectlyIdentifySymlinkWithParentSymLink() throws Exception {
167 if (SystemProperties.getOsName().startsWith("Win")) {
168
169 return;
170 }
171
172 final File realParent = new File(top, "realparent");
173 assertTrue(realParent.mkdirs());
174
175 final File symlinkParentDirectory = new File(top, "fakeparent");
176 assertTrue(setupSymlink(realParent, symlinkParentDirectory));
177
178 final File realChild = new File(symlinkParentDirectory, "realChild");
179 assertTrue(realChild.mkdirs());
180
181 final File symlinkChild = new File(symlinkParentDirectory, "fakeChild");
182 assertTrue(setupSymlink(realChild, symlinkChild));
183
184 assertTrue(FileUtils.isSymlink(symlinkChild));
185 assertFalse(FileUtils.isSymlink(realChild));
186 }
187
188 @Test
189 public void testIdentifiesBrokenSymlinkFile() throws Exception {
190 if (SystemProperties.getOsName().startsWith("Win")) {
191
192 return;
193 }
194
195 final File nonExistentFile = new File(top, "non-existent");
196 final File symlinkFile = new File(top, "fakeinner");
197 final File badSymlinkInPathFile = new File(symlinkFile, "fakeinner");
198 final File nonExistentParentFile = new File("non-existent", "file");
199
200 assertTrue(setupSymlink(nonExistentFile, symlinkFile));
201
202 assertTrue(FileUtils.isSymlink(symlinkFile));
203 assertFalse(FileUtils.isSymlink(nonExistentFile));
204 assertFalse(FileUtils.isSymlink(nonExistentParentFile));
205 assertFalse(FileUtils.isSymlink(badSymlinkInPathFile));
206 }
207
208 @Test
209 public void testIdentifiesSymlinkDir() throws Exception {
210 if (SystemProperties.getOsName().startsWith("Win")) {
211
212 return;
213 }
214
215 final File randomDirectory = new File(top, "randomDir");
216 assertTrue(randomDirectory.mkdirs());
217
218 final File symlinkDirectory = new File(top, "fakeDir");
219 assertTrue(setupSymlink(randomDirectory, symlinkDirectory));
220
221 assertTrue(FileUtils.isSymlink(symlinkDirectory));
222 assertFalse(FileUtils.isSymlink(randomDirectory));
223 }
224
225 @Test
226 public void testIdentifiesSymlinkFile() throws Exception {
227 if (SystemProperties.getOsName().startsWith("Win")) {
228
229 return;
230 }
231
232 final File randomFile = new File(top, "randomfile");
233 FileUtils.touch(randomFile);
234
235 final File symlinkFile = new File(top, "fakeinner");
236 assertTrue(setupSymlink(randomFile, symlinkFile));
237
238 assertTrue(FileUtils.isSymlink(symlinkFile));
239 assertFalse(FileUtils.isSymlink(randomFile));
240 }
241
242 @Test
243 public void testStillClearsIfGivenDirectoryIsASymlink() throws Exception {
244 if (SystemProperties.getOsName().startsWith("Win")) {
245
246 return;
247 }
248
249 final File randomDirectory = new File(top, "randomDir");
250 assertTrue(randomDirectory.mkdirs());
251
252 FileUtils.touch(new File(randomDirectory, "randomfile"));
253 assertEquals(1, randomDirectory.list().length);
254
255 final File symlinkDirectory = new File(top, "fakeDir");
256 assertTrue(setupSymlink(randomDirectory, symlinkDirectory));
257
258 FileUtils.cleanDirectory(symlinkDirectory);
259 assertEquals(0, symlinkDirectory.list().length);
260 assertEquals(0, randomDirectory.list().length);
261 }
262
263 }