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 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 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 assertTrue(realOuter.exists());
86 assertEquals(0, realOuter.list().length);
87
88
89 assertEquals(1, randomDirectory.list().length, "Contents of symbolic link should not have been removed");
90 }
91
92 @Test
93 void testCleanDirWithParentSymlinks() throws Exception {
94 if (SystemProperties.getOsName().startsWith("Win")) {
95
96 return;
97 }
98
99 final File realParent = new File(top, "realparent");
100 assertTrue(realParent.mkdirs());
101
102 final File realInner = new File(realParent, "realinner");
103 assertTrue(realInner.mkdirs());
104
105 FileUtils.touch(new File(realInner, "file1"));
106 assertEquals(1, realInner.list().length);
107
108 final File randomDirectory = new File(top, "randomDir");
109 assertTrue(randomDirectory.mkdirs());
110
111 FileUtils.touch(new File(randomDirectory, "randomfile"));
112 assertEquals(1, randomDirectory.list().length);
113
114 final File symlinkDirectory = new File(realParent, "fakeinner");
115 assertTrue(setupSymlink(randomDirectory, symlinkDirectory));
116
117 assertEquals(1, symlinkDirectory.list().length);
118
119 final File symlinkParentDirectory = new File(top, "fakeouter");
120 assertTrue(setupSymlink(realParent, symlinkParentDirectory));
121
122
123
124 FileUtils.cleanDirectory(symlinkParentDirectory);
125 assertTrue(symlinkParentDirectory.exists());
126 assertEquals(0, symlinkParentDirectory.list().length);
127 assertEquals(0, realParent.list().length);
128
129
130 assertEquals(1, randomDirectory.list().length, "Contents of symbolic link should not have been removed");
131 }
132
133 @Test
134 void testCleanDirWithSymlinkFile() throws Exception {
135 if (SystemProperties.getOsName().startsWith("Win")) {
136
137 return;
138 }
139
140 final File realOuter = new File(top, "realouter");
141 assertTrue(realOuter.mkdirs());
142
143 final File realInner = new File(realOuter, "realinner");
144 assertTrue(realInner.mkdirs());
145
146 final File realFile = new File(realInner, "file1");
147 FileUtils.touch(realFile);
148 assertEquals(1, realInner.list().length);
149
150 final File randomFile = new File(top, "randomfile");
151 FileUtils.touch(randomFile);
152
153 final File symlinkFile = new File(realInner, "fakeinner");
154 assertTrue(setupSymlink(randomFile, symlinkFile));
155
156 assertEquals(2, realInner.list().length);
157
158
159 FileUtils.cleanDirectory(realOuter);
160 assertTrue(realOuter.exists());
161 assertEquals(0, realOuter.list().length);
162
163
164 assertTrue(randomFile.exists());
165 assertFalse(symlinkFile.exists());
166 }
167
168 @Test
169 void testCorrectlyIdentifySymlinkWithParentSymLink() throws Exception {
170 if (SystemProperties.getOsName().startsWith("Win")) {
171
172 return;
173 }
174
175 final File realParent = new File(top, "realparent");
176 assertTrue(realParent.mkdirs());
177
178 final File symlinkParentDirectory = new File(top, "fakeparent");
179 assertTrue(setupSymlink(realParent, symlinkParentDirectory));
180
181 final File realChild = new File(symlinkParentDirectory, "realChild");
182 assertTrue(realChild.mkdirs());
183
184 final File symlinkChild = new File(symlinkParentDirectory, "fakeChild");
185 assertTrue(setupSymlink(realChild, symlinkChild));
186
187 assertTrue(FileUtils.isSymlink(symlinkChild));
188 assertFalse(FileUtils.isSymlink(realChild));
189 }
190
191 @Test
192 void testIdentifiesBrokenSymlinkFile() throws Exception {
193 if (SystemProperties.getOsName().startsWith("Win")) {
194
195 return;
196 }
197
198 final File nonExistentFile = new File(top, "non-existent");
199 final File symlinkFile = new File(top, "fakeinner");
200 final File badSymlinkInPathFile = new File(symlinkFile, "fakeinner");
201 final File nonExistentParentFile = new File("non-existent", "file");
202
203 assertTrue(setupSymlink(nonExistentFile, symlinkFile));
204
205 assertTrue(FileUtils.isSymlink(symlinkFile));
206 assertFalse(FileUtils.isSymlink(nonExistentFile));
207 assertFalse(FileUtils.isSymlink(nonExistentParentFile));
208 assertFalse(FileUtils.isSymlink(badSymlinkInPathFile));
209 }
210
211 @Test
212 void testIdentifiesSymlinkDir() throws Exception {
213 if (SystemProperties.getOsName().startsWith("Win")) {
214
215 return;
216 }
217
218 final File randomDirectory = new File(top, "randomDir");
219 assertTrue(randomDirectory.mkdirs());
220
221 final File symlinkDirectory = new File(top, "fakeDir");
222 assertTrue(setupSymlink(randomDirectory, symlinkDirectory));
223
224 assertTrue(FileUtils.isSymlink(symlinkDirectory));
225 assertFalse(FileUtils.isSymlink(randomDirectory));
226 }
227
228 @Test
229 void testIdentifiesSymlinkFile() throws Exception {
230 if (SystemProperties.getOsName().startsWith("Win")) {
231
232 return;
233 }
234
235 final File randomFile = new File(top, "randomfile");
236 FileUtils.touch(randomFile);
237
238 final File symlinkFile = new File(top, "fakeinner");
239 assertTrue(setupSymlink(randomFile, symlinkFile));
240
241 assertTrue(FileUtils.isSymlink(symlinkFile));
242 assertFalse(FileUtils.isSymlink(randomFile));
243 }
244
245 @Test
246 void testStillClearsIfGivenDirectoryIsASymlink() throws Exception {
247 if (SystemProperties.getOsName().startsWith("Win")) {
248
249 return;
250 }
251
252 final File randomDirectory = new File(top, "randomDir");
253 assertTrue(randomDirectory.mkdirs());
254
255 FileUtils.touch(new File(randomDirectory, "randomfile"));
256 assertEquals(1, randomDirectory.list().length);
257
258 final File symlinkDirectory = new File(top, "fakeDir");
259 assertTrue(setupSymlink(randomDirectory, symlinkDirectory));
260
261 FileUtils.cleanDirectory(symlinkDirectory);
262 assertTrue(symlinkDirectory.exists());
263 assertEquals(0, symlinkDirectory.list().length);
264 assertEquals(0, randomDirectory.list().length);
265 }
266
267 }