Path: blob/master/test/jdk/java/io/File/SymLinks.java
41149 views
/*1* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* @test24* @bug 659586625* @summary Test java.io.File operations with sym links26* @build SymLinks Util27* @run main SymLinks28*/2930import java.io.*;31import java.nio.file.*;32import java.nio.file.attribute.*;33import static java.nio.file.LinkOption.*;3435public class SymLinks {36static final PrintStream out = System.out;3738static final File top = new File(System.getProperty("test.dir", "."));3940// files used by the test4142static final File file = new File(top, "foofile");43static final File link2file = new File(top, "link2file");44static final File link2link2file = new File(top, "link2link2file");4546static final File dir = new File(top, "foodir");47static final File link2dir = new File(top, "link2dir");48static final File link2link2dir = new File(top, "link2link2dir");4950static final File link2nobody = new File(top, "link2nobody");51static final File link2link2nobody = new File(top, "link2link2nobody");5253/**54* Setup files, directories, and sym links used by test.55*/56static void setup() throws IOException {57// link2link2file -> link2file -> foofile58FileOutputStream fos = new FileOutputStream(file);59try {60fos.write(new byte[16*1024]);61} finally {62fos.close();63}64mklink(link2file, file);65mklink(link2link2file, link2file);6667// link2link2dir -> link2dir -> dir68assertTrue(dir.mkdir());69mklink(link2dir, dir);70mklink(link2link2dir, link2dir);7172// link2link2nobody -> link2nobody -> <does-not-exist>73mklink(link2nobody, new File(top, "DoesNotExist"));74mklink(link2link2nobody, link2nobody);75}7677/**78* Remove files, directories, and sym links used by test.79*/80static void cleanup() throws IOException {81if (file != null)82file.delete();83if (link2file != null)84Files.deleteIfExists(link2file.toPath());85if (link2link2file != null)86Files.deleteIfExists(link2link2file.toPath());87if (dir != null)88dir.delete();89if (link2dir != null)90Files.deleteIfExists(link2dir.toPath());91if (link2link2dir != null)92Files.deleteIfExists(link2link2dir.toPath());93if (link2nobody != null)94Files.deleteIfExists(link2nobody.toPath());95if (link2link2nobody != null)96Files.deleteIfExists(link2link2nobody.toPath());97}9899/**100* Creates a sym link source->target101*/102static void mklink(File source, File target) throws IOException {103Files.createSymbolicLink(source.toPath(), target.toPath());104}105106/**107* Returns true if the "link" exists and is a sym link.108*/109static boolean isSymLink(File link) {110return Files.isSymbolicLink(link.toPath());111}112113/**114* Returns the last modified time of a sym link.115*/116static long lastModifiedOfSymLink(File link) throws IOException {117BasicFileAttributes attrs =118Files.readAttributes(link.toPath(), BasicFileAttributes.class, NOFOLLOW_LINKS);119assertTrue(attrs.isSymbolicLink());120return attrs.lastModifiedTime().toMillis();121}122123/**124* Returns true if sym links are supported on the file system where125* "dir" exists.126*/127static boolean supportsSymLinks(File dir) {128Path link = dir.toPath().resolve("link");129Path target = dir.toPath().resolve("target");130try {131Files.createSymbolicLink(link, target);132Files.delete(link);133return true;134} catch (UnsupportedOperationException x) {135return false;136} catch (IOException x) {137return false;138}139}140141static void assertTrue(boolean v) {142if (!v) throw new RuntimeException("Test failed");143}144145static void assertFalse(boolean v) {146assertTrue(!v);147}148149static void header(String h) {150out.println();151out.println();152out.println("-- " + h + " --");153}154155/**156* Tests go here.157*/158static void go() throws IOException {159160// check setup161assertTrue(file.isFile());162assertTrue(isSymLink(link2file));163assertTrue(isSymLink(link2link2file));164assertTrue(dir.isDirectory());165assertTrue(isSymLink(link2dir));166assertTrue(isSymLink(link2link2dir));167assertTrue(isSymLink(link2nobody));168assertTrue(isSymLink(link2link2nobody));169170header("createNewFile");171172assertFalse(file.createNewFile());173assertFalse(link2file.createNewFile());174assertFalse(link2link2file.createNewFile());175assertFalse(dir.createNewFile());176assertFalse(link2dir.createNewFile());177assertFalse(link2link2dir.createNewFile());178assertFalse(link2nobody.createNewFile());179assertFalse(link2link2nobody.createNewFile());180181header("mkdir");182183assertFalse(file.mkdir());184assertFalse(link2file.mkdir());185assertFalse(link2link2file.mkdir());186assertFalse(dir.mkdir());187assertFalse(link2dir.mkdir());188assertFalse(link2link2dir.mkdir());189assertFalse(link2nobody.mkdir());190assertFalse(link2link2nobody.mkdir());191192header("delete");193194File link = new File(top, "mylink");195try {196mklink(link, file);197assertTrue(link.delete());198assertTrue(!isSymLink(link));199assertTrue(file.exists());200201mklink(link, link2file);202assertTrue(link.delete());203assertTrue(!isSymLink(link));204assertTrue(link2file.exists());205206mklink(link, dir);207assertTrue(link.delete());208assertTrue(!isSymLink(link));209assertTrue(dir.exists());210211mklink(link, link2dir);212assertTrue(link.delete());213assertTrue(!isSymLink(link));214assertTrue(link2dir.exists());215216mklink(link, link2nobody);217assertTrue(link.delete());218assertTrue(!isSymLink(link));219assertTrue(isSymLink(link2nobody));220221} finally {222Files.deleteIfExists(link.toPath());223}224225header("renameTo");226227File newlink = new File(top, "newlink");228assertTrue(link2file.renameTo(newlink));229try {230assertTrue(file.exists());231assertTrue(isSymLink(newlink));232assertTrue(!isSymLink(link2file));233} finally {234newlink.renameTo(link2file); // restore link235}236237assertTrue(link2dir.renameTo(newlink));238try {239assertTrue(dir.exists());240assertTrue(isSymLink(newlink));241assertTrue(!isSymLink(link2dir));242} finally {243newlink.renameTo(link2dir); // restore link244}245246header("list");247248final String name = "entry";249File entry = new File(dir, name);250try {251assertTrue(dir.list().length == 0); // directory should be empty252assertTrue(link2dir.list().length == 0);253assertTrue(link2link2dir.list().length == 0);254255assertTrue(entry.createNewFile());256assertTrue(dir.list().length == 1);257assertTrue(dir.list()[0].equals(name));258259// access directory by following links260assertTrue(link2dir.list().length == 1);261assertTrue(link2dir.list()[0].equals(name));262assertTrue(link2link2dir.list().length == 1);263assertTrue(link2link2dir.list()[0].equals(name));264265// files that are not directories266assertTrue(link2file.list() == null);267assertTrue(link2nobody.list() == null);268269} finally {270entry.delete();271}272273header("isXXX");274275assertTrue(file.isFile());276assertTrue(link2file.isFile());277assertTrue(link2link2file.isFile());278279assertTrue(dir.isDirectory());280assertTrue(link2dir.isDirectory());281assertTrue(link2link2dir.isDirectory());282283// on Windows we test with the DOS hidden attribute set284if (System.getProperty("os.name").startsWith("Windows")) {285DosFileAttributeView view = Files286.getFileAttributeView(file.toPath(), DosFileAttributeView.class);287view.setHidden(true);288try {289assertTrue(file.isHidden());290assertTrue(link2file.isHidden());291assertTrue(link2link2file.isHidden());292} finally {293view.setHidden(false);294}295assertFalse(file.isHidden());296assertFalse(link2file.isHidden());297assertFalse(link2link2file.isHidden());298}299300header("length");301302long len = file.length();303assertTrue(len > 0L);304// these tests should follow links305assertTrue(link2file.length() == len);306assertTrue(link2link2file.length() == len);307assertTrue(link2nobody.length() == 0L);308309header("lastModified / setLastModified");310311// need time to diff between link and file312long origLastModified = file.lastModified();313assertTrue(origLastModified != 0L);314try { Thread.sleep(2000); } catch (InterruptedException x) { }315file.setLastModified(System.currentTimeMillis());316317long lastModified = file.lastModified();318assertTrue(lastModified != origLastModified);319assertTrue(lastModifiedOfSymLink(link2file) != lastModified);320assertTrue(lastModifiedOfSymLink(link2link2file) != lastModified);321assertTrue(link2file.lastModified() == lastModified);322assertTrue(link2link2file.lastModified() == lastModified);323assertTrue(link2nobody.lastModified() == 0L);324325origLastModified = dir.lastModified();326assertTrue(origLastModified != 0L);327dir.setLastModified(0L);328assertTrue(dir.lastModified() == 0L);329assertTrue(link2dir.lastModified() == 0L);330assertTrue(link2link2dir.lastModified() == 0L);331dir.setLastModified(origLastModified);332333header("setXXX / canXXX");334335assertTrue(file.canRead());336assertTrue(file.canWrite());337assertTrue(link2file.canRead());338assertTrue(link2file.canWrite());339assertTrue(link2link2file.canRead());340assertTrue(link2link2file.canWrite());341342if (!Util.isPrivileged() && file.setReadOnly()) {343assertFalse(file.canWrite());344assertFalse(link2file.canWrite());345assertFalse(link2link2file.canWrite());346347assertTrue(file.setWritable(true)); // make writable348assertTrue(file.canWrite());349assertTrue(link2file.canWrite());350assertTrue(link2link2file.canWrite());351352assertTrue(link2file.setReadOnly()); // make read only353assertFalse(file.canWrite());354assertFalse(link2file.canWrite());355assertFalse(link2link2file.canWrite());356357assertTrue(link2link2file.setWritable(true)); // make writable358assertTrue(file.canWrite());359assertTrue(link2file.canWrite());360assertTrue(link2link2file.canWrite());361}362}363364public static void main(String[] args) throws IOException {365if (supportsSymLinks(top)) {366try {367setup();368go();369} finally {370cleanup();371}372}373}374375}376377378