1 /*
   2  * Copyright (c) 2008, 2013, 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 8005566 8032220
  26  * @summary Unit test for miscellenous methods in java.nio.file.Files
  27  * @library ..
  28  */
  29 
  30 import java.nio.file.*;
  31 import static java.nio.file.Files.*;
  32 import static java.nio.file.LinkOption.*;
  33 import java.nio.file.attribute.*;
  34 import java.io.IOException;
  35 import java.util.*;
  36 
  37 public class Misc {
  38 
  39     public static void main(String[] args) throws IOException {
  40         Path dir = TestUtil.createTemporaryDirectory();
  41         try {
  42             testCreateDirectories(dir);
  43             testIsHidden(dir);
  44             testIsSameFile(dir);
  45             testFileTypeMethods(dir);
  46             testAccessMethods(dir);
  47         } finally {
  48              TestUtil.removeAll(dir);
  49         }
  50     }
  51 
  52     /**
  53      * Tests createDirectories
  54      */
  55     static void testCreateDirectories(Path tmpdir) throws IOException {
  56         // a no-op
  57         createDirectories(tmpdir);
  58 
  59         // create one directory
  60         Path subdir = tmpdir.resolve("a");
  61         createDirectories(subdir);
  62         assertTrue(exists(subdir));
  63 
  64         // create parents
  65         subdir = subdir.resolve("b/c/d");
  66         createDirectories(subdir);
  67         assertTrue(exists(subdir));
  68 
  69         // existing file is not a directory
  70         Path file = createFile(tmpdir.resolve("x"));
  71         try {
  72             createDirectories(file);
  73             throw new RuntimeException("failure expected");
  74         } catch (FileAlreadyExistsException x) { }
  75         try {
  76             createDirectories(file.resolve("y"));
  77             throw new RuntimeException("failure expected");
  78         } catch (IOException x) { }
  79 
  80         // the root directory always exists
  81         Path root = Paths.get("/");
  82         Files.createDirectories(root);
  83         Files.createDirectories(root.toAbsolutePath());
  84     }
  85 
  86     /**
  87      * Tests isHidden
  88      */
  89     static void testIsHidden(Path tmpdir) throws IOException {
  90         assertTrue(!isHidden(tmpdir));
  91 
  92         Path file = tmpdir.resolve(".foo");
  93         if (System.getProperty("os.name").startsWith("Windows")) {
  94             createFile(file);
  95             try {
  96                 setAttribute(file, "dos:hidden", true);
  97                 try {
  98                     assertTrue(isHidden(file));
  99                 } finally {
 100                     setAttribute(file, "dos:hidden", false);
 101                 }
 102             } finally {
 103                 delete(file);
 104             }
 105         } else {
 106             assertTrue(isHidden(file));
 107         }
 108     }
 109 
 110     /**
 111      * Tests isSameFile
 112      */
 113     static void testIsSameFile(Path tmpdir) throws IOException {
 114         Path thisFile = tmpdir.resolve("thisFile");
 115         Path thatFile = tmpdir.resolve("thatFile");
 116 
 117         /**
 118          * Test: isSameFile for self
 119          */
 120         assertTrue(isSameFile(thisFile, thisFile));
 121 
 122         /**
 123          * Test: Neither files exist
 124          */
 125         try {
 126             isSameFile(thisFile, thatFile);
 127             throw new RuntimeException("IOException not thrown");
 128         } catch (IOException x) {
 129         }
 130         try {
 131             isSameFile(thatFile, thisFile);
 132             throw new RuntimeException("IOException not thrown");
 133         } catch (IOException x) {
 134         }
 135 
 136         createFile(thisFile);
 137         try {
 138             /**
 139              * Test: One file exists
 140              */
 141             try {
 142                 isSameFile(thisFile, thatFile);
 143                 throw new RuntimeException("IOException not thrown");
 144             } catch (IOException x) {
 145             }
 146             try {
 147                 isSameFile(thatFile, thisFile);
 148                 throw new RuntimeException("IOException not thrown");
 149             } catch (IOException x) {
 150             }
 151 
 152             /**
 153              * Test: Both file exists
 154              */
 155             createFile(thatFile);
 156             try {
 157                 assertTrue(!isSameFile(thisFile, thatFile));
 158                 assertTrue(!isSameFile(thatFile, thisFile));
 159             } finally {
 160                 delete(thatFile);
 161             }
 162 
 163             /**
 164              * Test: Symbolic links
 165              */
 166             if (TestUtil.supportsLinks(tmpdir)) {
 167                 createSymbolicLink(thatFile, thisFile);
 168                 try {
 169                     assertTrue(isSameFile(thisFile, thatFile));
 170                     assertTrue(isSameFile(thatFile, thisFile));
 171                 } finally {
 172                     TestUtil.deleteUnchecked(thatFile);
 173                 }
 174             }
 175         } finally {
 176             delete(thisFile);
 177         }
 178 
 179         // nulls
 180         try {
 181             isSameFile(thisFile, null);
 182             throw new RuntimeException("NullPointerException expected");
 183         } catch (NullPointerException ignore) { }
 184         try {
 185             isSameFile(null, thatFile);
 186             throw new RuntimeException("NullPointerException expected");
 187         } catch (NullPointerException ignore) { }
 188     }
 189 
 190     /**
 191      * Exercise isRegularFile, isDirectory, isSymbolicLink
 192      */
 193     static void testFileTypeMethods(Path tmpdir) throws IOException {
 194         assertTrue(!isRegularFile(tmpdir));
 195         assertTrue(!isRegularFile(tmpdir, NOFOLLOW_LINKS));
 196         assertTrue(isDirectory(tmpdir));
 197         assertTrue(isDirectory(tmpdir, NOFOLLOW_LINKS));
 198         assertTrue(!isSymbolicLink(tmpdir));
 199 
 200         Path file = createFile(tmpdir.resolve("foo"));
 201         try {
 202             assertTrue(isRegularFile(file));
 203             assertTrue(isRegularFile(file, NOFOLLOW_LINKS));
 204             assertTrue(!isDirectory(file));
 205             assertTrue(!isDirectory(file, NOFOLLOW_LINKS));
 206             assertTrue(!isSymbolicLink(file));
 207 
 208             if (TestUtil.supportsLinks(tmpdir)) {
 209                 Path link = tmpdir.resolve("link");
 210 
 211                 createSymbolicLink(link, tmpdir);
 212                 try {
 213                     assertTrue(!isRegularFile(link));
 214                     assertTrue(!isRegularFile(link, NOFOLLOW_LINKS));
 215                     assertTrue(isDirectory(link));
 216                     assertTrue(!isDirectory(link, NOFOLLOW_LINKS));
 217                     assertTrue(isSymbolicLink(link));
 218                 } finally {
 219                     delete(link);
 220                 }
 221 
 222                 createSymbolicLink(link, file);
 223                 try {
 224                     assertTrue(isRegularFile(link));
 225                     assertTrue(!isRegularFile(link, NOFOLLOW_LINKS));
 226                     assertTrue(!isDirectory(link));
 227                     assertTrue(!isDirectory(link, NOFOLLOW_LINKS));
 228                     assertTrue(isSymbolicLink(link));
 229                 } finally {
 230                     delete(link);
 231                 }
 232 
 233                 createLink(link, file);
 234                 try {
 235                     assertTrue(isRegularFile(link));
 236                     assertTrue(isRegularFile(link, NOFOLLOW_LINKS));
 237                     assertTrue(!isDirectory(link));
 238                     assertTrue(!isDirectory(link, NOFOLLOW_LINKS));
 239                     assertTrue(!isSymbolicLink(link));
 240                 } finally {
 241                     delete(link);
 242                 }
 243             }
 244 
 245         } finally {
 246             delete(file);
 247         }
 248     }
 249 
 250     /**
 251      * Exercise isReadbale, isWritable, isExecutable, exists, notExists
 252      */
 253     static void testAccessMethods(Path tmpdir) throws IOException {
 254         // should return false when file does not exist
 255         Path doesNotExist = tmpdir.resolve("doesNotExist");
 256         assertTrue(!isReadable(doesNotExist));
 257         assertTrue(!isWritable(doesNotExist));
 258         assertTrue(!isExecutable(doesNotExist));
 259         assertTrue(!exists(doesNotExist));
 260         assertTrue(notExists(doesNotExist));
 261 
 262         Path file = createFile(tmpdir.resolve("foo"));
 263         try {
 264             // files exist
 265             assertTrue(isReadable(file));
 266             assertTrue(isWritable(file));
 267             assertTrue(exists(file));
 268             assertTrue(!notExists(file));
 269             assertTrue(isReadable(tmpdir));
 270             assertTrue(isWritable(tmpdir));
 271             assertTrue(exists(tmpdir));
 272             assertTrue(!notExists(tmpdir));
 273 
 274 
 275             // sym link exists
 276             if (TestUtil.supportsLinks(tmpdir)) {
 277                 Path link = tmpdir.resolve("link");
 278 
 279                 createSymbolicLink(link, file);
 280                 try {
 281                     assertTrue(isReadable(link));
 282                     assertTrue(isWritable(link));
 283                     assertTrue(exists(link));
 284                     assertTrue(!notExists(link));
 285                 } finally {
 286                     delete(link);
 287                 }
 288 
 289                 createSymbolicLink(link, doesNotExist);
 290                 try {
 291                     assertTrue(!isReadable(link));
 292                     assertTrue(!isWritable(link));
 293                     assertTrue(!exists(link));
 294                     assertTrue(exists(link, NOFOLLOW_LINKS));
 295                     assertTrue(notExists(link));
 296                     assertTrue(!notExists(link, NOFOLLOW_LINKS));
 297                 } finally {
 298                     delete(link);
 299                 }
 300             }
 301 
 302             /**
 303              * Test: Edit ACL to deny WRITE and EXECUTE
 304              */
 305             if (getFileStore(file).supportsFileAttributeView("acl")) {
 306                 AclFileAttributeView view =
 307                     getFileAttributeView(file, AclFileAttributeView.class);
 308                 UserPrincipal owner = view.getOwner();
 309                 List<AclEntry> acl = view.getAcl();
 310 
 311                 // Insert entry to deny WRITE and EXECUTE
 312                 AclEntry entry = AclEntry.newBuilder()
 313                     .setType(AclEntryType.DENY)
 314                     .setPrincipal(owner)
 315                     .setPermissions(AclEntryPermission.WRITE_DATA,
 316                                     AclEntryPermission.EXECUTE)
 317                     .build();
 318                 acl.add(0, entry);
 319                 view.setAcl(acl);
 320                 try {
 321                     if (isRoot()) {
 322                         // root has all permissions
 323                         assertTrue(isWritable(file));
 324                         assertTrue(isExecutable(file));
 325                     } else {
 326                         assertTrue(!isWritable(file));
 327                         assertTrue(!isExecutable(file));
 328                     }
 329                 } finally {
 330                     // Restore ACL
 331                     acl.remove(0);
 332                     view.setAcl(acl);
 333                 }
 334             }
 335 
 336             /**
 337              * Test: Windows DOS read-only attribute
 338              */
 339             if (System.getProperty("os.name").startsWith("Windows")) {
 340                 setAttribute(file, "dos:readonly", true);
 341                 try {
 342                     assertTrue(!isWritable(file));
 343                 } finally {
 344                     setAttribute(file, "dos:readonly", false);
 345                 }
 346 
 347                 // Read-only attribute does not make direcory read-only
 348                 DosFileAttributeView view =
 349                     getFileAttributeView(tmpdir, DosFileAttributeView.class);
 350                 boolean save = view.readAttributes().isReadOnly();
 351                 view.setReadOnly(true);
 352                 try {
 353                     assertTrue(isWritable(file));
 354                 } finally {
 355                     view.setReadOnly(save);
 356                 }
 357             }
 358         } finally {
 359             delete(file);
 360         }
 361     }
 362 
 363     static void assertTrue(boolean okay) {
 364         if (!okay)
 365             throw new RuntimeException("Assertion Failed");
 366     }
 367 
 368     private static boolean isRoot() {
 369         if (System.getProperty("os.name").startsWith("Windows"))
 370             return false;
 371 
 372         Path passwd = Paths.get("/etc/passwd");
 373         return Files.isWritable(passwd);
 374     }
 375 }