/test/java/io/File/SymLinks.java
Java | 374 lines | 257 code | 59 blank | 58 comment | 42 complexity | 2b5a0da3ab6c24c5c88e0e8c835cae7c MD5 | raw file
- /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
- /* @test
- * @bug 6595866
- * @summary Test java.io.File operations with sym links
- */
- import java.io.*;
- import java.nio.file.*;
- import java.nio.file.attribute.*;
- import static java.nio.file.LinkOption.*;
- public class SymLinks {
- final static PrintStream out = System.out;
- final static File top = new File(System.getProperty("test.dir", "."));
- // files used by the test
- final static File file = new File(top, "foofile");
- final static File link2file = new File(top, "link2file");
- final static File link2link2file = new File(top, "link2link2file");
- final static File dir = new File(top, "foodir");
- final static File link2dir = new File(top, "link2dir");
- final static File link2link2dir = new File(top, "link2link2dir");
- final static File link2nobody = new File(top, "link2nobody");
- final static File link2link2nobody = new File(top, "link2link2nobody");
- /**
- * Setup files, directories, and sym links used by test.
- */
- static void setup() throws IOException {
- // link2link2file -> link2file -> foofile
- FileOutputStream fos = new FileOutputStream(file);
- try {
- fos.write(new byte[16*1024]);
- } finally {
- fos.close();
- }
- mklink(link2file, file);
- mklink(link2link2file, link2file);
- // link2link2dir -> link2dir -> dir
- assertTrue(dir.mkdir());
- mklink(link2dir, dir);
- mklink(link2link2dir, link2dir);
- // link2link2nobody -> link2nobody -> <does-not-exist>
- mklink(link2nobody, new File(top, "DoesNotExist"));
- mklink(link2link2nobody, link2nobody);
- }
- /**
- * Remove files, directories, and sym links used by test.
- */
- static void cleanup() throws IOException {
- if (file != null)
- file.delete();
- if (link2file != null)
- Files.deleteIfExists(link2file.toPath());
- if (link2link2file != null)
- Files.deleteIfExists(link2link2file.toPath());
- if (dir != null)
- dir.delete();
- if (link2dir != null)
- Files.deleteIfExists(link2dir.toPath());
- if (link2link2dir != null)
- Files.deleteIfExists(link2link2dir.toPath());
- if (link2nobody != null)
- Files.deleteIfExists(link2nobody.toPath());
- if (link2link2nobody != null)
- Files.deleteIfExists(link2link2nobody.toPath());
- }
- /**
- * Creates a sym link source->target
- */
- static void mklink(File source, File target) throws IOException {
- Files.createSymbolicLink(source.toPath(), target.toPath());
- }
- /**
- * Returns true if the "link" exists and is a sym link.
- */
- static boolean isSymLink(File link) {
- return Files.isSymbolicLink(link.toPath());
- }
- /**
- * Returns the last modified time of a sym link.
- */
- static long lastModifiedOfSymLink(File link) throws IOException {
- BasicFileAttributes attrs =
- Files.readAttributes(link.toPath(), BasicFileAttributes.class, NOFOLLOW_LINKS);
- assertTrue(attrs.isSymbolicLink());
- return attrs.lastModifiedTime().toMillis();
- }
- /**
- * Returns true if sym links are supported on the file system where
- * "dir" exists.
- */
- static boolean supportsSymLinks(File dir) {
- Path link = dir.toPath().resolve("link");
- Path target = dir.toPath().resolve("target");
- try {
- Files.createSymbolicLink(link, target);
- Files.delete(link);
- return true;
- } catch (UnsupportedOperationException x) {
- return false;
- } catch (IOException x) {
- return false;
- }
- }
- static void assertTrue(boolean v) {
- if (!v) throw new RuntimeException("Test failed");
- }
- static void assertFalse(boolean v) {
- assertTrue(!v);
- }
- static void header(String h) {
- out.println();
- out.println();
- out.println("-- " + h + " --");
- }
- /**
- * Tests go here.
- */
- static void go() throws IOException {
- // check setup
- assertTrue(file.isFile());
- assertTrue(isSymLink(link2file));
- assertTrue(isSymLink(link2link2file));
- assertTrue(dir.isDirectory());
- assertTrue(isSymLink(link2dir));
- assertTrue(isSymLink(link2link2dir));
- assertTrue(isSymLink(link2nobody));
- assertTrue(isSymLink(link2link2nobody));
- header("createNewFile");
- assertFalse(file.createNewFile());
- assertFalse(link2file.createNewFile());
- assertFalse(link2link2file.createNewFile());
- assertFalse(dir.createNewFile());
- assertFalse(link2dir.createNewFile());
- assertFalse(link2link2dir.createNewFile());
- assertFalse(link2nobody.createNewFile());
- assertFalse(link2link2nobody.createNewFile());
- header("mkdir");
- assertFalse(file.mkdir());
- assertFalse(link2file.mkdir());
- assertFalse(link2link2file.mkdir());
- assertFalse(dir.mkdir());
- assertFalse(link2dir.mkdir());
- assertFalse(link2link2dir.mkdir());
- assertFalse(link2nobody.mkdir());
- assertFalse(link2link2nobody.mkdir());
- header("delete");
- File link = new File(top, "mylink");
- try {
- mklink(link, file);
- assertTrue(link.delete());
- assertTrue(!isSymLink(link));
- assertTrue(file.exists());
- mklink(link, link2file);
- assertTrue(link.delete());
- assertTrue(!isSymLink(link));
- assertTrue(link2file.exists());
- mklink(link, dir);
- assertTrue(link.delete());
- assertTrue(!isSymLink(link));
- assertTrue(dir.exists());
- mklink(link, link2dir);
- assertTrue(link.delete());
- assertTrue(!isSymLink(link));
- assertTrue(link2dir.exists());
- mklink(link, link2nobody);
- assertTrue(link.delete());
- assertTrue(!isSymLink(link));
- assertTrue(isSymLink(link2nobody));
- } finally {
- Files.deleteIfExists(link.toPath());
- }
- header("renameTo");
- File newlink = new File(top, "newlink");
- assertTrue(link2file.renameTo(newlink));
- try {
- assertTrue(file.exists());
- assertTrue(isSymLink(newlink));
- assertTrue(!isSymLink(link2file));
- } finally {
- newlink.renameTo(link2file); // restore link
- }
- assertTrue(link2dir.renameTo(newlink));
- try {
- assertTrue(dir.exists());
- assertTrue(isSymLink(newlink));
- assertTrue(!isSymLink(link2dir));
- } finally {
- newlink.renameTo(link2dir); // restore link
- }
- header("list");
- final String name = "entry";
- File entry = new File(dir, name);
- try {
- assertTrue(dir.list().length == 0); // directory should be empty
- assertTrue(link2dir.list().length == 0);
- assertTrue(link2link2dir.list().length == 0);
- assertTrue(entry.createNewFile());
- assertTrue(dir.list().length == 1);
- assertTrue(dir.list()[0].equals(name));
- // access directory by following links
- assertTrue(link2dir.list().length == 1);
- assertTrue(link2dir.list()[0].equals(name));
- assertTrue(link2link2dir.list().length == 1);
- assertTrue(link2link2dir.list()[0].equals(name));
- // files that are not directories
- assertTrue(link2file.list() == null);
- assertTrue(link2nobody.list() == null);
- } finally {
- entry.delete();
- }
- header("isXXX");
- assertTrue(file.isFile());
- assertTrue(link2file.isFile());
- assertTrue(link2link2file.isFile());
- assertTrue(dir.isDirectory());
- assertTrue(link2dir.isDirectory());
- assertTrue(link2link2dir.isDirectory());
- // on Windows we test with the DOS hidden attribute set
- if (System.getProperty("os.name").startsWith("Windows")) {
- DosFileAttributeView view = Files
- .getFileAttributeView(file.toPath(), DosFileAttributeView.class);
- view.setHidden(true);
- try {
- assertTrue(file.isHidden());
- assertTrue(link2file.isHidden());
- assertTrue(link2link2file.isHidden());
- } finally {
- view.setHidden(false);
- }
- assertFalse(file.isHidden());
- assertFalse(link2file.isHidden());
- assertFalse(link2link2file.isHidden());
- }
- header("length");
- long len = file.length();
- assertTrue(len > 0L);
- // these tests should follow links
- assertTrue(link2file.length() == len);
- assertTrue(link2link2file.length() == len);
- assertTrue(link2nobody.length() == 0L);
- header("lastModified / setLastModified");
- // need time to diff between link and file
- long origLastModified = file.lastModified();
- assertTrue(origLastModified != 0L);
- try { Thread.sleep(2000); } catch (InterruptedException x) { }
- file.setLastModified(System.currentTimeMillis());
- long lastModified = file.lastModified();
- assertTrue(lastModified != origLastModified);
- assertTrue(lastModifiedOfSymLink(link2file) != lastModified);
- assertTrue(lastModifiedOfSymLink(link2link2file) != lastModified);
- assertTrue(link2file.lastModified() == lastModified);
- assertTrue(link2link2file.lastModified() == lastModified);
- assertTrue(link2nobody.lastModified() == 0L);
- origLastModified = dir.lastModified();
- assertTrue(origLastModified != 0L);
- dir.setLastModified(0L);
- assertTrue(dir.lastModified() == 0L);
- assertTrue(link2dir.lastModified() == 0L);
- assertTrue(link2link2dir.lastModified() == 0L);
- dir.setLastModified(origLastModified);
- header("setXXX / canXXX");
- assertTrue(file.canRead());
- assertTrue(file.canWrite());
- assertTrue(link2file.canRead());
- assertTrue(link2file.canWrite());
- assertTrue(link2link2file.canRead());
- assertTrue(link2link2file.canWrite());
- if (file.setReadOnly()) {
- assertFalse(file.canWrite());
- assertFalse(link2file.canWrite());
- assertFalse(link2link2file.canWrite());
- assertTrue(file.setWritable(true)); // make writable
- assertTrue(file.canWrite());
- assertTrue(link2file.canWrite());
- assertTrue(link2link2file.canWrite());
- assertTrue(link2file.setReadOnly()); // make read only
- assertFalse(file.canWrite());
- assertFalse(link2file.canWrite());
- assertFalse(link2link2file.canWrite());
- assertTrue(link2link2file.setWritable(true)); // make writable
- assertTrue(file.canWrite());
- assertTrue(link2file.canWrite());
- assertTrue(link2link2file.canWrite());
- }
- }
- public static void main(String[] args) throws IOException {
- if (supportsSymLinks(top)) {
- try {
- setup();
- go();
- } finally {
- cleanup();
- }
- }
- }
- }