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