blob: e52c9b65bccaeebf932d5cb98d9c724c533064ca [file] [log] [blame]
Laszlo Csomor94d90582016-09-08 15:08:00 +00001// Copyright 2016 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Ulf Adams8afbd3c2017-02-28 10:42:48 +000015package com.google.devtools.build.lib.windows;
Laszlo Csomor94d90582016-09-08 15:08:00 +000016
17import static com.google.common.truth.Truth.assertThat;
Ulf Adams8afbd3c2017-02-28 10:42:48 +000018import static com.google.devtools.build.lib.windows.WindowsFileSystem.SHORT_NAME_MATCHER;
lberki4a45ea82017-06-01 10:05:42 +020019import static org.junit.Assert.fail;
Laszlo Csomor94d90582016-09-08 15:08:00 +000020
Laszlo Csomor81f92fe2017-02-15 16:08:45 +000021import com.google.common.base.Function;
Laszlo Csomor8679e4c2017-01-03 15:21:08 +000022import com.google.common.base.Predicate;
Laszlo Csomor81f92fe2017-02-15 16:08:45 +000023import com.google.common.collect.ImmutableList;
Laszlo Csomor94d90582016-09-08 15:08:00 +000024import com.google.common.collect.ImmutableMap;
Laszlo Csomor81f92fe2017-02-15 16:08:45 +000025import com.google.common.collect.Iterables;
Laszlo Csomor94d90582016-09-08 15:08:00 +000026import com.google.devtools.build.lib.testutil.TestSpec;
27import com.google.devtools.build.lib.util.OS;
Ulf Adams8afbd3c2017-02-28 10:42:48 +000028import com.google.devtools.build.lib.vfs.Path;
29import com.google.devtools.build.lib.vfs.PathFragment;
30import com.google.devtools.build.lib.vfs.Symlinks;
31import com.google.devtools.build.lib.windows.WindowsFileSystem.WindowsPath;
Laszlo Csomor13f92262017-06-30 16:22:41 +020032import com.google.devtools.build.lib.windows.jni.WindowsFileOperations;
Laszlo Csomor94d90582016-09-08 15:08:00 +000033import com.google.devtools.build.lib.windows.util.WindowsTestUtil;
34import java.io.File;
Laszlo Csomorfe7e57e2016-12-21 16:02:51 +000035import java.io.IOException;
Laszlo Csomor94d90582016-09-08 15:08:00 +000036import java.nio.file.Files;
Laszlo Csomor8679e4c2017-01-03 15:21:08 +000037import java.util.ArrayList;
Laszlo Csomor94d90582016-09-08 15:08:00 +000038import java.util.Arrays;
39import java.util.HashMap;
Laszlo Csomor8679e4c2017-01-03 15:21:08 +000040import java.util.List;
Laszlo Csomor94d90582016-09-08 15:08:00 +000041import java.util.Map;
42import org.junit.After;
43import org.junit.Before;
44import org.junit.Test;
45import org.junit.runner.RunWith;
46import org.junit.runners.JUnit4;
47
48/** Unit tests for {@link WindowsFileSystem}. */
49@RunWith(JUnit4.class)
50@TestSpec(localOnly = true, supportedOs = OS.WINDOWS)
51public class WindowsFileSystemTest {
52
53 private String scratchRoot;
54 private WindowsTestUtil testUtil;
55 private WindowsFileSystem fs;
56
57 @Before
58 public void loadJni() throws Exception {
Yun Peng6a4247b2017-10-24 14:36:10 +020059 scratchRoot = new File(System.getenv("TEST_TMPDIR"), "x").getAbsolutePath();
Laszlo Csomor94d90582016-09-08 15:08:00 +000060 testUtil = new WindowsTestUtil(scratchRoot);
61 fs = new WindowsFileSystem();
62 cleanupScratchDir();
63 }
64
65 @After
66 public void cleanupScratchDir() throws Exception {
67 testUtil.deleteAllUnder("");
68 }
69
70 @Test
Ulf Adams8afbd3c2017-02-28 10:42:48 +000071 public void testShortNameMatcher() {
72 assertThat(SHORT_NAME_MATCHER.apply("abc")).isFalse(); // no ~ in the name
73 assertThat(SHORT_NAME_MATCHER.apply("abc~")).isFalse(); // no number after the ~
74 assertThat(SHORT_NAME_MATCHER.apply("~abc")).isFalse(); // no ~ followed by number
75 assertThat(SHORT_NAME_MATCHER.apply("too_long_path")).isFalse(); // too long for 8dot3
76 assertThat(SHORT_NAME_MATCHER.apply("too_long_path~1")).isFalse(); // too long for 8dot3
77 assertThat(SHORT_NAME_MATCHER.apply("abcd~1234")).isFalse(); // too long for 8dot3
78 assertThat(SHORT_NAME_MATCHER.apply("h~1")).isTrue();
79 assertThat(SHORT_NAME_MATCHER.apply("h~12")).isTrue();
80 assertThat(SHORT_NAME_MATCHER.apply("h~12.")).isTrue();
81 assertThat(SHORT_NAME_MATCHER.apply("h~12.a")).isTrue();
82 assertThat(SHORT_NAME_MATCHER.apply("h~12.abc")).isTrue();
83 assertThat(SHORT_NAME_MATCHER.apply("h~123456")).isTrue();
84 assertThat(SHORT_NAME_MATCHER.apply("hellow~1")).isTrue();
85 assertThat(SHORT_NAME_MATCHER.apply("hellow~1.")).isTrue();
86 assertThat(SHORT_NAME_MATCHER.apply("hellow~1.a")).isTrue();
87 assertThat(SHORT_NAME_MATCHER.apply("hellow~1.abc")).isTrue();
88 assertThat(SHORT_NAME_MATCHER.apply("hello~1.abcd")).isFalse(); // too long for 8dot3
89 assertThat(SHORT_NAME_MATCHER.apply("hellow~1.abcd")).isFalse(); // too long for 8dot3
90 assertThat(SHORT_NAME_MATCHER.apply("hello~12")).isTrue();
91 assertThat(SHORT_NAME_MATCHER.apply("hello~12.")).isTrue();
92 assertThat(SHORT_NAME_MATCHER.apply("hello~12.a")).isTrue();
93 assertThat(SHORT_NAME_MATCHER.apply("hello~12.abc")).isTrue();
94 assertThat(SHORT_NAME_MATCHER.apply("hello~12.abcd")).isFalse(); // too long for 8dot3
95 assertThat(SHORT_NAME_MATCHER.apply("hellow~12")).isFalse(); // too long for 8dot3
96 assertThat(SHORT_NAME_MATCHER.apply("hellow~12.")).isFalse(); // too long for 8dot3
97 assertThat(SHORT_NAME_MATCHER.apply("hellow~12.a")).isFalse(); // too long for 8dot3
98 assertThat(SHORT_NAME_MATCHER.apply("hellow~12.ab")).isFalse(); // too long for 8dot3
99 assertThat(SHORT_NAME_MATCHER.apply("~h~1")).isTrue();
100 assertThat(SHORT_NAME_MATCHER.apply("~h~1.")).isTrue();
101 assertThat(SHORT_NAME_MATCHER.apply("~h~1.a")).isTrue();
102 assertThat(SHORT_NAME_MATCHER.apply("~h~1.abc")).isTrue();
103 assertThat(SHORT_NAME_MATCHER.apply("~h~1.abcd")).isFalse(); // too long for 8dot3
104 assertThat(SHORT_NAME_MATCHER.apply("~h~12")).isTrue();
105 assertThat(SHORT_NAME_MATCHER.apply("~h~12~1")).isTrue();
106 assertThat(SHORT_NAME_MATCHER.apply("~h~12~1.")).isTrue();
107 assertThat(SHORT_NAME_MATCHER.apply("~h~12~1.a")).isTrue();
108 assertThat(SHORT_NAME_MATCHER.apply("~h~12~1.abc")).isTrue();
109 assertThat(SHORT_NAME_MATCHER.apply("~h~12~1.abcd")).isFalse(); // too long for 8dot3
110 }
111
112 @Test
Laszlo Csomor94d90582016-09-08 15:08:00 +0000113 public void testCanWorkWithJunctionSymlinks() throws Exception {
114 testUtil.scratchFile("dir\\hello.txt", "hello");
115 testUtil.scratchDir("non_existent");
116 testUtil.createJunctions(ImmutableMap.of("junc", "dir", "junc_bad", "non_existent"));
117
118 Path juncPath = testUtil.createVfsPath(fs, "junc");
119 Path dirPath = testUtil.createVfsPath(fs, "dir");
120 Path juncBadPath = testUtil.createVfsPath(fs, "junc_bad");
121 Path nonExistentPath = testUtil.createVfsPath(fs, "non_existent");
122
123 // Test junction creation.
Ulf Adams8afbd3c2017-02-28 10:42:48 +0000124 assertThat(juncPath.exists(Symlinks.NOFOLLOW)).isTrue();
125 assertThat(dirPath.exists(Symlinks.NOFOLLOW)).isTrue();
126 assertThat(juncBadPath.exists(Symlinks.NOFOLLOW)).isTrue();
127 assertThat(nonExistentPath.exists(Symlinks.NOFOLLOW)).isTrue();
Laszlo Csomor94d90582016-09-08 15:08:00 +0000128
129 // Test recognizing and dereferencing a directory junction.
Ulf Adams8afbd3c2017-02-28 10:42:48 +0000130 assertThat(juncPath.isSymbolicLink()).isTrue();
131 assertThat(juncPath.isDirectory(Symlinks.FOLLOW)).isTrue();
132 assertThat(juncPath.isDirectory(Symlinks.NOFOLLOW)).isFalse();
133 assertThat(juncPath.getDirectoryEntries())
Laszlo Csomor94d90582016-09-08 15:08:00 +0000134 .containsExactly(testUtil.createVfsPath(fs, "junc\\hello.txt"));
135
136 // Test deleting a directory junction.
Ulf Adams8afbd3c2017-02-28 10:42:48 +0000137 assertThat(juncPath.delete()).isTrue();
138 assertThat(juncPath.exists(Symlinks.NOFOLLOW)).isFalse();
Laszlo Csomor94d90582016-09-08 15:08:00 +0000139
140 // Test recognizing a dangling directory junction.
Ulf Adams8afbd3c2017-02-28 10:42:48 +0000141 assertThat(nonExistentPath.delete()).isTrue();
142 assertThat(nonExistentPath.exists(Symlinks.NOFOLLOW)).isFalse();
143 assertThat(juncBadPath.exists(Symlinks.NOFOLLOW)).isTrue();
Laszlo Csomor94d90582016-09-08 15:08:00 +0000144 // TODO(bazel-team): fix https://github.com/bazelbuild/bazel/issues/1690 and uncomment the
145 // assertion below.
146 //assertThat(fs.isSymbolicLink(juncBadPath)).isTrue();
147 assertThat(fs.isDirectory(juncBadPath, /* followSymlinks */ true)).isFalse();
148 assertThat(fs.isDirectory(juncBadPath, /* followSymlinks */ false)).isFalse();
149
150 // Test deleting a dangling junction.
Ulf Adams8afbd3c2017-02-28 10:42:48 +0000151 assertThat(juncBadPath.delete()).isTrue();
152 assertThat(juncBadPath.exists(Symlinks.NOFOLLOW)).isFalse();
Laszlo Csomor94d90582016-09-08 15:08:00 +0000153 }
154
155 @Test
156 public void testMockJunctionCreation() throws Exception {
157 String root = testUtil.scratchDir("dir").getParent().toString();
158 testUtil.scratchFile("dir/file.txt", "hello");
159 testUtil.createJunctions(ImmutableMap.of("junc", "dir"));
160 String[] children = new File(root + "/junc").list();
161 assertThat(children).isNotNull();
162 assertThat(children).hasLength(1);
163 assertThat(Arrays.asList(children)).containsExactly("file.txt");
164 }
165
166 @Test
167 public void testIsJunction() throws Exception {
168 final Map<String, String> junctions = new HashMap<>();
169 junctions.put("shrtpath/a", "shrttrgt");
170 junctions.put("shrtpath/b", "longtargetpath");
171 junctions.put("shrtpath/c", "longta~1");
172 junctions.put("longlinkpath/a", "shrttrgt");
173 junctions.put("longlinkpath/b", "longtargetpath");
174 junctions.put("longlinkpath/c", "longta~1");
175 junctions.put("abbrev~1/a", "shrttrgt");
176 junctions.put("abbrev~1/b", "longtargetpath");
177 junctions.put("abbrev~1/c", "longta~1");
178
179 String root = testUtil.scratchDir("shrtpath").getParent().toAbsolutePath().toString();
180 testUtil.scratchDir("longlinkpath");
181 testUtil.scratchDir("abbreviated");
182 testUtil.scratchDir("control/a");
183 testUtil.scratchDir("control/b");
184 testUtil.scratchDir("control/c");
185
186 testUtil.scratchFile("shrttrgt/file1.txt", "hello");
187 testUtil.scratchFile("longtargetpath/file2.txt", "hello");
188
189 testUtil.createJunctions(junctions);
190
Laszlo Csomor124c16c2016-11-04 14:22:46 +0000191 assertThat(WindowsFileSystem.isJunction(new File(root, "shrtpath/a"))).isTrue();
192 assertThat(WindowsFileSystem.isJunction(new File(root, "shrtpath/b"))).isTrue();
193 assertThat(WindowsFileSystem.isJunction(new File(root, "shrtpath/c"))).isTrue();
194 assertThat(WindowsFileSystem.isJunction(new File(root, "longlinkpath/a"))).isTrue();
195 assertThat(WindowsFileSystem.isJunction(new File(root, "longlinkpath/b"))).isTrue();
196 assertThat(WindowsFileSystem.isJunction(new File(root, "longlinkpath/c"))).isTrue();
197 assertThat(WindowsFileSystem.isJunction(new File(root, "longli~1/a"))).isTrue();
198 assertThat(WindowsFileSystem.isJunction(new File(root, "longli~1/b"))).isTrue();
199 assertThat(WindowsFileSystem.isJunction(new File(root, "longli~1/c"))).isTrue();
200 assertThat(WindowsFileSystem.isJunction(new File(root, "abbreviated/a"))).isTrue();
201 assertThat(WindowsFileSystem.isJunction(new File(root, "abbreviated/b"))).isTrue();
202 assertThat(WindowsFileSystem.isJunction(new File(root, "abbreviated/c"))).isTrue();
203 assertThat(WindowsFileSystem.isJunction(new File(root, "abbrev~1/a"))).isTrue();
204 assertThat(WindowsFileSystem.isJunction(new File(root, "abbrev~1/b"))).isTrue();
205 assertThat(WindowsFileSystem.isJunction(new File(root, "abbrev~1/c"))).isTrue();
206 assertThat(WindowsFileSystem.isJunction(new File(root, "control/a"))).isFalse();
207 assertThat(WindowsFileSystem.isJunction(new File(root, "control/b"))).isFalse();
208 assertThat(WindowsFileSystem.isJunction(new File(root, "control/c"))).isFalse();
209 assertThat(WindowsFileSystem.isJunction(new File(root, "shrttrgt/file1.txt")))
Laszlo Csomor94d90582016-09-08 15:08:00 +0000210 .isFalse();
Laszlo Csomor124c16c2016-11-04 14:22:46 +0000211 assertThat(WindowsFileSystem.isJunction(new File(root, "longtargetpath/file2.txt")))
Laszlo Csomor94d90582016-09-08 15:08:00 +0000212 .isFalse();
Laszlo Csomor124c16c2016-11-04 14:22:46 +0000213 assertThat(WindowsFileSystem.isJunction(new File(root, "longta~1/file2.txt")))
Laszlo Csomor94d90582016-09-08 15:08:00 +0000214 .isFalse();
Laszlo Csomorfe7e57e2016-12-21 16:02:51 +0000215 try {
216 WindowsFileSystem.isJunction(new File(root, "non-existent"));
lberki4a45ea82017-06-01 10:05:42 +0200217 fail("expected failure");
Laszlo Csomorfe7e57e2016-12-21 16:02:51 +0000218 } catch (IOException e) {
219 assertThat(e.getMessage()).contains("cannot find");
220 }
Laszlo Csomor94d90582016-09-08 15:08:00 +0000221
222 assertThat(Arrays.asList(new File(root + "/shrtpath/a").list())).containsExactly("file1.txt");
223 assertThat(Arrays.asList(new File(root + "/shrtpath/b").list())).containsExactly("file2.txt");
224 assertThat(Arrays.asList(new File(root + "/shrtpath/c").list())).containsExactly("file2.txt");
225 assertThat(Arrays.asList(new File(root + "/longlinkpath/a").list()))
226 .containsExactly("file1.txt");
227 assertThat(Arrays.asList(new File(root + "/longlinkpath/b").list()))
228 .containsExactly("file2.txt");
229 assertThat(Arrays.asList(new File(root + "/longlinkpath/c").list()))
230 .containsExactly("file2.txt");
231 assertThat(Arrays.asList(new File(root + "/abbreviated/a").list()))
232 .containsExactly("file1.txt");
233 assertThat(Arrays.asList(new File(root + "/abbreviated/b").list()))
234 .containsExactly("file2.txt");
235 assertThat(Arrays.asList(new File(root + "/abbreviated/c").list()))
236 .containsExactly("file2.txt");
237 }
238
239 @Test
240 public void testIsJunctionIsTrueForDanglingJunction() throws Exception {
241 java.nio.file.Path helloPath = testUtil.scratchFile("target\\hello.txt", "hello");
242 testUtil.createJunctions(ImmutableMap.of("link", "target"));
243
244 File linkPath = new File(helloPath.getParent().getParent().toFile(), "link");
245 assertThat(Arrays.asList(linkPath.list())).containsExactly("hello.txt");
Laszlo Csomor124c16c2016-11-04 14:22:46 +0000246 assertThat(WindowsFileSystem.isJunction(linkPath)).isTrue();
Laszlo Csomor94d90582016-09-08 15:08:00 +0000247
248 assertThat(helloPath.toFile().delete()).isTrue();
249 assertThat(helloPath.getParent().toFile().delete()).isTrue();
250 assertThat(helloPath.getParent().toFile().exists()).isFalse();
251 assertThat(Arrays.asList(linkPath.getParentFile().list())).containsExactly("link");
252
Laszlo Csomor124c16c2016-11-04 14:22:46 +0000253 assertThat(WindowsFileSystem.isJunction(linkPath)).isTrue();
Laszlo Csomor94d90582016-09-08 15:08:00 +0000254 assertThat(
255 Files.exists(
256 linkPath.toPath(), WindowsFileSystem.symlinkOpts(/* followSymlinks */ false)))
257 .isTrue();
258 assertThat(
259 Files.exists(
260 linkPath.toPath(), WindowsFileSystem.symlinkOpts(/* followSymlinks */ true)))
261 .isFalse();
262 }
Laszlo Csomoraa1614b2016-12-15 11:16:44 +0000263
264 @Test
265 public void testIsJunctionHandlesFilesystemChangesCorrectly() throws Exception {
266 File longPath =
267 testUtil.scratchFile("target\\helloworld.txt", "hello").toAbsolutePath().toFile();
268 File shortPath = new File(longPath.getParentFile(), "hellow~1.txt");
269 assertThat(WindowsFileSystem.isJunction(longPath)).isFalse();
270 assertThat(WindowsFileSystem.isJunction(shortPath)).isFalse();
271
272 assertThat(longPath.delete()).isTrue();
273 testUtil.createJunctions(ImmutableMap.of("target\\helloworld.txt", "target"));
274 assertThat(WindowsFileSystem.isJunction(longPath)).isTrue();
275 assertThat(WindowsFileSystem.isJunction(shortPath)).isTrue();
276
277 assertThat(longPath.delete()).isTrue();
278 assertThat(longPath.mkdir()).isTrue();
279 assertThat(WindowsFileSystem.isJunction(longPath)).isFalse();
280 assertThat(WindowsFileSystem.isJunction(shortPath)).isFalse();
281 }
Laszlo Csomor8679e4c2017-01-03 15:21:08 +0000282
283 @Test
284 public void testShortPathResolution() throws Exception {
285 String shortPath = "shortp~1.res/foo/withsp~1/bar/~witht~1/hello.txt";
286 String longPath = "shortpath.resolution/foo/with spaces/bar/~with tilde/hello.txt";
287 testUtil.scratchFile(longPath, "hello");
288 Path p = fs.getPath(scratchRoot).getRelative(shortPath);
289 assertThat(p.getPathString()).endsWith(longPath);
290 assertThat(p).isEqualTo(fs.getPath(scratchRoot).getRelative(shortPath));
291 assertThat(p).isEqualTo(fs.getPath(scratchRoot).getRelative(longPath));
lberkie355e772017-05-31 14:34:53 +0200292 assertThat(fs.getPath(scratchRoot).getRelative(shortPath)).isSameAs(p);
293 assertThat(fs.getPath(scratchRoot).getRelative(longPath)).isSameAs(p);
Laszlo Csomor8679e4c2017-01-03 15:21:08 +0000294 }
295
296 @Test
297 public void testUnresolvableShortPathWhichIsThenCreated() throws Exception {
298 String shortPath = "unreso~1.sho/foo/will~1.exi/bar/hello.txt";
299 String longPrefix = "unresolvable.shortpath/foo/";
300 String longPath = longPrefix + "will.exist/bar/hello.txt";
301 testUtil.scratchDir(longPrefix);
Ulf Adams8afbd3c2017-02-28 10:42:48 +0000302 final WindowsPath foo = (WindowsPath) fs.getPath(scratchRoot).getRelative(longPrefix);
Laszlo Csomor8679e4c2017-01-03 15:21:08 +0000303
304 // Assert that we can create an unresolvable path.
305 Path p = fs.getPath(scratchRoot).getRelative(shortPath);
306 assertThat(p.getPathString()).endsWith(longPrefix + "will~1.exi/bar/hello.txt");
307 // Assert that said path is not cached in its parent's `children` cache.
308 final List<String> children = new ArrayList<>();
309 Predicate<Path> collector =
310 new Predicate<Path>() {
311 @Override
312 public boolean apply(Path child) {
313 children.add(child.relativeTo(foo).getPathString());
314 return true;
315 }
316 };
317 foo.applyToChildren(collector);
318 assertThat(children).isEmpty();
319 // Assert that we can then create the whole path, and can now resolve the short form.
320 testUtil.scratchFile(longPath, "hello");
321 Path q = fs.getPath(scratchRoot).getRelative(shortPath);
322 assertThat(q.getPathString()).endsWith(longPath);
323 // Assert however that the unresolved and resolved Path objects are different, and only the
324 // resolved one is cached.
325 assertThat(p).isNotEqualTo(q);
326 foo.applyToChildren(collector);
327 assertThat(children).containsExactly("will.exist");
328 }
329
330 /**
331 * Test the scenario when a short path resolves to different long ones over time.
332 *
333 * <p>This can happen if the user deletes a directory during the bazel server's lifetime, then
334 * recreates it with the same name prefix such that the resulting directory's 8dot3 name is the
335 * same as the old one's.
336 */
337 @Test
338 public void testShortPathResolvesToDifferentPathsOverTime() throws Exception {
339 Path p1 = fs.getPath(scratchRoot).getRelative("longpa~1");
340 Path p2 = fs.getPath(scratchRoot).getRelative("longpa~1");
341 assertThat(p1.exists()).isFalse();
342 assertThat(p1).isEqualTo(p2);
343 assertThat(p1).isNotSameAs(p2);
344
345 testUtil.scratchDir("longpathnow");
346 Path q1 = fs.getPath(scratchRoot).getRelative("longpa~1");
347 Path q2 = fs.getPath(scratchRoot).getRelative("longpa~1");
348 assertThat(q1.exists()).isTrue();
349 assertThat(q1).isEqualTo(q2);
350 // Assert q1 == q2, because we could successfully resolve the short path to a long name and we
351 // cache them by the long name, so it's irrelevant they were created from a 8dot3 name, or what
352 // that name resolves to later in time.
353 assertThat(q1).isSameAs(q2);
354 assertThat(q1).isSameAs(fs.getPath(scratchRoot).getRelative("longpathnow"));
355
356 // Delete the original resolution of "longpa~1" ("longpathnow").
357 assertThat(q1.delete()).isTrue();
358 assertThat(q1.exists()).isFalse();
359
360 // Create a directory whose 8dot3 name is also "longpa~1" but its long name is different.
361 testUtil.scratchDir("longpaththen");
362 Path r1 = fs.getPath(scratchRoot).getRelative("longpa~1");
363 Path r2 = fs.getPath(scratchRoot).getRelative("longpa~1");
364 assertThat(r1.exists()).isTrue();
365 assertThat(r1).isEqualTo(r2);
366 assertThat(r1).isSameAs(r2);
367 assertThat(r1).isSameAs(fs.getPath(scratchRoot).getRelative("longpaththen"));
368 // r1 == r2 and q1 == q2, but r1 != q1, because the resolution of "longpa~1" changed over time.
369 assertThat(r1).isNotEqualTo(q1);
370 assertThat(r1).isNotSameAs(q1);
371 }
Laszlo Csomor81f92fe2017-02-15 16:08:45 +0000372
373 @Test
374 public void testCreateSymbolicLink() throws Exception {
375 // Create the `scratchRoot` directory.
376 assertThat(fs.getPath(scratchRoot).createDirectory()).isTrue();
377 // Create symlink with directory target, relative path.
378 Path link1 = fs.getPath(scratchRoot).getRelative("link1");
nharmata4d2a0a12017-04-06 17:56:18 +0000379 fs.createSymbolicLink(link1, PathFragment.create(".."));
Laszlo Csomor81f92fe2017-02-15 16:08:45 +0000380 // Create symlink with directory target, absolute path.
381 Path link2 = fs.getPath(scratchRoot).getRelative("link2");
382 fs.createSymbolicLink(link2, fs.getPath(scratchRoot).getRelative("link1").asFragment());
383 // Create scratch files that'll be symlink targets.
384 testUtil.scratchFile("foo.txt", "hello");
385 testUtil.scratchFile("bar.txt", "hello");
386 // Create symlink with file target, relative path.
387 Path link3 = fs.getPath(scratchRoot).getRelative("link3");
nharmata4d2a0a12017-04-06 17:56:18 +0000388 fs.createSymbolicLink(link3, PathFragment.create("foo.txt"));
Laszlo Csomor81f92fe2017-02-15 16:08:45 +0000389 // Create symlink with file target, absolute path.
390 Path link4 = fs.getPath(scratchRoot).getRelative("link4");
391 fs.createSymbolicLink(link4, fs.getPath(scratchRoot).getRelative("bar.txt").asFragment());
392 // Assert that link1 and link2 are true junctions and have the right contents.
393 for (Path p : ImmutableList.of(link1, link2)) {
394 assertThat(WindowsFileOperations.isJunction(p.getPathString())).isTrue();
395 assertThat(p.isSymbolicLink()).isTrue();
396 assertThat(
397 Iterables.transform(
398 Arrays.asList(new File(p.getPathString()).listFiles()),
399 new Function<File, String>() {
400 @Override
401 public String apply(File input) {
402 return input.getName();
403 }
404 }))
405 .containsExactly("x");
406 }
407 // Assert that link3 and link4 are copies of files.
408 for (Path p : ImmutableList.of(link3, link4)) {
409 assertThat(WindowsFileOperations.isJunction(p.getPathString())).isFalse();
410 assertThat(p.isSymbolicLink()).isFalse();
411 assertThat(p.isFile()).isTrue();
412 }
413 }
Laszlo Csomor94d90582016-09-08 15:08:00 +0000414}