1 /* 2 * Copyright 2013 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.jimfs; 18 19 import static com.google.common.jimfs.TestUtils.bytes; 20 import static com.google.common.jimfs.TestUtils.permutations; 21 import static com.google.common.jimfs.TestUtils.preFilledBytes; 22 import static com.google.common.primitives.Bytes.concat; 23 import static com.google.common.truth.Truth.assertThat; 24 import static java.nio.charset.StandardCharsets.UTF_8; 25 import static java.nio.file.LinkOption.NOFOLLOW_LINKS; 26 import static java.nio.file.StandardCopyOption.ATOMIC_MOVE; 27 import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES; 28 import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; 29 import static java.nio.file.StandardOpenOption.APPEND; 30 import static java.nio.file.StandardOpenOption.CREATE; 31 import static java.nio.file.StandardOpenOption.CREATE_NEW; 32 import static java.nio.file.StandardOpenOption.DSYNC; 33 import static java.nio.file.StandardOpenOption.READ; 34 import static java.nio.file.StandardOpenOption.SPARSE; 35 import static java.nio.file.StandardOpenOption.SYNC; 36 import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING; 37 import static java.nio.file.StandardOpenOption.WRITE; 38 import static java.util.concurrent.TimeUnit.MILLISECONDS; 39 import static org.junit.Assert.assertArrayEquals; 40 import static org.junit.Assert.assertEquals; 41 import static org.junit.Assert.assertFalse; 42 import static org.junit.Assert.assertTrue; 43 import static org.junit.Assert.fail; 44 45 import com.google.common.collect.ImmutableList; 46 import com.google.common.collect.ImmutableSet; 47 import com.google.common.collect.Iterables; 48 import com.google.common.collect.Iterators; 49 import com.google.common.collect.Ordering; 50 import com.google.common.io.ByteStreams; 51 import com.google.common.io.CharStreams; 52 import com.google.common.primitives.Bytes; 53 import com.google.common.util.concurrent.Uninterruptibles; 54 import java.io.ByteArrayInputStream; 55 import java.io.ByteArrayOutputStream; 56 import java.io.IOException; 57 import java.io.InputStream; 58 import java.io.OutputStream; 59 import java.io.Reader; 60 import java.io.Writer; 61 import java.net.URI; 62 import java.nio.ByteBuffer; 63 import java.nio.channels.AsynchronousFileChannel; 64 import java.nio.channels.FileChannel; 65 import java.nio.channels.NonReadableChannelException; 66 import java.nio.channels.NonWritableChannelException; 67 import java.nio.channels.SeekableByteChannel; 68 import java.nio.file.ClosedDirectoryStreamException; 69 import java.nio.file.DirectoryNotEmptyException; 70 import java.nio.file.DirectoryStream; 71 import java.nio.file.FileAlreadyExistsException; 72 import java.nio.file.FileStore; 73 import java.nio.file.FileSystem; 74 import java.nio.file.FileSystemException; 75 import java.nio.file.FileSystems; 76 import java.nio.file.Files; 77 import java.nio.file.NoSuchFileException; 78 import java.nio.file.NotDirectoryException; 79 import java.nio.file.NotLinkException; 80 import java.nio.file.Path; 81 import java.nio.file.Paths; 82 import java.nio.file.SecureDirectoryStream; 83 import java.nio.file.attribute.BasicFileAttributeView; 84 import java.nio.file.attribute.BasicFileAttributes; 85 import java.nio.file.attribute.FileAttribute; 86 import java.nio.file.attribute.FileTime; 87 import java.nio.file.attribute.PosixFilePermission; 88 import java.nio.file.attribute.PosixFilePermissions; 89 import java.nio.file.attribute.UserPrincipal; 90 import java.util.Arrays; 91 import java.util.Iterator; 92 import java.util.Set; 93 import java.util.regex.PatternSyntaxException; 94 import org.junit.Test; 95 import org.junit.runner.RunWith; 96 import org.junit.runners.JUnit4; 97 98 /** 99 * Tests an in-memory file system through the public APIs in {@link Files}, etc. This also acts as 100 * the tests for {@code FileSystemView}, as each public API method is (mostly) implemented by a 101 * method in {@code FileSystemView}. 102 * 103 * <p>These tests uses a Unix-like file system, but most of what they test applies to any file 104 * system configuration. 105 * 106 * @author Colin Decker 107 */ 108 @RunWith(JUnit4.class) 109 public class JimfsUnixLikeFileSystemTest extends AbstractJimfsIntegrationTest { 110 111 private static final Configuration UNIX_CONFIGURATION = 112 Configuration.unix().toBuilder() 113 .setAttributeViews("basic", "owner", "posix", "unix") 114 .setMaxSize(1024 * 1024 * 1024) // 1 GB 115 .setMaxCacheSize(256 * 1024 * 1024) // 256 MB 116 .build(); 117 118 @Override createFileSystem()119 protected FileSystem createFileSystem() { 120 return Jimfs.newFileSystem("unix", UNIX_CONFIGURATION); 121 } 122 123 @Test testFileSystem()124 public void testFileSystem() { 125 assertThat(fs.getSeparator()).isEqualTo("/"); 126 assertThat(fs.getRootDirectories()) 127 .containsExactlyElementsIn(ImmutableSet.of(path("/"))) 128 .inOrder(); 129 assertThat(fs.isOpen()).isTrue(); 130 assertThat(fs.isReadOnly()).isFalse(); 131 assertThat(fs.supportedFileAttributeViews()).containsExactly("basic", "owner", "posix", "unix"); 132 assertThat(fs.provider()).isInstanceOf(JimfsFileSystemProvider.class); 133 } 134 135 @Test testFileStore()136 public void testFileStore() throws IOException { 137 FileStore fileStore = Iterables.getOnlyElement(fs.getFileStores()); 138 assertThat(fileStore.name()).isEqualTo("jimfs"); 139 assertThat(fileStore.type()).isEqualTo("jimfs"); 140 assertThat(fileStore.isReadOnly()).isFalse(); 141 142 long totalSpace = 1024 * 1024 * 1024; // 1 GB 143 assertThat(fileStore.getTotalSpace()).isEqualTo(totalSpace); 144 assertThat(fileStore.getUnallocatedSpace()).isEqualTo(totalSpace); 145 assertThat(fileStore.getUsableSpace()).isEqualTo(totalSpace); 146 147 Files.write(fs.getPath("/foo"), new byte[10000]); 148 149 assertThat(fileStore.getTotalSpace()).isEqualTo(totalSpace); 150 151 // We wrote 10000 bytes, but since the file system allocates fixed size blocks, more than 10k 152 // bytes may have been allocated. As such, the unallocated space after the write can be at most 153 // maxUnallocatedSpace. 154 assertThat(fileStore.getUnallocatedSpace() <= totalSpace - 10000).isTrue(); 155 156 // Usable space is at most unallocated space. (In this case, it's currently exactly unallocated 157 // space, but that's not required.) 158 assertThat(fileStore.getUsableSpace() <= fileStore.getUnallocatedSpace()).isTrue(); 159 160 Files.delete(fs.getPath("/foo")); 161 assertThat(fileStore.getTotalSpace()).isEqualTo(totalSpace); 162 assertThat(fileStore.getUnallocatedSpace()).isEqualTo(totalSpace); 163 assertThat(fileStore.getUsableSpace()).isEqualTo(totalSpace); 164 } 165 166 @Test testPaths()167 public void testPaths() { 168 assertThatPath("/").isAbsolute().and().hasRootComponent("/").and().hasNoNameComponents(); 169 assertThatPath("foo").isRelative().and().hasNameComponents("foo"); 170 assertThatPath("foo/bar").isRelative().and().hasNameComponents("foo", "bar"); 171 assertThatPath("/foo/bar/baz") 172 .isAbsolute() 173 .and() 174 .hasRootComponent("/") 175 .and() 176 .hasNameComponents("foo", "bar", "baz"); 177 } 178 179 @Test testPaths_equalityIsCaseSensitive()180 public void testPaths_equalityIsCaseSensitive() { 181 assertThatPath("foo").isNotEqualTo(path("FOO")); 182 } 183 184 @Test testPaths_areSortedCaseSensitive()185 public void testPaths_areSortedCaseSensitive() { 186 Path p1 = path("a"); 187 Path p2 = path("B"); 188 Path p3 = path("c"); 189 Path p4 = path("D"); 190 191 assertThat(Ordering.natural().immutableSortedCopy(Arrays.asList(p3, p4, p1, p2))) 192 .isEqualTo(ImmutableList.of(p2, p4, p1, p3)); 193 194 // would be p1, p2, p3, p4 if sorting were case insensitive 195 } 196 197 @Test testPaths_resolve()198 public void testPaths_resolve() { 199 assertThatPath(path("/").resolve("foo/bar")) 200 .isAbsolute() 201 .and() 202 .hasRootComponent("/") 203 .and() 204 .hasNameComponents("foo", "bar"); 205 assertThatPath(path("foo/bar").resolveSibling("baz")) 206 .isRelative() 207 .and() 208 .hasNameComponents("foo", "baz"); 209 assertThatPath(path("foo/bar").resolve("/one/two")) 210 .isAbsolute() 211 .and() 212 .hasRootComponent("/") 213 .and() 214 .hasNameComponents("one", "two"); 215 } 216 217 @Test testPaths_normalize()218 public void testPaths_normalize() { 219 assertThatPath(path("foo/bar/..").normalize()).isRelative().and().hasNameComponents("foo"); 220 assertThatPath(path("foo/./bar/../baz/test/./../stuff").normalize()) 221 .isRelative() 222 .and() 223 .hasNameComponents("foo", "baz", "stuff"); 224 assertThatPath(path("../../foo/./bar").normalize()) 225 .isRelative() 226 .and() 227 .hasNameComponents("..", "..", "foo", "bar"); 228 assertThatPath(path("foo/../../bar").normalize()) 229 .isRelative() 230 .and() 231 .hasNameComponents("..", "bar"); 232 assertThatPath(path(".././..").normalize()).isRelative().and().hasNameComponents("..", ".."); 233 } 234 235 @Test testPaths_relativize()236 public void testPaths_relativize() { 237 assertThatPath(path("/foo/bar").relativize(path("/foo/bar/baz"))) 238 .isRelative() 239 .and() 240 .hasNameComponents("baz"); 241 assertThatPath(path("/foo/bar/baz").relativize(path("/foo/bar"))) 242 .isRelative() 243 .and() 244 .hasNameComponents(".."); 245 assertThatPath(path("/foo/bar/baz").relativize(path("/foo/baz/bar"))) 246 .isRelative() 247 .and() 248 .hasNameComponents("..", "..", "baz", "bar"); 249 assertThatPath(path("foo/bar").relativize(path("foo"))) 250 .isRelative() 251 .and() 252 .hasNameComponents(".."); 253 assertThatPath(path("foo").relativize(path("foo/bar"))) 254 .isRelative() 255 .and() 256 .hasNameComponents("bar"); 257 258 try { 259 Path unused = path("/foo/bar").relativize(path("bar")); 260 fail(); 261 } catch (IllegalArgumentException expected) { 262 } 263 264 try { 265 Path unused = path("bar").relativize(path("/foo/bar")); 266 fail(); 267 } catch (IllegalArgumentException expected) { 268 } 269 } 270 271 @Test testPaths_startsWith_endsWith()272 public void testPaths_startsWith_endsWith() { 273 assertThat(path("/foo/bar").startsWith("/")).isTrue(); 274 assertThat(path("/foo/bar").startsWith("/foo")).isTrue(); 275 assertThat(path("/foo/bar").startsWith("/foo/bar")).isTrue(); 276 assertThat(path("/foo/bar").endsWith("bar")).isTrue(); 277 assertThat(path("/foo/bar").endsWith("foo/bar")).isTrue(); 278 assertThat(path("/foo/bar").endsWith("/foo/bar")).isTrue(); 279 assertThat(path("/foo/bar").endsWith("/foo")).isFalse(); 280 assertThat(path("/foo/bar").startsWith("foo/bar")).isFalse(); 281 } 282 283 @Test testPaths_toAbsolutePath()284 public void testPaths_toAbsolutePath() { 285 assertThatPath(path("/foo/bar").toAbsolutePath()) 286 .isAbsolute() 287 .and() 288 .hasRootComponent("/") 289 .and() 290 .hasNameComponents("foo", "bar") 291 .and() 292 .isEqualTo(path("/foo/bar")); 293 294 assertThatPath(path("foo/bar").toAbsolutePath()) 295 .isAbsolute() 296 .and() 297 .hasRootComponent("/") 298 .and() 299 .hasNameComponents("work", "foo", "bar") 300 .and() 301 .isEqualTo(path("/work/foo/bar")); 302 } 303 304 @Test testPaths_toRealPath()305 public void testPaths_toRealPath() throws IOException { 306 Files.createDirectories(path("/foo/bar")); 307 Files.createSymbolicLink(path("/link"), path("/")); 308 309 assertThatPath(path("/link/foo/bar").toRealPath()).isEqualTo(path("/foo/bar")); 310 311 assertThatPath(path("").toRealPath()).isEqualTo(path("/work")); 312 assertThatPath(path(".").toRealPath()).isEqualTo(path("/work")); 313 assertThatPath(path("..").toRealPath()).isEqualTo(path("/")); 314 assertThatPath(path("../..").toRealPath()).isEqualTo(path("/")); 315 assertThatPath(path("./.././..").toRealPath()).isEqualTo(path("/")); 316 assertThatPath(path("./.././../.").toRealPath()).isEqualTo(path("/")); 317 } 318 319 @Test testPaths_toUri()320 public void testPaths_toUri() { 321 assertThat(path("/").toUri()).isEqualTo(URI.create("jimfs://unix/")); 322 assertThat(path("/foo").toUri()).isEqualTo(URI.create("jimfs://unix/foo")); 323 assertThat(path("/foo/bar").toUri()).isEqualTo(URI.create("jimfs://unix/foo/bar")); 324 assertThat(path("foo").toUri()).isEqualTo(URI.create("jimfs://unix/work/foo")); 325 assertThat(path("foo/bar").toUri()).isEqualTo(URI.create("jimfs://unix/work/foo/bar")); 326 assertThat(path("").toUri()).isEqualTo(URI.create("jimfs://unix/work/")); 327 assertThat(path("./../.").toUri()).isEqualTo(URI.create("jimfs://unix/work/./.././")); 328 } 329 330 @Test testPaths_getFromUri()331 public void testPaths_getFromUri() { 332 assertThatPath(Paths.get(URI.create("jimfs://unix/"))).isEqualTo(path("/")); 333 assertThatPath(Paths.get(URI.create("jimfs://unix/foo"))).isEqualTo(path("/foo")); 334 assertThatPath(Paths.get(URI.create("jimfs://unix/foo%20bar"))).isEqualTo(path("/foo bar")); 335 assertThatPath(Paths.get(URI.create("jimfs://unix/foo/./bar"))).isEqualTo(path("/foo/./bar")); 336 assertThatPath(Paths.get(URI.create("jimfs://unix/foo/bar/"))).isEqualTo(path("/foo/bar")); 337 } 338 339 @Test testPathMatchers_regex()340 public void testPathMatchers_regex() { 341 assertThatPath("bar").matches("regex:.*"); 342 assertThatPath("bar").matches("regex:bar"); 343 assertThatPath("bar").matches("regex:[a-z]+"); 344 assertThatPath("/foo/bar").matches("regex:/.*"); 345 assertThatPath("/foo/bar").matches("regex:/.*/bar"); 346 } 347 348 @Test testPathMatchers_glob()349 public void testPathMatchers_glob() { 350 assertThatPath("bar").matches("glob:bar"); 351 assertThatPath("bar").matches("glob:*"); 352 assertThatPath("/foo").doesNotMatch("glob:*"); 353 assertThatPath("/foo/bar").doesNotMatch("glob:*"); 354 assertThatPath("/foo/bar").matches("glob:**"); 355 assertThatPath("/foo/bar").matches("glob:/**"); 356 assertThatPath("foo/bar").doesNotMatch("glob:/**"); 357 assertThatPath("/foo/bar/baz/stuff").matches("glob:/foo/**"); 358 assertThatPath("/foo/bar/baz/stuff").matches("glob:/**/stuff"); 359 assertThatPath("/foo").matches("glob:/[a-z]*"); 360 assertThatPath("/Foo").doesNotMatch("glob:/[a-z]*"); 361 assertThatPath("/foo/bar/baz/Stuff.java").matches("glob:**/*.java"); 362 assertThatPath("/foo/bar/baz/Stuff.java").matches("glob:**/*.{java,class}"); 363 assertThatPath("/foo/bar/baz/Stuff.class").matches("glob:**/*.{java,class}"); 364 assertThatPath("/foo/bar/baz/Stuff.java").matches("glob:**/*.*"); 365 366 try { 367 fs.getPathMatcher("glob:**/*.{java,class"); 368 fail(); 369 } catch (PatternSyntaxException expected) { 370 } 371 } 372 373 @Test testPathMatchers_invalid()374 public void testPathMatchers_invalid() { 375 try { 376 fs.getPathMatcher("glob"); 377 fail(); 378 } catch (IllegalArgumentException expected) { 379 } 380 381 try { 382 fs.getPathMatcher("foo:foo"); 383 fail(); 384 } catch (UnsupportedOperationException expected) { 385 assertThat(expected.getMessage()).contains("syntax"); 386 } 387 } 388 389 @Test testNewFileSystem_hasRootAndWorkingDirectory()390 public void testNewFileSystem_hasRootAndWorkingDirectory() throws IOException { 391 assertThatPath("/").hasChildren("work"); 392 assertThatPath("/work").hasNoChildren(); 393 } 394 395 @Test testCreateDirectory_absolute()396 public void testCreateDirectory_absolute() throws IOException { 397 Files.createDirectory(path("/test")); 398 399 assertThatPath("/test").exists(); 400 assertThatPath("/").hasChildren("test", "work"); 401 402 Files.createDirectory(path("/foo")); 403 Files.createDirectory(path("/foo/bar")); 404 405 assertThatPath("/foo/bar").exists(); 406 assertThatPath("/foo").hasChildren("bar"); 407 } 408 409 @Test testCreateFile_absolute()410 public void testCreateFile_absolute() throws IOException { 411 Files.createFile(path("/test.txt")); 412 413 assertThatPath("/test.txt").isRegularFile(); 414 assertThatPath("/").hasChildren("test.txt", "work"); 415 416 Files.createDirectory(path("/foo")); 417 Files.createFile(path("/foo/test.txt")); 418 419 assertThatPath("/foo/test.txt").isRegularFile(); 420 assertThatPath("/foo").hasChildren("test.txt"); 421 } 422 423 @Test testCreateSymbolicLink_absolute()424 public void testCreateSymbolicLink_absolute() throws IOException { 425 Files.createSymbolicLink(path("/link.txt"), path("test.txt")); 426 427 assertThatPath("/link.txt", NOFOLLOW_LINKS).isSymbolicLink().withTarget("test.txt"); 428 assertThatPath("/").hasChildren("link.txt", "work"); 429 430 Files.createDirectory(path("/foo")); 431 Files.createSymbolicLink(path("/foo/link.txt"), path("test.txt")); 432 433 assertThatPath("/foo/link.txt").noFollowLinks().isSymbolicLink().withTarget("test.txt"); 434 assertThatPath("/foo").hasChildren("link.txt"); 435 } 436 437 @Test testCreateLink_absolute()438 public void testCreateLink_absolute() throws IOException { 439 Files.createFile(path("/test.txt")); 440 Files.createLink(path("/link.txt"), path("/test.txt")); 441 442 // don't assert that the link is the same file here, just that it was created 443 // later tests check that linking works correctly 444 assertThatPath("/link.txt", NOFOLLOW_LINKS).isRegularFile(); 445 assertThatPath("/").hasChildren("link.txt", "test.txt", "work"); 446 447 Files.createDirectory(path("/foo")); 448 Files.createLink(path("/foo/link.txt"), path("/test.txt")); 449 450 assertThatPath("/foo/link.txt", NOFOLLOW_LINKS).isRegularFile(); 451 assertThatPath("/foo").hasChildren("link.txt"); 452 } 453 454 @Test testCreateDirectory_relative()455 public void testCreateDirectory_relative() throws IOException { 456 Files.createDirectory(path("test")); 457 458 assertThatPath("/work/test", NOFOLLOW_LINKS).isDirectory(); 459 assertThatPath("test", NOFOLLOW_LINKS).isDirectory(); 460 assertThatPath("/work").hasChildren("test"); 461 assertThatPath("test").isSameFileAs("/work/test"); 462 463 Files.createDirectory(path("foo")); 464 Files.createDirectory(path("foo/bar")); 465 466 assertThatPath("/work/foo/bar", NOFOLLOW_LINKS).isDirectory(); 467 assertThatPath("foo/bar", NOFOLLOW_LINKS).isDirectory(); 468 assertThatPath("/work/foo").hasChildren("bar"); 469 assertThatPath("foo").hasChildren("bar"); 470 assertThatPath("foo/bar").isSameFileAs("/work/foo/bar"); 471 } 472 473 @Test testCreateFile_relative()474 public void testCreateFile_relative() throws IOException { 475 Files.createFile(path("test.txt")); 476 477 assertThatPath("/work/test.txt", NOFOLLOW_LINKS).isRegularFile(); 478 assertThatPath("test.txt", NOFOLLOW_LINKS).isRegularFile(); 479 assertThatPath("/work").hasChildren("test.txt"); 480 assertThatPath("test.txt").isSameFileAs("/work/test.txt"); 481 482 Files.createDirectory(path("foo")); 483 Files.createFile(path("foo/test.txt")); 484 485 assertThatPath("/work/foo/test.txt", NOFOLLOW_LINKS).isRegularFile(); 486 assertThatPath("foo/test.txt", NOFOLLOW_LINKS).isRegularFile(); 487 assertThatPath("/work/foo").hasChildren("test.txt"); 488 assertThatPath("foo").hasChildren("test.txt"); 489 assertThatPath("foo/test.txt").isSameFileAs("/work/foo/test.txt"); 490 } 491 492 @Test testCreateSymbolicLink_relative()493 public void testCreateSymbolicLink_relative() throws IOException { 494 Files.createSymbolicLink(path("link.txt"), path("test.txt")); 495 496 assertThatPath("/work/link.txt", NOFOLLOW_LINKS).isSymbolicLink().withTarget("test.txt"); 497 assertThatPath("link.txt", NOFOLLOW_LINKS).isSymbolicLink().withTarget("test.txt"); 498 assertThatPath("/work").hasChildren("link.txt"); 499 500 Files.createDirectory(path("foo")); 501 Files.createSymbolicLink(path("foo/link.txt"), path("test.txt")); 502 503 assertThatPath("/work/foo/link.txt", NOFOLLOW_LINKS).isSymbolicLink().withTarget("test.txt"); 504 assertThatPath("foo/link.txt", NOFOLLOW_LINKS).isSymbolicLink().withTarget("test.txt"); 505 assertThatPath("/work/foo").hasChildren("link.txt"); 506 assertThatPath("foo").hasChildren("link.txt"); 507 } 508 509 @Test testCreateLink_relative()510 public void testCreateLink_relative() throws IOException { 511 Files.createFile(path("test.txt")); 512 Files.createLink(path("link.txt"), path("test.txt")); 513 514 // don't assert that the link is the same file here, just that it was created 515 // later tests check that linking works correctly 516 assertThatPath("/work/link.txt", NOFOLLOW_LINKS).isRegularFile(); 517 assertThatPath("link.txt", NOFOLLOW_LINKS).isRegularFile(); 518 assertThatPath("/work").hasChildren("link.txt", "test.txt"); 519 520 Files.createDirectory(path("foo")); 521 Files.createLink(path("foo/link.txt"), path("test.txt")); 522 523 assertThatPath("/work/foo/link.txt", NOFOLLOW_LINKS).isRegularFile(); 524 assertThatPath("foo/link.txt", NOFOLLOW_LINKS).isRegularFile(); 525 assertThatPath("foo").hasChildren("link.txt"); 526 } 527 528 @Test testCreateFile_existing()529 public void testCreateFile_existing() throws IOException { 530 Files.createFile(path("/test")); 531 try { 532 Files.createFile(path("/test")); 533 fail(); 534 } catch (FileAlreadyExistsException expected) { 535 assertEquals("/test", expected.getMessage()); 536 } 537 538 try { 539 Files.createDirectory(path("/test")); 540 fail(); 541 } catch (FileAlreadyExistsException expected) { 542 assertEquals("/test", expected.getMessage()); 543 } 544 545 try { 546 Files.createSymbolicLink(path("/test"), path("/foo")); 547 fail(); 548 } catch (FileAlreadyExistsException expected) { 549 assertEquals("/test", expected.getMessage()); 550 } 551 552 Files.createFile(path("/foo")); 553 try { 554 Files.createLink(path("/test"), path("/foo")); 555 fail(); 556 } catch (FileAlreadyExistsException expected) { 557 assertEquals("/test", expected.getMessage()); 558 } 559 } 560 561 @Test testCreateFile_parentDoesNotExist()562 public void testCreateFile_parentDoesNotExist() throws IOException { 563 try { 564 Files.createFile(path("/foo/test")); 565 fail(); 566 } catch (NoSuchFileException expected) { 567 assertEquals("/foo/test", expected.getMessage()); 568 } 569 570 try { 571 Files.createDirectory(path("/foo/test")); 572 fail(); 573 } catch (NoSuchFileException expected) { 574 assertEquals("/foo/test", expected.getMessage()); 575 } 576 577 try { 578 Files.createSymbolicLink(path("/foo/test"), path("/bar")); 579 fail(); 580 } catch (NoSuchFileException expected) { 581 assertEquals("/foo/test", expected.getMessage()); 582 } 583 584 Files.createFile(path("/bar")); 585 try { 586 Files.createLink(path("/foo/test"), path("/bar")); 587 fail(); 588 } catch (NoSuchFileException expected) { 589 assertEquals("/foo/test", expected.getMessage()); 590 } 591 } 592 593 @Test testCreateFile_parentIsNotDirectory()594 public void testCreateFile_parentIsNotDirectory() throws IOException { 595 Files.createDirectory(path("/foo")); 596 Files.createFile(path("/foo/bar")); 597 598 try { 599 Files.createFile(path("/foo/bar/baz")); 600 fail(); 601 } catch (NoSuchFileException expected) { 602 assertThat(expected.getFile()).isEqualTo("/foo/bar/baz"); 603 } 604 } 605 606 @Test testCreateFile_nonDirectoryHigherInPath()607 public void testCreateFile_nonDirectoryHigherInPath() throws IOException { 608 Files.createDirectory(path("/foo")); 609 Files.createFile(path("/foo/bar")); 610 611 try { 612 Files.createFile(path("/foo/bar/baz/stuff")); 613 fail(); 614 } catch (NoSuchFileException expected) { 615 assertThat(expected.getFile()).isEqualTo("/foo/bar/baz/stuff"); 616 } 617 } 618 619 @Test testCreateFile_parentSymlinkDoesNotExist()620 public void testCreateFile_parentSymlinkDoesNotExist() throws IOException { 621 Files.createDirectory(path("/foo")); 622 Files.createSymbolicLink(path("/foo/bar"), path("/foo/nope")); 623 624 try { 625 Files.createFile(path("/foo/bar/baz")); 626 fail(); 627 } catch (NoSuchFileException expected) { 628 assertThat(expected.getFile()).isEqualTo("/foo/bar/baz"); 629 } 630 } 631 632 @Test testCreateFile_symlinkHigherInPathDoesNotExist()633 public void testCreateFile_symlinkHigherInPathDoesNotExist() throws IOException { 634 Files.createDirectory(path("/foo")); 635 Files.createSymbolicLink(path("/foo/bar"), path("nope")); 636 637 try { 638 Files.createFile(path("/foo/bar/baz/stuff")); 639 fail(); 640 } catch (NoSuchFileException expected) { 641 assertThat(expected.getFile()).isEqualTo("/foo/bar/baz/stuff"); 642 } 643 } 644 645 @Test testCreateFile_parentSymlinkDoesPointsToNonDirectory()646 public void testCreateFile_parentSymlinkDoesPointsToNonDirectory() throws IOException { 647 Files.createDirectory(path("/foo")); 648 Files.createFile(path("/foo/file")); 649 Files.createSymbolicLink(path("/foo/bar"), path("/foo/file")); 650 651 try { 652 Files.createFile(path("/foo/bar/baz")); 653 fail(); 654 } catch (NoSuchFileException expected) { 655 assertThat(expected.getFile()).isEqualTo("/foo/bar/baz"); 656 } 657 } 658 659 @Test testCreateFile_symlinkHigherInPathPointsToNonDirectory()660 public void testCreateFile_symlinkHigherInPathPointsToNonDirectory() throws IOException { 661 Files.createDirectory(path("/foo")); 662 Files.createFile(path("/foo/file")); 663 Files.createSymbolicLink(path("/foo/bar"), path("file")); 664 665 try { 666 Files.createFile(path("/foo/bar/baz/stuff")); 667 fail(); 668 } catch (NoSuchFileException expected) { 669 assertThat(expected.getFile()).isEqualTo("/foo/bar/baz/stuff"); 670 } 671 } 672 673 @Test testCreateFile_withInitialAttributes()674 public void testCreateFile_withInitialAttributes() throws IOException { 675 Set<PosixFilePermission> permissions = PosixFilePermissions.fromString("rwxrwxrwx"); 676 FileAttribute<?> permissionsAttr = PosixFilePermissions.asFileAttribute(permissions); 677 678 Files.createFile(path("/normal")); 679 Files.createFile(path("/foo"), permissionsAttr); 680 681 assertThatPath("/normal").attribute("posix:permissions").isNot(permissions); 682 assertThatPath("/foo").attribute("posix:permissions").is(permissions); 683 } 684 685 @Test testCreateFile_withInitialAttributes_illegalInitialAttribute()686 public void testCreateFile_withInitialAttributes_illegalInitialAttribute() throws IOException { 687 try { 688 Files.createFile( 689 path("/foo"), 690 new BasicFileAttribute<>("basic:lastModifiedTime", FileTime.fromMillis(0L))); 691 fail(); 692 } catch (UnsupportedOperationException expected) { 693 } 694 695 assertThatPath("/foo").doesNotExist(); 696 697 try { 698 Files.createFile(path("/foo"), new BasicFileAttribute<>("basic:noSuchAttribute", "foo")); 699 fail(); 700 } catch (UnsupportedOperationException expected) { 701 } 702 703 assertThatPath("/foo").doesNotExist(); 704 } 705 706 @Test testOpenChannel_withInitialAttributes_createNewFile()707 public void testOpenChannel_withInitialAttributes_createNewFile() throws IOException { 708 FileAttribute<Set<PosixFilePermission>> permissions = 709 PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwxrwxrwx")); 710 Files.newByteChannel(path("/foo"), ImmutableSet.of(WRITE, CREATE), permissions).close(); 711 712 assertThatPath("/foo") 713 .isRegularFile() 714 .and() 715 .attribute("posix:permissions") 716 .is(permissions.value()); 717 } 718 719 @Test testOpenChannel_withInitialAttributes_fileExists()720 public void testOpenChannel_withInitialAttributes_fileExists() throws IOException { 721 Files.createFile(path("/foo")); 722 723 FileAttribute<Set<PosixFilePermission>> permissions = 724 PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwxrwxrwx")); 725 Files.newByteChannel(path("/foo"), ImmutableSet.of(WRITE, CREATE), permissions).close(); 726 727 assertThatPath("/foo") 728 .isRegularFile() 729 .and() 730 .attribute("posix:permissions") 731 .isNot(permissions.value()); 732 } 733 734 @Test testCreateDirectory_withInitialAttributes()735 public void testCreateDirectory_withInitialAttributes() throws IOException { 736 FileAttribute<Set<PosixFilePermission>> permissions = 737 PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwxrwxrwx")); 738 739 Files.createDirectory(path("/foo"), permissions); 740 741 assertThatPath("/foo") 742 .isDirectory() 743 .and() 744 .attribute("posix:permissions") 745 .is(permissions.value()); 746 747 Files.createDirectory(path("/normal")); 748 749 assertThatPath("/normal") 750 .isDirectory() 751 .and() 752 .attribute("posix:permissions") 753 .isNot(permissions.value()); 754 } 755 756 @Test testCreateSymbolicLink_withInitialAttributes()757 public void testCreateSymbolicLink_withInitialAttributes() throws IOException { 758 FileAttribute<Set<PosixFilePermission>> permissions = 759 PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwxrwxrwx")); 760 761 Files.createSymbolicLink(path("/foo"), path("bar"), permissions); 762 763 assertThatPath("/foo", NOFOLLOW_LINKS) 764 .isSymbolicLink() 765 .and() 766 .attribute("posix:permissions") 767 .is(permissions.value()); 768 769 Files.createSymbolicLink(path("/normal"), path("bar")); 770 771 assertThatPath("/normal", NOFOLLOW_LINKS) 772 .isSymbolicLink() 773 .and() 774 .attribute("posix:permissions") 775 .isNot(permissions.value()); 776 } 777 778 @Test testCreateDirectories()779 public void testCreateDirectories() throws IOException { 780 Files.createDirectories(path("/foo/bar/baz")); 781 782 assertThatPath("/foo").isDirectory(); 783 assertThatPath("/foo/bar").isDirectory(); 784 assertThatPath("/foo/bar/baz").isDirectory(); 785 786 Files.createDirectories(path("/foo/asdf/jkl")); 787 788 assertThatPath("/foo/asdf").isDirectory(); 789 assertThatPath("/foo/asdf/jkl").isDirectory(); 790 791 Files.createDirectories(path("bar/baz")); 792 793 assertThatPath("bar/baz").isDirectory(); 794 assertThatPath("/work/bar/baz").isDirectory(); 795 } 796 797 @Test testDirectories_newlyCreatedDirectoryHasTwoLinks()798 public void testDirectories_newlyCreatedDirectoryHasTwoLinks() throws IOException { 799 // one link from its parent to it; one from it to itself 800 801 Files.createDirectory(path("/foo")); 802 803 assertThatPath("/foo").hasLinkCount(2); 804 } 805 806 @Test testDirectories_creatingDirectoryAddsOneLinkToParent()807 public void testDirectories_creatingDirectoryAddsOneLinkToParent() throws IOException { 808 // from the .. direntry 809 810 Files.createDirectory(path("/foo")); 811 Files.createDirectory(path("/foo/bar")); 812 813 assertThatPath("/foo").hasLinkCount(3); 814 815 Files.createDirectory(path("/foo/baz")); 816 817 assertThatPath("/foo").hasLinkCount(4); 818 } 819 820 @Test testDirectories_creatingNonDirectoryDoesNotAddLinkToParent()821 public void testDirectories_creatingNonDirectoryDoesNotAddLinkToParent() throws IOException { 822 Files.createDirectory(path("/foo")); 823 Files.createFile(path("/foo/file")); 824 Files.createSymbolicLink(path("/foo/fileSymlink"), path("file")); 825 Files.createLink(path("/foo/link"), path("/foo/file")); 826 Files.createSymbolicLink(path("/foo/fooSymlink"), path("/foo")); 827 828 assertThatPath("/foo").hasLinkCount(2); 829 } 830 831 @Test testSize_forNewFile_isZero()832 public void testSize_forNewFile_isZero() throws IOException { 833 Files.createFile(path("/test")); 834 835 assertThatPath("/test").hasSize(0); 836 } 837 838 @Test testRead_forNewFile_isEmpty()839 public void testRead_forNewFile_isEmpty() throws IOException { 840 Files.createFile(path("/test")); 841 842 assertThatPath("/test").containsNoBytes(); 843 } 844 845 @Test testWriteFile_succeeds()846 public void testWriteFile_succeeds() throws IOException { 847 Files.createFile(path("/test")); 848 Files.write(path("/test"), new byte[] {0, 1, 2, 3}); 849 } 850 851 @Test testSize_forFileAfterWrite_isNumberOfBytesWritten()852 public void testSize_forFileAfterWrite_isNumberOfBytesWritten() throws IOException { 853 Files.write(path("/test"), new byte[] {0, 1, 2, 3}); 854 855 assertThatPath("/test").hasSize(4); 856 } 857 858 @Test testRead_forFileAfterWrite_isBytesWritten()859 public void testRead_forFileAfterWrite_isBytesWritten() throws IOException { 860 byte[] bytes = {0, 1, 2, 3}; 861 Files.write(path("/test"), bytes); 862 863 assertThatPath("/test").containsBytes(bytes); 864 } 865 866 @Test testWriteFile_withStandardOptions()867 public void testWriteFile_withStandardOptions() throws IOException { 868 Path test = path("/test"); 869 byte[] bytes = {0, 1, 2, 3}; 870 871 try { 872 // CREATE and CREATE_NEW not specified 873 Files.write(test, bytes, WRITE); 874 fail(); 875 } catch (NoSuchFileException expected) { 876 assertEquals(test.toString(), expected.getMessage()); 877 } 878 879 Files.write(test, bytes, CREATE_NEW); // succeeds, file does not exist 880 assertThatPath("/test").containsBytes(bytes); 881 882 try { 883 Files.write(test, bytes, CREATE_NEW); // CREATE_NEW requires file not exist 884 fail(); 885 } catch (FileAlreadyExistsException expected) { 886 assertEquals(test.toString(), expected.getMessage()); 887 } 888 889 Files.write(test, new byte[] {4, 5}, CREATE); // succeeds, ok for file to already exist 890 assertThatPath("/test").containsBytes(4, 5, 2, 3); // did not truncate or append, so overwrote 891 892 Files.write(test, bytes, WRITE, CREATE, TRUNCATE_EXISTING); // default options 893 assertThatPath("/test").containsBytes(bytes); 894 895 Files.write(test, bytes, WRITE, APPEND); 896 assertThatPath("/test").containsBytes(0, 1, 2, 3, 0, 1, 2, 3); 897 898 Files.write(test, bytes, WRITE, CREATE, TRUNCATE_EXISTING, APPEND, SPARSE, DSYNC, SYNC); 899 assertThatPath("/test").containsBytes(bytes); 900 901 try { 902 Files.write(test, bytes, READ, WRITE); // READ not allowed 903 fail(); 904 } catch (UnsupportedOperationException expected) { 905 } 906 } 907 908 @Test testWriteLines_succeeds()909 public void testWriteLines_succeeds() throws IOException { 910 Files.write(path("/test.txt"), ImmutableList.of("hello", "world"), UTF_8); 911 } 912 913 @Test testOpenFile_withReadAndTruncateExisting_doesNotTruncateFile()914 public void testOpenFile_withReadAndTruncateExisting_doesNotTruncateFile() throws IOException { 915 byte[] bytes = bytes(1, 2, 3, 4); 916 Files.write(path("/test"), bytes); 917 918 try (FileChannel channel = FileChannel.open(path("/test"), READ, TRUNCATE_EXISTING)) { 919 // TRUNCATE_EXISTING ignored when opening for read 920 byte[] readBytes = new byte[4]; 921 channel.read(ByteBuffer.wrap(readBytes)); 922 923 assertThat(Bytes.asList(readBytes)).isEqualTo(Bytes.asList(bytes)); 924 } 925 } 926 927 @Test testRead_forFileAfterWriteLines_isLinesWritten()928 public void testRead_forFileAfterWriteLines_isLinesWritten() throws IOException { 929 Files.write(path("/test.txt"), ImmutableList.of("hello", "world"), UTF_8); 930 931 assertThatPath("/test.txt").containsLines("hello", "world"); 932 } 933 934 @Test testWriteLines_withStandardOptions()935 public void testWriteLines_withStandardOptions() throws IOException { 936 Path test = path("/test.txt"); 937 ImmutableList<String> lines = ImmutableList.of("hello", "world"); 938 939 try { 940 // CREATE and CREATE_NEW not specified 941 Files.write(test, lines, UTF_8, WRITE); 942 fail(); 943 } catch (NoSuchFileException expected) { 944 assertEquals(test.toString(), expected.getMessage()); 945 } 946 947 Files.write(test, lines, UTF_8, CREATE_NEW); // succeeds, file does not exist 948 assertThatPath(test).containsLines(lines); 949 950 try { 951 Files.write(test, lines, UTF_8, CREATE_NEW); // CREATE_NEW requires file not exist 952 fail(); 953 } catch (FileAlreadyExistsException expected) { 954 } 955 956 // succeeds, ok for file to already exist 957 Files.write(test, ImmutableList.of("foo"), UTF_8, CREATE); 958 // did not truncate or append, so overwrote 959 if (System.getProperty("line.separator").length() == 2) { 960 // on Windows, an extra character is overwritten by the \r\n line separator 961 assertThatPath(test).containsLines("foo", "", "world"); 962 } else { 963 assertThatPath(test).containsLines("foo", "o", "world"); 964 } 965 966 Files.write(test, lines, UTF_8, WRITE, CREATE, TRUNCATE_EXISTING); // default options 967 assertThatPath(test).containsLines(lines); 968 969 Files.write(test, lines, UTF_8, WRITE, APPEND); 970 assertThatPath(test).containsLines("hello", "world", "hello", "world"); 971 972 Files.write(test, lines, UTF_8, WRITE, CREATE, TRUNCATE_EXISTING, APPEND, SPARSE, DSYNC, SYNC); 973 assertThatPath(test).containsLines(lines); 974 975 try { 976 Files.write(test, lines, UTF_8, READ, WRITE); // READ not allowed 977 fail(); 978 } catch (UnsupportedOperationException expected) { 979 } 980 } 981 982 @Test testWrite_fileExistsButIsNotRegularFile()983 public void testWrite_fileExistsButIsNotRegularFile() throws IOException { 984 Files.createDirectory(path("/foo")); 985 986 try { 987 // non-CREATE mode 988 Files.write(path("/foo"), preFilledBytes(10), WRITE); 989 fail(); 990 } catch (FileSystemException expected) { 991 assertThat(expected.getFile()).isEqualTo("/foo"); 992 assertThat(expected.getMessage()).contains("regular file"); 993 } 994 995 try { 996 // CREATE mode 997 Files.write(path("/foo"), preFilledBytes(10)); 998 fail(); 999 } catch (FileSystemException expected) { 1000 assertThat(expected.getFile()).isEqualTo("/foo"); 1001 assertThat(expected.getMessage()).contains("regular file"); 1002 } 1003 } 1004 1005 @Test testDelete_file()1006 public void testDelete_file() throws IOException { 1007 try { 1008 Files.delete(path("/test")); 1009 fail(); 1010 } catch (NoSuchFileException expected) { 1011 assertEquals("/test", expected.getMessage()); 1012 } 1013 1014 try { 1015 Files.delete(path("/foo/bar")); 1016 fail(); 1017 } catch (NoSuchFileException expected) { 1018 assertEquals("/foo/bar", expected.getMessage()); 1019 } 1020 1021 assertFalse(Files.deleteIfExists(path("/test"))); 1022 assertFalse(Files.deleteIfExists(path("/foo/bar"))); 1023 1024 Files.createFile(path("/test")); 1025 assertThatPath("/test").isRegularFile(); 1026 1027 Files.delete(path("/test")); 1028 assertThatPath("/test").doesNotExist(); 1029 1030 Files.createFile(path("/test")); 1031 1032 assertTrue(Files.deleteIfExists(path("/test"))); 1033 assertThatPath("/test").doesNotExist(); 1034 } 1035 1036 @Test testDelete_file_whenOpenReferencesRemain()1037 public void testDelete_file_whenOpenReferencesRemain() throws IOException { 1038 // the open streams should continue to function normally despite the deletion 1039 1040 Path foo = path("/foo"); 1041 byte[] bytes = preFilledBytes(100); 1042 Files.write(foo, bytes); 1043 1044 InputStream in = Files.newInputStream(foo); 1045 OutputStream out = Files.newOutputStream(foo, APPEND); 1046 FileChannel channel = FileChannel.open(foo, READ, WRITE); 1047 1048 assertThat(channel.size()).isEqualTo(100L); 1049 1050 Files.delete(foo); 1051 assertThatPath("/foo").doesNotExist(); 1052 1053 assertThat(channel.size()).isEqualTo(100L); 1054 1055 ByteBuffer buf = ByteBuffer.allocate(100); 1056 while (buf.hasRemaining()) { 1057 channel.read(buf); 1058 } 1059 1060 assertArrayEquals(bytes, buf.array()); 1061 1062 byte[] moreBytes = {1, 2, 3, 4, 5}; 1063 out.write(moreBytes); 1064 1065 assertThat(channel.size()).isEqualTo(105L); 1066 buf.clear(); 1067 assertThat(channel.read(buf)).isEqualTo(5); 1068 1069 buf.flip(); 1070 byte[] b = new byte[5]; 1071 buf.get(b); 1072 assertArrayEquals(moreBytes, b); 1073 1074 byte[] allBytes = new byte[105]; 1075 int off = 0; 1076 int read; 1077 while ((read = in.read(allBytes, off, allBytes.length - off)) != -1) { 1078 off += read; 1079 } 1080 assertArrayEquals(concat(bytes, moreBytes), allBytes); 1081 1082 channel.close(); 1083 out.close(); 1084 in.close(); 1085 } 1086 1087 @Test testDelete_directory()1088 public void testDelete_directory() throws IOException { 1089 Files.createDirectories(path("/foo/bar")); 1090 assertThatPath("/foo").isDirectory(); 1091 assertThatPath("/foo/bar").isDirectory(); 1092 1093 Files.delete(path("/foo/bar")); 1094 assertThatPath("/foo/bar").doesNotExist(); 1095 1096 assertTrue(Files.deleteIfExists(path("/foo"))); 1097 assertThatPath("/foo").doesNotExist(); 1098 } 1099 1100 @Test testDelete_pathPermutations()1101 public void testDelete_pathPermutations() throws IOException { 1102 Path bar = path("/work/foo/bar"); 1103 Files.createDirectories(bar); 1104 for (Path path : permutations(bar)) { 1105 Files.createDirectories(bar); 1106 assertThatPath(path).isSameFileAs(bar); 1107 Files.delete(path); 1108 assertThatPath(bar).doesNotExist(); 1109 assertThatPath(path).doesNotExist(); 1110 } 1111 1112 Path baz = path("/test/baz"); 1113 Files.createDirectories(baz); 1114 Path hello = baz.resolve("hello.txt"); 1115 for (Path path : permutations(hello)) { 1116 Files.createFile(hello); 1117 assertThatPath(path).isSameFileAs(hello); 1118 Files.delete(path); 1119 assertThatPath(hello).doesNotExist(); 1120 assertThatPath(path).doesNotExist(); 1121 } 1122 } 1123 1124 @Test testDelete_directory_cantDeleteNonEmptyDirectory()1125 public void testDelete_directory_cantDeleteNonEmptyDirectory() throws IOException { 1126 Files.createDirectories(path("/foo/bar")); 1127 1128 try { 1129 Files.delete(path("/foo")); 1130 fail(); 1131 } catch (DirectoryNotEmptyException expected) { 1132 assertThat(expected.getFile()).isEqualTo("/foo"); 1133 } 1134 1135 try { 1136 Files.deleteIfExists(path("/foo")); 1137 fail(); 1138 } catch (DirectoryNotEmptyException expected) { 1139 assertThat(expected.getFile()).isEqualTo("/foo"); 1140 } 1141 } 1142 1143 @Test testDelete_directory_canDeleteWorkingDirectoryByAbsolutePath()1144 public void testDelete_directory_canDeleteWorkingDirectoryByAbsolutePath() throws IOException { 1145 assertThatPath("/work").exists(); 1146 assertThatPath("").exists(); 1147 assertThatPath(".").exists(); 1148 1149 Files.delete(path("/work")); 1150 1151 assertThatPath("/work").doesNotExist(); 1152 assertThatPath("").exists(); 1153 assertThatPath(".").exists(); 1154 } 1155 1156 @Test testDelete_directory_cantDeleteWorkingDirectoryByRelativePath()1157 public void testDelete_directory_cantDeleteWorkingDirectoryByRelativePath() throws IOException { 1158 try { 1159 Files.delete(path("")); 1160 fail(); 1161 } catch (FileSystemException expected) { 1162 assertThat(expected.getFile()).isEqualTo(""); 1163 } 1164 1165 try { 1166 Files.delete(path(".")); 1167 fail(); 1168 } catch (FileSystemException expected) { 1169 assertThat(expected.getFile()).isEqualTo("."); 1170 } 1171 1172 try { 1173 Files.delete(path("../../work")); 1174 fail(); 1175 } catch (FileSystemException expected) { 1176 assertThat(expected.getFile()).isEqualTo("../../work"); 1177 } 1178 1179 try { 1180 Files.delete(path("./../work/.././../work/.")); 1181 fail(); 1182 } catch (FileSystemException expected) { 1183 assertThat(expected.getFile()).isEqualTo("./../work/.././../work/."); 1184 } 1185 } 1186 1187 @Test testDelete_directory_cantDeleteRoot()1188 public void testDelete_directory_cantDeleteRoot() throws IOException { 1189 // delete working directory so that root is empty 1190 // don't want to just be testing the "can't delete when not empty" logic 1191 Files.delete(path("/work")); 1192 1193 try { 1194 Files.delete(path("/")); 1195 fail(); 1196 } catch (IOException expected) { 1197 assertThat(expected.getMessage()).contains("root"); 1198 } 1199 1200 Files.createDirectories(path("/foo/bar")); 1201 1202 try { 1203 Files.delete(path("/foo/bar/../..")); 1204 fail(); 1205 } catch (IOException expected) { 1206 assertThat(expected.getMessage()).contains("root"); 1207 } 1208 1209 try { 1210 Files.delete(path("/foo/./../foo/bar/./../bar/.././../../..")); 1211 fail(); 1212 } catch (IOException expected) { 1213 assertThat(expected.getMessage()).contains("root"); 1214 } 1215 } 1216 1217 @Test testSymbolicLinks()1218 public void testSymbolicLinks() throws IOException { 1219 Files.createSymbolicLink(path("/link.txt"), path("/file.txt")); 1220 assertThatPath("/link.txt", NOFOLLOW_LINKS).isSymbolicLink().withTarget("/file.txt"); 1221 assertThatPath("/link.txt").doesNotExist(); // following the link; target doesn't exist 1222 1223 try { 1224 Files.createFile(path("/link.txt")); 1225 fail(); 1226 } catch (FileAlreadyExistsException expected) { 1227 } 1228 1229 try { 1230 Files.readAllBytes(path("/link.txt")); 1231 fail(); 1232 } catch (NoSuchFileException expected) { 1233 } 1234 1235 Files.createFile(path("/file.txt")); 1236 assertThatPath("/link.txt").isRegularFile(); // following the link; target does exist 1237 assertThatPath("/link.txt").containsNoBytes(); 1238 1239 Files.createSymbolicLink(path("/foo"), path("/bar/baz")); 1240 assertThatPath("/foo", NOFOLLOW_LINKS).isSymbolicLink().withTarget("/bar/baz"); 1241 assertThatPath("/foo").doesNotExist(); // following the link; target doesn't exist 1242 1243 Files.createDirectories(path("/bar/baz")); 1244 assertThatPath("/foo").isDirectory(); // following the link; target does exist 1245 1246 Files.createFile(path("/bar/baz/test.txt")); 1247 assertThatPath("/foo/test.txt", NOFOLLOW_LINKS).isRegularFile(); // follow intermediate link 1248 1249 try { 1250 Files.readSymbolicLink(path("/none")); 1251 fail(); 1252 } catch (NoSuchFileException expected) { 1253 assertEquals("/none", expected.getMessage()); 1254 } 1255 1256 try { 1257 Files.readSymbolicLink(path("/file.txt")); 1258 fail(); 1259 } catch (NotLinkException expected) { 1260 assertEquals("/file.txt", expected.getMessage()); 1261 } 1262 } 1263 1264 @Test testSymbolicLinks_symlinkCycle()1265 public void testSymbolicLinks_symlinkCycle() throws IOException { 1266 Files.createDirectory(path("/foo")); 1267 Files.createSymbolicLink(path("/foo/bar"), path("baz")); 1268 Files.createSymbolicLink(path("/foo/baz"), path("bar")); 1269 1270 try { 1271 Files.createFile(path("/foo/bar/file")); 1272 fail(); 1273 } catch (IOException expected) { 1274 assertThat(expected.getMessage()).contains("symbolic link"); 1275 } 1276 1277 try { 1278 Files.write(path("/foo/bar"), preFilledBytes(10)); 1279 fail(); 1280 } catch (IOException expected) { 1281 assertThat(expected.getMessage()).contains("symbolic link"); 1282 } 1283 } 1284 1285 @Test testSymbolicLinks_lookupOfAbsoluteSymlinkPathFromRelativePath()1286 public void testSymbolicLinks_lookupOfAbsoluteSymlinkPathFromRelativePath() throws IOException { 1287 // relative path lookups are in the FileSystemView for the working directory 1288 // this tests that when an absolute path is encountered, the lookup handles it correctly 1289 1290 Files.createDirectories(path("/foo/bar/baz")); 1291 Files.createFile(path("/foo/bar/baz/file")); 1292 Files.createDirectories(path("one/two/three")); 1293 Files.createSymbolicLink(path("/work/one/two/three/link"), path("/foo/bar")); 1294 1295 assertThatPath("one/two/three/link/baz/file").isSameFileAs("/foo/bar/baz/file"); 1296 } 1297 1298 @Test testLink()1299 public void testLink() throws IOException { 1300 Files.createFile(path("/file.txt")); 1301 // checking link count requires "unix" attribute support, which we're using here 1302 assertThatPath("/file.txt").hasLinkCount(1); 1303 1304 Files.createLink(path("/link.txt"), path("/file.txt")); 1305 1306 assertThatPath("/link.txt").isSameFileAs("/file.txt"); 1307 1308 assertThatPath("/file.txt").hasLinkCount(2); 1309 assertThatPath("/link.txt").hasLinkCount(2); 1310 1311 assertThatPath("/file.txt").containsNoBytes(); 1312 assertThatPath("/link.txt").containsNoBytes(); 1313 1314 byte[] bytes = {0, 1, 2, 3}; 1315 Files.write(path("/file.txt"), bytes); 1316 1317 assertThatPath("/file.txt").containsBytes(bytes); 1318 assertThatPath("/link.txt").containsBytes(bytes); 1319 1320 Files.write(path("/link.txt"), bytes, APPEND); 1321 1322 assertThatPath("/file.txt").containsBytes(0, 1, 2, 3, 0, 1, 2, 3); 1323 assertThatPath("/link.txt").containsBytes(0, 1, 2, 3, 0, 1, 2, 3); 1324 1325 Files.delete(path("/file.txt")); 1326 assertThatPath("/link.txt").hasLinkCount(1); 1327 1328 assertThatPath("/link.txt").containsBytes(0, 1, 2, 3, 0, 1, 2, 3); 1329 } 1330 1331 @Test testLink_forSymbolicLink_usesSymbolicLinkTarget()1332 public void testLink_forSymbolicLink_usesSymbolicLinkTarget() throws IOException { 1333 Files.createFile(path("/file")); 1334 Files.createSymbolicLink(path("/symlink"), path("/file")); 1335 1336 Object key = getFileKey("/file"); 1337 1338 Files.createLink(path("/link"), path("/symlink")); 1339 1340 assertThatPath("/link") 1341 .isRegularFile() 1342 .and() 1343 .hasLinkCount(2) 1344 .and() 1345 .attribute("fileKey") 1346 .is(key); 1347 } 1348 1349 @Test testLink_failsWhenTargetDoesNotExist()1350 public void testLink_failsWhenTargetDoesNotExist() throws IOException { 1351 try { 1352 Files.createLink(path("/link"), path("/foo")); 1353 fail(); 1354 } catch (NoSuchFileException expected) { 1355 assertEquals("/foo", expected.getFile()); 1356 } 1357 1358 Files.createSymbolicLink(path("/foo"), path("/bar")); 1359 1360 try { 1361 Files.createLink(path("/link"), path("/foo")); 1362 fail(); 1363 } catch (NoSuchFileException expected) { 1364 assertEquals("/foo", expected.getFile()); 1365 } 1366 } 1367 1368 @Test testLink_failsForNonRegularFile()1369 public void testLink_failsForNonRegularFile() throws IOException { 1370 Files.createDirectory(path("/dir")); 1371 1372 try { 1373 Files.createLink(path("/link"), path("/dir")); 1374 fail(); 1375 } catch (FileSystemException expected) { 1376 assertEquals("/link", expected.getFile()); 1377 assertEquals("/dir", expected.getOtherFile()); 1378 } 1379 1380 assertThatPath("/link").doesNotExist(); 1381 } 1382 1383 @Test testLinks_failsWhenTargetFileAlreadyExists()1384 public void testLinks_failsWhenTargetFileAlreadyExists() throws IOException { 1385 Files.createFile(path("/file")); 1386 Files.createFile(path("/link")); 1387 1388 try { 1389 Files.createLink(path("/link"), path("/file")); 1390 fail(); 1391 } catch (FileAlreadyExistsException expected) { 1392 assertEquals("/link", expected.getFile()); 1393 } 1394 } 1395 1396 @Test testStreams()1397 public void testStreams() throws IOException { 1398 try (OutputStream out = Files.newOutputStream(path("/test"))) { 1399 for (int i = 0; i < 100; i++) { 1400 out.write(i); 1401 } 1402 } 1403 1404 byte[] expected = new byte[100]; 1405 for (byte i = 0; i < 100; i++) { 1406 expected[i] = i; 1407 } 1408 1409 try (InputStream in = Files.newInputStream(path("/test"))) { 1410 byte[] bytes = new byte[100]; 1411 ByteStreams.readFully(in, bytes); 1412 assertArrayEquals(expected, bytes); 1413 } 1414 1415 try (Writer writer = Files.newBufferedWriter(path("/test.txt"), UTF_8)) { 1416 writer.write("hello"); 1417 } 1418 1419 try (Reader reader = Files.newBufferedReader(path("/test.txt"), UTF_8)) { 1420 assertEquals("hello", CharStreams.toString(reader)); 1421 } 1422 1423 try (Writer writer = Files.newBufferedWriter(path("/test.txt"), UTF_8, APPEND)) { 1424 writer.write(" world"); 1425 } 1426 1427 try (Reader reader = Files.newBufferedReader(path("/test.txt"), UTF_8)) { 1428 assertEquals("hello world", CharStreams.toString(reader)); 1429 } 1430 } 1431 1432 @Test testOutputStream_withTruncateExistingAndNotWrite_truncatesFile()1433 public void testOutputStream_withTruncateExistingAndNotWrite_truncatesFile() throws IOException { 1434 // https://github.com/google/jimfs/pull/77 1435 Path path = path("/test"); 1436 Files.write(path, new byte[] {1, 2, 3}); 1437 assertThatPath(path).containsBytes(1, 2, 3); 1438 1439 try (OutputStream out = Files.newOutputStream(path, CREATE, TRUNCATE_EXISTING)) { 1440 out.write(new byte[] {1, 2}); 1441 } 1442 1443 assertThatPath(path).containsBytes(1, 2); 1444 } 1445 1446 @Test testChannels()1447 public void testChannels() throws IOException { 1448 try (FileChannel channel = FileChannel.open(path("/test.txt"), CREATE_NEW, WRITE)) { 1449 ByteBuffer buf1 = UTF_8.encode("hello"); 1450 ByteBuffer buf2 = UTF_8.encode(" world"); 1451 while (buf1.hasRemaining() || buf2.hasRemaining()) { 1452 channel.write(new ByteBuffer[] {buf1, buf2}); 1453 } 1454 1455 assertEquals(11, channel.position()); 1456 assertEquals(11, channel.size()); 1457 1458 channel.write(UTF_8.encode("!")); 1459 1460 assertEquals(12, channel.position()); 1461 assertEquals(12, channel.size()); 1462 } 1463 1464 try (SeekableByteChannel channel = Files.newByteChannel(path("/test.txt"), READ)) { 1465 assertEquals(0, channel.position()); 1466 assertEquals(12, channel.size()); 1467 1468 ByteBuffer buffer = ByteBuffer.allocate(100); 1469 while (channel.read(buffer) != -1) {} 1470 buffer.flip(); 1471 assertEquals("hello world!", UTF_8.decode(buffer).toString()); 1472 } 1473 1474 byte[] bytes = preFilledBytes(100); 1475 1476 Files.write(path("/test"), bytes); 1477 1478 try (SeekableByteChannel channel = Files.newByteChannel(path("/test"), READ, WRITE)) { 1479 ByteBuffer buffer = ByteBuffer.wrap(preFilledBytes(50)); 1480 1481 channel.position(50); 1482 channel.write(buffer); 1483 buffer.flip(); 1484 channel.write(buffer); 1485 1486 channel.position(0); 1487 ByteBuffer readBuffer = ByteBuffer.allocate(150); 1488 while (readBuffer.hasRemaining()) { 1489 channel.read(readBuffer); 1490 } 1491 1492 byte[] expected = Bytes.concat(preFilledBytes(50), preFilledBytes(50), preFilledBytes(50)); 1493 1494 assertArrayEquals(expected, readBuffer.array()); 1495 } 1496 1497 try (FileChannel channel = FileChannel.open(path("/test"), READ, WRITE)) { 1498 assertEquals(150, channel.size()); 1499 1500 channel.truncate(10); 1501 assertEquals(10, channel.size()); 1502 1503 ByteBuffer buffer = ByteBuffer.allocate(20); 1504 assertEquals(10, channel.read(buffer)); 1505 buffer.flip(); 1506 1507 byte[] expected = new byte[20]; 1508 System.arraycopy(preFilledBytes(10), 0, expected, 0, 10); 1509 assertArrayEquals(expected, buffer.array()); 1510 } 1511 } 1512 1513 @Test testCopy_inputStreamToFile()1514 public void testCopy_inputStreamToFile() throws IOException { 1515 byte[] bytes = preFilledBytes(512); 1516 1517 Files.copy(new ByteArrayInputStream(bytes), path("/test")); 1518 assertThatPath("/test").containsBytes(bytes); 1519 1520 try { 1521 Files.copy(new ByteArrayInputStream(bytes), path("/test")); 1522 fail(); 1523 } catch (FileAlreadyExistsException expected) { 1524 assertEquals("/test", expected.getMessage()); 1525 } 1526 1527 Files.copy(new ByteArrayInputStream(bytes), path("/test"), REPLACE_EXISTING); 1528 assertThatPath("/test").containsBytes(bytes); 1529 1530 Files.copy(new ByteArrayInputStream(bytes), path("/foo"), REPLACE_EXISTING); 1531 assertThatPath("/foo").containsBytes(bytes); 1532 } 1533 1534 @Test testCopy_fileToOutputStream()1535 public void testCopy_fileToOutputStream() throws IOException { 1536 byte[] bytes = preFilledBytes(512); 1537 Files.write(path("/test"), bytes); 1538 1539 ByteArrayOutputStream out = new ByteArrayOutputStream(); 1540 Files.copy(path("/test"), out); 1541 assertArrayEquals(bytes, out.toByteArray()); 1542 } 1543 1544 @Test testCopy_fileToPath()1545 public void testCopy_fileToPath() throws IOException { 1546 byte[] bytes = preFilledBytes(512); 1547 Files.write(path("/foo"), bytes); 1548 1549 assertThatPath("/bar").doesNotExist(); 1550 Files.copy(path("/foo"), path("/bar")); 1551 assertThatPath("/bar").containsBytes(bytes); 1552 1553 byte[] moreBytes = preFilledBytes(2048); 1554 Files.write(path("/baz"), moreBytes); 1555 1556 Files.copy(path("/baz"), path("/bar"), REPLACE_EXISTING); 1557 assertThatPath("/bar").containsBytes(moreBytes); 1558 1559 try { 1560 Files.copy(path("/none"), path("/bar")); 1561 fail(); 1562 } catch (NoSuchFileException expected) { 1563 assertEquals("/none", expected.getMessage()); 1564 } 1565 } 1566 1567 @Test testCopy_withCopyAttributes()1568 public void testCopy_withCopyAttributes() throws IOException { 1569 Path foo = path("/foo"); 1570 Files.createFile(foo); 1571 1572 Files.getFileAttributeView(foo, BasicFileAttributeView.class) 1573 .setTimes(FileTime.fromMillis(100), FileTime.fromMillis(1000), FileTime.fromMillis(10000)); 1574 1575 assertThat(Files.getAttribute(foo, "lastModifiedTime")).isEqualTo(FileTime.fromMillis(100)); 1576 1577 UserPrincipal zero = fs.getUserPrincipalLookupService().lookupPrincipalByName("zero"); 1578 Files.setAttribute(foo, "owner:owner", zero); 1579 1580 Path bar = path("/bar"); 1581 Files.copy(foo, bar, COPY_ATTRIBUTES); 1582 1583 BasicFileAttributes attributes = Files.readAttributes(bar, BasicFileAttributes.class); 1584 assertThat(attributes.lastModifiedTime()).isEqualTo(FileTime.fromMillis(100)); 1585 assertThat(attributes.lastAccessTime()).isEqualTo(FileTime.fromMillis(1000)); 1586 assertThat(attributes.creationTime()).isEqualTo(FileTime.fromMillis(10000)); 1587 assertThat(Files.getAttribute(bar, "owner:owner")).isEqualTo(zero); 1588 1589 Path baz = path("/baz"); 1590 Files.copy(foo, baz); 1591 1592 // test that attributes are not copied when COPY_ATTRIBUTES is not specified 1593 attributes = Files.readAttributes(baz, BasicFileAttributes.class); 1594 assertThat(attributes.lastModifiedTime()).isNotEqualTo(FileTime.fromMillis(100)); 1595 assertThat(attributes.lastAccessTime()).isNotEqualTo(FileTime.fromMillis(1000)); 1596 assertThat(attributes.creationTime()).isNotEqualTo(FileTime.fromMillis(10000)); 1597 assertThat(Files.getAttribute(baz, "owner:owner")).isNotEqualTo(zero); 1598 } 1599 1600 @Test testCopy_doesNotSupportAtomicMove()1601 public void testCopy_doesNotSupportAtomicMove() throws IOException { 1602 try { 1603 Files.copy(path("/foo"), path("/bar"), ATOMIC_MOVE); 1604 fail(); 1605 } catch (UnsupportedOperationException expected) { 1606 } 1607 } 1608 1609 @Test testCopy_directoryToPath()1610 public void testCopy_directoryToPath() throws IOException { 1611 Files.createDirectory(path("/foo")); 1612 1613 assertThatPath("/bar").doesNotExist(); 1614 Files.copy(path("/foo"), path("/bar")); 1615 assertThatPath("/bar").isDirectory(); 1616 } 1617 1618 @Test testCopy_withoutReplaceExisting_failsWhenTargetExists()1619 public void testCopy_withoutReplaceExisting_failsWhenTargetExists() throws IOException { 1620 Files.createFile(path("/bar")); 1621 Files.createDirectory(path("/foo")); 1622 1623 // dir -> file 1624 try { 1625 Files.copy(path("/foo"), path("/bar")); 1626 fail(); 1627 } catch (FileAlreadyExistsException expected) { 1628 assertEquals("/bar", expected.getMessage()); 1629 } 1630 1631 Files.delete(path("/foo")); 1632 Files.createFile(path("/foo")); 1633 1634 // file -> file 1635 try { 1636 Files.copy(path("/foo"), path("/bar")); 1637 fail(); 1638 } catch (FileAlreadyExistsException expected) { 1639 assertEquals("/bar", expected.getMessage()); 1640 } 1641 1642 Files.delete(path("/bar")); 1643 Files.createDirectory(path("/bar")); 1644 1645 // file -> dir 1646 try { 1647 Files.copy(path("/foo"), path("/bar")); 1648 fail(); 1649 } catch (FileAlreadyExistsException expected) { 1650 assertEquals("/bar", expected.getMessage()); 1651 } 1652 1653 Files.delete(path("/foo")); 1654 Files.createDirectory(path("/foo")); 1655 1656 // dir -> dir 1657 try { 1658 Files.copy(path("/foo"), path("/bar")); 1659 fail(); 1660 } catch (FileAlreadyExistsException expected) { 1661 assertEquals("/bar", expected.getMessage()); 1662 } 1663 } 1664 1665 @Test testCopy_withReplaceExisting()1666 public void testCopy_withReplaceExisting() throws IOException { 1667 Files.createFile(path("/bar")); 1668 Files.createDirectory(path("/test")); 1669 1670 assertThatPath("/bar").isRegularFile(); 1671 1672 // overwrite regular file w/ directory 1673 Files.copy(path("/test"), path("/bar"), REPLACE_EXISTING); 1674 1675 assertThatPath("/bar").isDirectory(); 1676 1677 byte[] bytes = {0, 1, 2, 3}; 1678 Files.write(path("/baz"), bytes); 1679 1680 // overwrite directory w/ regular file 1681 Files.copy(path("/baz"), path("/bar"), REPLACE_EXISTING); 1682 1683 assertThatPath("/bar").containsSameBytesAs("/baz"); 1684 } 1685 1686 @Test testCopy_withReplaceExisting_cantReplaceNonEmptyDirectory()1687 public void testCopy_withReplaceExisting_cantReplaceNonEmptyDirectory() throws IOException { 1688 Files.createDirectory(path("/foo")); 1689 Files.createDirectory(path("/foo/bar")); 1690 Files.createFile(path("/foo/baz")); 1691 1692 Files.createDirectory(path("/test")); 1693 1694 try { 1695 Files.copy(path("/test"), path("/foo"), REPLACE_EXISTING); 1696 fail(); 1697 } catch (DirectoryNotEmptyException expected) { 1698 assertEquals("/foo", expected.getMessage()); 1699 } 1700 1701 Files.delete(path("/test")); 1702 Files.createFile(path("/test")); 1703 1704 try { 1705 Files.copy(path("/test"), path("/foo"), REPLACE_EXISTING); 1706 fail(); 1707 } catch (DirectoryNotEmptyException expected) { 1708 assertEquals("/foo", expected.getMessage()); 1709 } 1710 1711 Files.delete(path("/foo/baz")); 1712 Files.delete(path("/foo/bar")); 1713 1714 Files.copy(path("/test"), path("/foo"), REPLACE_EXISTING); 1715 assertThatPath("/foo").isRegularFile(); // replaced 1716 } 1717 1718 @Test testCopy_directoryToPath_doesNotCopyDirectoryContents()1719 public void testCopy_directoryToPath_doesNotCopyDirectoryContents() throws IOException { 1720 Files.createDirectory(path("/foo")); 1721 Files.createDirectory(path("/foo/baz")); 1722 Files.createFile(path("/foo/test")); 1723 1724 Files.copy(path("/foo"), path("/bar")); 1725 assertThatPath("/bar").hasNoChildren(); 1726 } 1727 1728 @Test testCopy_symbolicLinkToPath()1729 public void testCopy_symbolicLinkToPath() throws IOException { 1730 byte[] bytes = preFilledBytes(128); 1731 Files.write(path("/test"), bytes); 1732 Files.createSymbolicLink(path("/link"), path("/test")); 1733 1734 assertThatPath("/bar").doesNotExist(); 1735 Files.copy(path("/link"), path("/bar")); 1736 assertThatPath("/bar", NOFOLLOW_LINKS).containsBytes(bytes); 1737 1738 Files.delete(path("/bar")); 1739 1740 Files.copy(path("/link"), path("/bar"), NOFOLLOW_LINKS); 1741 assertThatPath("/bar", NOFOLLOW_LINKS).isSymbolicLink().withTarget("/test"); 1742 assertThatPath("/bar").isRegularFile(); 1743 assertThatPath("/bar").containsBytes(bytes); 1744 1745 Files.delete(path("/test")); 1746 assertThatPath("/bar", NOFOLLOW_LINKS).isSymbolicLink(); 1747 assertThatPath("/bar").doesNotExist(); 1748 } 1749 1750 @Test testCopy_toDifferentFileSystem()1751 public void testCopy_toDifferentFileSystem() throws IOException { 1752 try (FileSystem fs2 = Jimfs.newFileSystem(UNIX_CONFIGURATION)) { 1753 Path foo = fs.getPath("/foo"); 1754 byte[] bytes = {0, 1, 2, 3, 4}; 1755 Files.write(foo, bytes); 1756 1757 Path foo2 = fs2.getPath("/foo"); 1758 Files.copy(foo, foo2); 1759 1760 assertThatPath(foo).exists(); 1761 assertThatPath(foo2).exists().and().containsBytes(bytes); 1762 } 1763 } 1764 1765 @Test testCopy_toDifferentFileSystem_copyAttributes()1766 public void testCopy_toDifferentFileSystem_copyAttributes() throws IOException { 1767 try (FileSystem fs2 = Jimfs.newFileSystem(UNIX_CONFIGURATION)) { 1768 Path foo = fs.getPath("/foo"); 1769 byte[] bytes = {0, 1, 2, 3, 4}; 1770 Files.write(foo, bytes); 1771 Files.getFileAttributeView(foo, BasicFileAttributeView.class) 1772 .setTimes(FileTime.fromMillis(0), FileTime.fromMillis(1), FileTime.fromMillis(2)); 1773 1774 UserPrincipal owner = fs.getUserPrincipalLookupService().lookupPrincipalByName("foobar"); 1775 Files.setOwner(foo, owner); 1776 1777 assertThatPath(foo).attribute("owner:owner").is(owner); 1778 1779 Path foo2 = fs2.getPath("/foo"); 1780 Files.copy(foo, foo2, COPY_ATTRIBUTES); 1781 1782 assertThatPath(foo).exists(); 1783 1784 // when copying with COPY_ATTRIBUTES to a different FileSystem, only basic attributes (that 1785 // is, file times) can actually be copied 1786 assertThatPath(foo2) 1787 .exists() 1788 .and() 1789 .attribute("lastModifiedTime") 1790 .is(FileTime.fromMillis(0)) 1791 .and() 1792 .attribute("lastAccessTime") 1793 .is(FileTime.fromMillis(1)) 1794 .and() 1795 .attribute("creationTime") 1796 .is(FileTime.fromMillis(2)) 1797 .and() 1798 .attribute("owner:owner") 1799 .isNot(owner) 1800 .and() 1801 .attribute("owner:owner") 1802 .isNot(fs2.getUserPrincipalLookupService().lookupPrincipalByName("foobar")) 1803 .and() 1804 .containsBytes(bytes); // do this last; it updates the access time 1805 } 1806 } 1807 1808 @Test testMove()1809 public void testMove() throws IOException { 1810 byte[] bytes = preFilledBytes(100); 1811 Files.write(path("/foo"), bytes); 1812 1813 Object fooKey = getFileKey("/foo"); 1814 1815 Files.move(path("/foo"), path("/bar")); 1816 assertThatPath("/foo").doesNotExist(); 1817 assertThatPath("/bar").containsBytes(bytes).and().attribute("fileKey").is(fooKey); 1818 1819 Files.createDirectory(path("/foo")); 1820 Files.move(path("/bar"), path("/foo/bar")); 1821 1822 assertThatPath("/bar").doesNotExist(); 1823 assertThatPath("/foo/bar").isRegularFile(); 1824 1825 Files.move(path("/foo"), path("/baz")); 1826 assertThatPath("/foo").doesNotExist(); 1827 assertThatPath("/baz").isDirectory(); 1828 assertThatPath("/baz/bar").isRegularFile(); 1829 } 1830 1831 @Test testMove_movesSymbolicLinkNotTarget()1832 public void testMove_movesSymbolicLinkNotTarget() throws IOException { 1833 byte[] bytes = preFilledBytes(100); 1834 Files.write(path("/foo.txt"), bytes); 1835 1836 Files.createSymbolicLink(path("/link"), path("foo.txt")); 1837 1838 Files.move(path("/link"), path("/link.txt")); 1839 1840 assertThatPath("/foo.txt").noFollowLinks().isRegularFile().and().containsBytes(bytes); 1841 1842 assertThatPath(path("/link")).doesNotExist(); 1843 1844 assertThatPath(path("/link.txt")).noFollowLinks().isSymbolicLink(); 1845 1846 assertThatPath(path("/link.txt")).isRegularFile().and().containsBytes(bytes); 1847 } 1848 1849 @Test testMove_cannotMoveDirIntoOwnSubtree()1850 public void testMove_cannotMoveDirIntoOwnSubtree() throws IOException { 1851 Files.createDirectories(path("/foo")); 1852 1853 try { 1854 Files.move(path("/foo"), path("/foo/bar")); 1855 fail(); 1856 } catch (IOException expected) { 1857 assertThat(expected.getMessage()).contains("sub"); 1858 } 1859 1860 Files.createDirectories(path("/foo/bar/baz/stuff")); 1861 Files.createDirectories(path("/hello/world")); 1862 Files.createSymbolicLink(path("/hello/world/link"), path("../../foo/bar/baz")); 1863 1864 try { 1865 Files.move(path("/foo/bar"), path("/hello/world/link/bar")); 1866 fail(); 1867 } catch (IOException expected) { 1868 assertThat(expected.getMessage()).contains("sub"); 1869 } 1870 } 1871 1872 @Test testMove_withoutReplaceExisting_failsWhenTargetExists()1873 public void testMove_withoutReplaceExisting_failsWhenTargetExists() throws IOException { 1874 byte[] bytes = preFilledBytes(50); 1875 Files.write(path("/test"), bytes); 1876 1877 Object testKey = getFileKey("/test"); 1878 1879 Files.createFile(path("/bar")); 1880 1881 try { 1882 Files.move(path("/test"), path("/bar"), ATOMIC_MOVE); 1883 fail(); 1884 } catch (FileAlreadyExistsException expected) { 1885 assertEquals("/bar", expected.getMessage()); 1886 } 1887 1888 assertThatPath("/test").containsBytes(bytes).and().attribute("fileKey").is(testKey); 1889 1890 Files.delete(path("/bar")); 1891 Files.createDirectory(path("/bar")); 1892 1893 try { 1894 Files.move(path("/test"), path("/bar"), ATOMIC_MOVE); 1895 fail(); 1896 } catch (FileAlreadyExistsException expected) { 1897 assertEquals("/bar", expected.getMessage()); 1898 } 1899 1900 assertThatPath("/test").containsBytes(bytes).and().attribute("fileKey").is(testKey); 1901 } 1902 1903 @Test testMove_toDifferentFileSystem()1904 public void testMove_toDifferentFileSystem() throws IOException { 1905 try (FileSystem fs2 = Jimfs.newFileSystem(Configuration.unix())) { 1906 Path foo = fs.getPath("/foo"); 1907 byte[] bytes = {0, 1, 2, 3, 4}; 1908 Files.write(foo, bytes); 1909 Files.getFileAttributeView(foo, BasicFileAttributeView.class) 1910 .setTimes(FileTime.fromMillis(0), FileTime.fromMillis(1), FileTime.fromMillis(2)); 1911 1912 Path foo2 = fs2.getPath("/foo"); 1913 Files.move(foo, foo2); 1914 1915 assertThatPath(foo).doesNotExist(); 1916 assertThatPath(foo2) 1917 .exists() 1918 .and() 1919 .attribute("lastModifiedTime") 1920 .is(FileTime.fromMillis(0)) 1921 .and() 1922 .attribute("lastAccessTime") 1923 .is(FileTime.fromMillis(1)) 1924 .and() 1925 .attribute("creationTime") 1926 .is(FileTime.fromMillis(2)) 1927 .and() 1928 .containsBytes(bytes); // do this last; it updates the access time 1929 } 1930 } 1931 1932 @Test testIsSameFile()1933 public void testIsSameFile() throws IOException { 1934 Files.createDirectory(path("/foo")); 1935 Files.createSymbolicLink(path("/bar"), path("/foo")); 1936 Files.createFile(path("/bar/test")); 1937 1938 assertThatPath("/foo").isSameFileAs("/foo"); 1939 assertThatPath("/bar").isSameFileAs("/bar"); 1940 assertThatPath("/foo/test").isSameFileAs("/foo/test"); 1941 assertThatPath("/bar/test").isSameFileAs("/bar/test"); 1942 assertThatPath("/foo").isNotSameFileAs("test"); 1943 assertThatPath("/bar").isNotSameFileAs("/test"); 1944 assertThatPath("/foo").isSameFileAs("/bar"); 1945 assertThatPath("/foo/test").isSameFileAs("/bar/test"); 1946 1947 Files.createSymbolicLink(path("/baz"), path("bar")); // relative path 1948 assertThatPath("/baz").isSameFileAs("/foo"); 1949 assertThatPath("/baz/test").isSameFileAs("/foo/test"); 1950 } 1951 1952 @Test testIsSameFile_forPathFromDifferentFileSystemProvider()1953 public void testIsSameFile_forPathFromDifferentFileSystemProvider() throws IOException { 1954 Path defaultFileSystemRoot = FileSystems.getDefault().getRootDirectories().iterator().next(); 1955 1956 assertThat(Files.isSameFile(path("/"), defaultFileSystemRoot)).isFalse(); 1957 } 1958 1959 @Test testPathLookups()1960 public void testPathLookups() throws IOException { 1961 assertThatPath("/").isSameFileAs("/"); 1962 assertThatPath("/..").isSameFileAs("/"); 1963 assertThatPath("/../../..").isSameFileAs("/"); 1964 assertThatPath("../../../..").isSameFileAs("/"); 1965 assertThatPath("").isSameFileAs("/work"); 1966 1967 Files.createDirectories(path("/foo/bar/baz")); 1968 Files.createSymbolicLink(path("/foo/bar/link1"), path("../link2")); 1969 Files.createSymbolicLink(path("/foo/link2"), path("/")); 1970 1971 assertThatPath("/foo/bar/link1/foo/bar/link1/foo").isSameFileAs("/foo"); 1972 } 1973 1974 @Test testSecureDirectoryStream()1975 public void testSecureDirectoryStream() throws IOException { 1976 Files.createDirectories(path("/foo/bar")); 1977 Files.createFile(path("/foo/a")); 1978 Files.createFile(path("/foo/b")); 1979 Files.createSymbolicLink(path("/foo/barLink"), path("bar")); 1980 1981 try (DirectoryStream<Path> stream = Files.newDirectoryStream(path("/foo"))) { 1982 if (!(stream instanceof SecureDirectoryStream)) { 1983 fail("should be a secure directory stream"); 1984 } 1985 1986 SecureDirectoryStream<Path> secureStream = (SecureDirectoryStream<Path>) stream; 1987 1988 assertThat(ImmutableList.copyOf(secureStream)) 1989 .isEqualTo( 1990 ImmutableList.of( 1991 path("/foo/a"), path("/foo/b"), path("/foo/bar"), path("/foo/barLink"))); 1992 1993 secureStream.deleteFile(path("b")); 1994 assertThatPath("/foo/b").doesNotExist(); 1995 1996 secureStream.newByteChannel(path("b"), ImmutableSet.of(WRITE, CREATE_NEW)).close(); 1997 assertThatPath("/foo/b").isRegularFile(); 1998 1999 assertThatPath("/foo").hasChildren("a", "b", "bar", "barLink"); 2000 2001 Files.createDirectory(path("/baz")); 2002 Files.move(path("/foo"), path("/baz/stuff")); 2003 2004 assertThatPath(path("/foo")).doesNotExist(); 2005 2006 assertThatPath("/baz/stuff").hasChildren("a", "b", "bar", "barLink"); 2007 2008 secureStream.deleteFile(path("b")); 2009 2010 assertThatPath("/baz/stuff/b").doesNotExist(); 2011 assertThatPath("/baz/stuff").hasChildren("a", "bar", "barLink"); 2012 2013 assertThat( 2014 secureStream 2015 .getFileAttributeView(BasicFileAttributeView.class) 2016 .readAttributes() 2017 .isDirectory()) 2018 .isTrue(); 2019 2020 assertThat( 2021 secureStream 2022 .getFileAttributeView(path("a"), BasicFileAttributeView.class) 2023 .readAttributes() 2024 .isRegularFile()) 2025 .isTrue(); 2026 2027 try { 2028 secureStream.deleteFile(path("bar")); 2029 fail(); 2030 } catch (FileSystemException expected) { 2031 assertThat(expected.getFile()).isEqualTo("bar"); 2032 } 2033 2034 try { 2035 secureStream.deleteDirectory(path("a")); 2036 fail(); 2037 } catch (FileSystemException expected) { 2038 assertThat(expected.getFile()).isEqualTo("a"); 2039 } 2040 2041 try (SecureDirectoryStream<Path> barStream = secureStream.newDirectoryStream(path("bar"))) { 2042 barStream.newByteChannel(path("stuff"), ImmutableSet.of(WRITE, CREATE_NEW)).close(); 2043 assertThat( 2044 barStream 2045 .getFileAttributeView(path("stuff"), BasicFileAttributeView.class) 2046 .readAttributes() 2047 .isRegularFile()) 2048 .isTrue(); 2049 2050 assertThat( 2051 secureStream 2052 .getFileAttributeView(path("bar/stuff"), BasicFileAttributeView.class) 2053 .readAttributes() 2054 .isRegularFile()) 2055 .isTrue(); 2056 } 2057 2058 try (SecureDirectoryStream<Path> barLinkStream = 2059 secureStream.newDirectoryStream(path("barLink"))) { 2060 assertThat( 2061 barLinkStream 2062 .getFileAttributeView(path("stuff"), BasicFileAttributeView.class) 2063 .readAttributes() 2064 .isRegularFile()) 2065 .isTrue(); 2066 2067 assertThat( 2068 barLinkStream 2069 .getFileAttributeView(path(".."), BasicFileAttributeView.class) 2070 .readAttributes() 2071 .isDirectory()) 2072 .isTrue(); 2073 } 2074 2075 try { 2076 secureStream.newDirectoryStream(path("barLink"), NOFOLLOW_LINKS); 2077 fail(); 2078 } catch (NotDirectoryException expected) { 2079 assertThat(expected.getFile()).isEqualTo("barLink"); 2080 } 2081 2082 try (SecureDirectoryStream<Path> barStream = secureStream.newDirectoryStream(path("bar"))) { 2083 secureStream.move(path("a"), barStream, path("moved")); 2084 2085 assertThatPath(path("/baz/stuff/a")).doesNotExist(); 2086 assertThatPath(path("/baz/stuff/bar/moved")).isRegularFile(); 2087 2088 assertThat( 2089 barStream 2090 .getFileAttributeView(path("moved"), BasicFileAttributeView.class) 2091 .readAttributes() 2092 .isRegularFile()) 2093 .isTrue(); 2094 } 2095 } 2096 } 2097 2098 @Test testSecureDirectoryStreamBasedOnRelativePath()2099 public void testSecureDirectoryStreamBasedOnRelativePath() throws IOException { 2100 Files.createDirectories(path("foo")); 2101 Files.createFile(path("foo/a")); 2102 Files.createFile(path("foo/b")); 2103 Files.createDirectory(path("foo/c")); 2104 Files.createFile(path("foo/c/d")); 2105 Files.createFile(path("foo/c/e")); 2106 2107 try (DirectoryStream<Path> stream = Files.newDirectoryStream(path("foo"))) { 2108 SecureDirectoryStream<Path> secureStream = (SecureDirectoryStream<Path>) stream; 2109 2110 assertThat(ImmutableList.copyOf(secureStream)) 2111 .containsExactly(path("foo/a"), path("foo/b"), path("foo/c")); 2112 2113 try (DirectoryStream<Path> stream2 = secureStream.newDirectoryStream(path("c"))) { 2114 assertThat(ImmutableList.copyOf(stream2)).containsExactly(path("foo/c/d"), path("foo/c/e")); 2115 } 2116 } 2117 } 2118 2119 @SuppressWarnings("StreamResourceLeak") 2120 @Test testClosedSecureDirectoryStream()2121 public void testClosedSecureDirectoryStream() throws IOException { 2122 Files.createDirectory(path("/foo")); 2123 SecureDirectoryStream<Path> stream = 2124 (SecureDirectoryStream<Path>) Files.newDirectoryStream(path("/foo")); 2125 2126 stream.close(); 2127 2128 try { 2129 stream.iterator(); 2130 fail("expected ClosedDirectoryStreamException"); 2131 } catch (ClosedDirectoryStreamException expected) { 2132 } 2133 2134 try { 2135 stream.deleteDirectory(fs.getPath("a")); 2136 fail("expected ClosedDirectoryStreamException"); 2137 } catch (ClosedDirectoryStreamException expected) { 2138 } 2139 2140 try { 2141 stream.deleteFile(fs.getPath("a")); 2142 fail("expected ClosedDirectoryStreamException"); 2143 } catch (ClosedDirectoryStreamException expected) { 2144 } 2145 2146 try { 2147 stream.newByteChannel(fs.getPath("a"), ImmutableSet.of(CREATE, WRITE)); 2148 fail("expected ClosedDirectoryStreamException"); 2149 } catch (ClosedDirectoryStreamException expected) { 2150 } 2151 2152 try { 2153 stream.newDirectoryStream(fs.getPath("a")); 2154 fail("expected ClosedDirectoryStreamException"); 2155 } catch (ClosedDirectoryStreamException expected) { 2156 } 2157 2158 try { 2159 stream.move(fs.getPath("a"), stream, fs.getPath("b")); 2160 fail("expected ClosedDirectoryStreamException"); 2161 } catch (ClosedDirectoryStreamException expected) { 2162 } 2163 2164 try { 2165 stream.getFileAttributeView(BasicFileAttributeView.class); 2166 fail("expected ClosedDirectoryStreamException"); 2167 } catch (ClosedDirectoryStreamException expected) { 2168 } 2169 2170 try { 2171 stream.getFileAttributeView(fs.getPath("a"), BasicFileAttributeView.class); 2172 fail("expected ClosedDirectoryStreamException"); 2173 } catch (ClosedDirectoryStreamException expected) { 2174 } 2175 } 2176 2177 @SuppressWarnings("StreamResourceLeak") 2178 @Test testClosedSecureDirectoryStreamAttributeViewAndIterator()2179 public void testClosedSecureDirectoryStreamAttributeViewAndIterator() throws IOException { 2180 Files.createDirectory(path("/foo")); 2181 Files.createDirectory(path("/foo/bar")); 2182 SecureDirectoryStream<Path> stream = 2183 (SecureDirectoryStream<Path>) Files.newDirectoryStream(path("/foo")); 2184 2185 Iterator<Path> iter = stream.iterator(); 2186 BasicFileAttributeView view1 = stream.getFileAttributeView(BasicFileAttributeView.class); 2187 BasicFileAttributeView view2 = 2188 stream.getFileAttributeView(path("bar"), BasicFileAttributeView.class); 2189 2190 try { 2191 stream.iterator(); 2192 fail("expected IllegalStateException"); 2193 } catch (IllegalStateException expected) { 2194 } 2195 2196 stream.close(); 2197 2198 try { 2199 iter.next(); 2200 fail("expected ClosedDirectoryStreamException"); 2201 } catch (ClosedDirectoryStreamException expected) { 2202 } 2203 2204 try { 2205 view1.readAttributes(); 2206 fail("expected ClosedDirectoryStreamException"); 2207 } catch (ClosedDirectoryStreamException expected) { 2208 } 2209 2210 try { 2211 view2.readAttributes(); 2212 fail("expected ClosedDirectoryStreamException"); 2213 } catch (ClosedDirectoryStreamException expected) { 2214 } 2215 2216 try { 2217 view1.setTimes(null, null, null); 2218 fail("expected ClosedDirectoryStreamException"); 2219 } catch (ClosedDirectoryStreamException expected) { 2220 } 2221 2222 try { 2223 view2.setTimes(null, null, null); 2224 fail("expected ClosedDirectoryStreamException"); 2225 } catch (ClosedDirectoryStreamException expected) { 2226 } 2227 } 2228 2229 @Test testDirectoryAccessAndModifiedTimeUpdates()2230 public void testDirectoryAccessAndModifiedTimeUpdates() throws IOException { 2231 Files.createDirectories(path("/foo/bar")); 2232 FileTimeTester tester = new FileTimeTester(path("/foo/bar")); 2233 tester.assertAccessTimeDidNotChange(); 2234 tester.assertModifiedTimeDidNotChange(); 2235 2236 // TODO(cgdecker): Use a Clock for file times so I can test this reliably without sleeping 2237 Uninterruptibles.sleepUninterruptibly(1, MILLISECONDS); 2238 Files.createFile(path("/foo/bar/baz.txt")); 2239 2240 tester.assertAccessTimeDidNotChange(); 2241 tester.assertModifiedTimeChanged(); 2242 2243 Uninterruptibles.sleepUninterruptibly(1, MILLISECONDS); 2244 // access time is updated by reading the full contents of the directory 2245 // not just by doing a lookup in it 2246 try (DirectoryStream<Path> stream = Files.newDirectoryStream(path("/foo/bar"))) { 2247 // iterate the stream, forcing the directory to actually be read 2248 Iterators.advance(stream.iterator(), Integer.MAX_VALUE); 2249 } 2250 2251 tester.assertAccessTimeChanged(); 2252 tester.assertModifiedTimeDidNotChange(); 2253 2254 Uninterruptibles.sleepUninterruptibly(1, MILLISECONDS); 2255 Files.move(path("/foo/bar/baz.txt"), path("/foo/bar/baz2.txt")); 2256 2257 tester.assertAccessTimeDidNotChange(); 2258 tester.assertModifiedTimeChanged(); 2259 2260 Uninterruptibles.sleepUninterruptibly(1, MILLISECONDS); 2261 Files.delete(path("/foo/bar/baz2.txt")); 2262 2263 tester.assertAccessTimeDidNotChange(); 2264 tester.assertModifiedTimeChanged(); 2265 } 2266 2267 @Test testRegularFileAccessAndModifiedTimeUpdates()2268 public void testRegularFileAccessAndModifiedTimeUpdates() throws IOException { 2269 Path foo = path("foo"); 2270 Files.createFile(foo); 2271 2272 FileTimeTester tester = new FileTimeTester(foo); 2273 tester.assertAccessTimeDidNotChange(); 2274 tester.assertModifiedTimeDidNotChange(); 2275 2276 Uninterruptibles.sleepUninterruptibly(1, MILLISECONDS); 2277 try (FileChannel channel = FileChannel.open(foo, READ)) { 2278 // opening READ channel does not change times 2279 tester.assertAccessTimeDidNotChange(); 2280 tester.assertModifiedTimeDidNotChange(); 2281 2282 Uninterruptibles.sleepUninterruptibly(1, MILLISECONDS); 2283 channel.read(ByteBuffer.allocate(100)); 2284 2285 // read call on channel does 2286 tester.assertAccessTimeChanged(); 2287 tester.assertModifiedTimeDidNotChange(); 2288 2289 Uninterruptibles.sleepUninterruptibly(1, MILLISECONDS); 2290 channel.read(ByteBuffer.allocate(100)); 2291 2292 tester.assertAccessTimeChanged(); 2293 tester.assertModifiedTimeDidNotChange(); 2294 2295 Uninterruptibles.sleepUninterruptibly(1, MILLISECONDS); 2296 try { 2297 channel.write(ByteBuffer.wrap(new byte[] {0, 1, 2, 3})); 2298 } catch (NonWritableChannelException ignore) { 2299 } 2300 2301 // failed write on non-readable channel does not change times 2302 tester.assertAccessTimeDidNotChange(); 2303 tester.assertModifiedTimeDidNotChange(); 2304 2305 Uninterruptibles.sleepUninterruptibly(1, MILLISECONDS); 2306 } 2307 2308 // closing channel does not change times 2309 tester.assertAccessTimeDidNotChange(); 2310 tester.assertModifiedTimeDidNotChange(); 2311 2312 Uninterruptibles.sleepUninterruptibly(1, MILLISECONDS); 2313 try (FileChannel channel = FileChannel.open(foo, WRITE)) { 2314 // opening WRITE channel does not change times 2315 tester.assertAccessTimeDidNotChange(); 2316 tester.assertModifiedTimeDidNotChange(); 2317 2318 Uninterruptibles.sleepUninterruptibly(1, MILLISECONDS); 2319 channel.write(ByteBuffer.wrap(new byte[] {0, 1, 2, 3})); 2320 2321 // write call on channel does 2322 tester.assertAccessTimeDidNotChange(); 2323 tester.assertModifiedTimeChanged(); 2324 2325 Uninterruptibles.sleepUninterruptibly(1, MILLISECONDS); 2326 channel.write(ByteBuffer.wrap(new byte[] {4, 5, 6, 7})); 2327 2328 tester.assertAccessTimeDidNotChange(); 2329 tester.assertModifiedTimeChanged(); 2330 2331 Uninterruptibles.sleepUninterruptibly(1, MILLISECONDS); 2332 try { 2333 channel.read(ByteBuffer.allocate(100)); 2334 } catch (NonReadableChannelException ignore) { 2335 } 2336 2337 // failed read on non-readable channel does not change times 2338 tester.assertAccessTimeDidNotChange(); 2339 tester.assertModifiedTimeDidNotChange(); 2340 2341 Uninterruptibles.sleepUninterruptibly(1, MILLISECONDS); 2342 } 2343 2344 // closing channel does not change times 2345 tester.assertAccessTimeDidNotChange(); 2346 tester.assertModifiedTimeDidNotChange(); 2347 } 2348 2349 @Test testUnsupportedFeatures()2350 public void testUnsupportedFeatures() throws IOException { 2351 FileSystem fileSystem = 2352 Jimfs.newFileSystem( 2353 Configuration.unix().toBuilder() 2354 .setSupportedFeatures() // none 2355 .build()); 2356 2357 Path foo = fileSystem.getPath("foo"); 2358 Path bar = foo.resolveSibling("bar"); 2359 2360 try { 2361 Files.createLink(foo, bar); 2362 fail(); 2363 } catch (UnsupportedOperationException expected) { 2364 } 2365 2366 try { 2367 Files.createSymbolicLink(foo, bar); 2368 fail(); 2369 } catch (UnsupportedOperationException expected) { 2370 } 2371 2372 try { 2373 Files.readSymbolicLink(foo); 2374 fail(); 2375 } catch (UnsupportedOperationException expected) { 2376 } 2377 2378 try { 2379 FileChannel.open(foo); 2380 fail(); 2381 } catch (UnsupportedOperationException expected) { 2382 } 2383 2384 try { 2385 AsynchronousFileChannel.open(foo); 2386 fail(); 2387 } catch (UnsupportedOperationException expected) { 2388 } 2389 2390 Files.createDirectory(foo); 2391 Files.createFile(bar); 2392 2393 try (DirectoryStream<Path> stream = Files.newDirectoryStream(foo)) { 2394 assertThat(stream).isNotInstanceOf(SecureDirectoryStream.class); 2395 } 2396 2397 try (SeekableByteChannel channel = Files.newByteChannel(bar)) { 2398 assertThat(channel).isNotInstanceOf(FileChannel.class); 2399 } 2400 } 2401 } 2402