1 /*
   2  * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /* @test
  25  * @bug 4313887 6838333 6863864
  26  * @summary Unit test for java.nio.file.Path createSymbolicLink,
  27  *     readSymbolicLink, and createLink methods
  28  * @library ..
  29  * @build Links
  30  * @run main/othervm Links
  31  */
  32 
  33 import java.nio.file.*;
  34 import java.nio.file.attribute.*;
  35 import java.io.*;
  36 
  37 public class Links {
  38 
  39     static final boolean isWindows =
  40         System.getProperty("os.name").startsWith("Windows");
  41 
  42     static void assertTrue(boolean okay) {
  43         if (!okay)
  44             throw new RuntimeException("Assertion failed");
  45     }
  46 
  47     /**
  48      * Exercise createSymbolicLink and readLink methods
  49      */
  50     static void testSymLinks(Path dir) throws IOException {
  51         final Path link = dir.resolve("link");
  52 
  53         // Check if sym links are supported
  54         try {
  55             link.createSymbolicLink(Paths.get("foo"));
  56             link.delete();
  57         } catch (UnsupportedOperationException x) {
  58             // sym links not supported
  59             return;
  60         } catch (IOException x) {
  61             // probably insufficient privileges to create sym links (Windows)
  62             return;
  63         }
  64 
  65         // Test links to various targets
  66         String[] windowsTargets =
  67             { "foo", "C:\\foo", "\\foo", "\\\\server\\share\\foo" };
  68         String[] otherTargets = { "relative", "/absolute" };
  69 
  70         String[] targets = (isWindows) ? windowsTargets : otherTargets;
  71         for (String s: targets) {
  72             Path target = Paths.get(s);
  73             link.createSymbolicLink(target);
  74             try {
  75                 assertTrue(link.readSymbolicLink().equals(target));
  76             } finally {
  77                 link.delete();
  78             }
  79         }
  80 
  81         // Test links to directory
  82         Path mydir = dir.resolve("mydir");
  83         Path myfile = mydir.resolve("myfile");
  84         try {
  85             mydir.createDirectory();
  86             myfile.createFile();
  87 
  88             // link -> "mydir"
  89             link.createSymbolicLink(mydir.getName());
  90             assertTrue(link.readSymbolicLink().equals(mydir.getName()));
  91 
  92             // Test access to directory via link
  93             DirectoryStream<Path> stream = link.newDirectoryStream();
  94             try {
  95                 boolean found = false;
  96                 for (Path entry: stream) {
  97                     if (entry.getName().equals(myfile.getName())) {
  98                         found = true;
  99                         break;
 100                     }
 101                 }
 102                 assertTrue(found);
 103             } finally {
 104                 stream.close();
 105             }
 106 
 107             // Test link2 -> link -> mydir
 108             final Path link2 = dir.resolve("link2");
 109             Path target2 = link.getName();
 110             link2.createSymbolicLink(target2);
 111             try {
 112                 assertTrue(link2.readSymbolicLink().equals(target2));
 113                 link2.newDirectoryStream().close();
 114             } finally {
 115                 link2.delete();
 116             }
 117 
 118             // Remove mydir and re-create link2 before re-creating mydir
 119             // (This is a useful test on Windows to ensure that creating a
 120             // sym link to a directory sym link creates the right type of link).
 121             myfile.delete();
 122             mydir.delete();
 123             link2.createSymbolicLink(target2);
 124             try {
 125                 assertTrue(link2.readSymbolicLink().equals(target2));
 126                 mydir.createDirectory();
 127                 link2.newDirectoryStream().close();
 128             } finally {
 129                 link2.delete();
 130             }
 131 
 132         } finally {
 133             myfile.deleteIfExists();
 134             mydir.deleteIfExists();
 135             link.deleteIfExists();
 136         }
 137     }
 138 
 139     /**
 140      * Exercise createLink method
 141      */
 142     static void testHardLinks(Path dir) throws IOException {
 143         Path foo = dir.resolve("foo").createFile();
 144         try {
 145             Path bar;
 146             try {
 147                 bar = dir.resolve("bar").createLink(foo);
 148             } catch (UnsupportedOperationException x) {
 149                 return;
 150             } catch (IOException x) {
 151                 // probably insufficient privileges (Windows)
 152                 return;
 153             }
 154             try {
 155                 Object key1 = Attributes
 156                     .readBasicFileAttributes(foo).fileKey();
 157                 Object key2 = Attributes
 158                     .readBasicFileAttributes(bar).fileKey();
 159                 assertTrue((key1 == null) || (key1.equals(key2)));
 160             } finally {
 161                 bar.delete();
 162             }
 163 
 164 
 165         } finally {
 166             foo.delete();
 167         }
 168     }
 169 
 170     public static void main(String[] args) throws IOException {
 171         Path dir = TestUtil.createTemporaryDirectory();
 172         try {
 173             testSymLinks(dir);
 174             testHardLinks(dir);
 175 
 176             // repeat tests on Windows with long path
 177             if (isWindows) {
 178                 Path dirWithLongPath = null;
 179                 try {
 180                     dirWithLongPath = TestUtil.createDirectoryWithLongPath(dir);
 181                 } catch (IOException x) {
 182                     System.out.println("Unable to create long path: " + x);
 183                 }
 184                 if (dirWithLongPath != null) {
 185                     System.out.println("");
 186                     System.out.println("** REPEAT TESTS WITH LONG PATH **");
 187                     testSymLinks(dirWithLongPath);
 188                     testHardLinks(dirWithLongPath);
 189                 }
 190             }
 191         } finally {
 192             TestUtil.removeAll(dir);
 193         }
 194     }
 195 }