jdk/test/java/nio/file/DirectoryStream/SecureDS.java
changeset 2057 3acf8e5e2ca0
child 3065 452aaa2899fc
equal deleted inserted replaced
2056:115e09b7a004 2057:3acf8e5e2ca0
       
     1 /*
       
     2  * Copyright 2008-2009 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    21  * have any questions.
       
    22  */
       
    23 
       
    24 /* @test
       
    25  * @bug 4313887
       
    26  * @summary Unit test for java.nio.file.SecureDirectoryStream
       
    27  * @library ..
       
    28  */
       
    29 
       
    30 import java.nio.file.*;
       
    31 import static java.nio.file.StandardOpenOption.*;
       
    32 import static java.nio.file.LinkOption.*;
       
    33 import java.nio.file.attribute.*;
       
    34 import java.nio.channels.*;
       
    35 import java.io.IOException;
       
    36 import java.util.*;
       
    37 
       
    38 public class SecureDS {
       
    39     static boolean supportsLinks;
       
    40 
       
    41     public static void main(String[] args) throws IOException {
       
    42         Path dir = TestUtil.createTemporaryDirectory();
       
    43         try {
       
    44             DirectoryStream stream = dir.newDirectoryStream();
       
    45             stream.close();
       
    46             if (!(stream instanceof SecureDirectoryStream)) {
       
    47                 System.out.println("SecureDirectoryStream not supported.");
       
    48                 return;
       
    49             }
       
    50 
       
    51             supportsLinks = TestUtil.supportsLinks(dir);
       
    52 
       
    53             // run tests
       
    54             doBasicTests(dir);
       
    55             doMoveTests(dir);
       
    56             miscTests(dir);
       
    57 
       
    58         } finally {
       
    59             TestUtil.removeAll(dir);
       
    60         }
       
    61     }
       
    62 
       
    63     // Exercise each of SecureDirectoryStream's method (except move)
       
    64     static void doBasicTests(Path dir) throws IOException {
       
    65         Path dir1 = dir.resolve("dir1").createDirectory();
       
    66         Path dir2 = dir.resolve("dir2");
       
    67 
       
    68         // create a file, directory, and two sym links in the directory
       
    69         Path fileEntry = Paths.get("myfile");
       
    70         dir1.resolve(fileEntry).createFile();
       
    71         Path dirEntry = Paths.get("mydir");
       
    72         dir1.resolve(dirEntry).createDirectory();
       
    73         // myfilelink -> myfile
       
    74         Path link1Entry = Paths.get("myfilelink");
       
    75         if (supportsLinks)
       
    76             dir1.resolve(link1Entry).createSymbolicLink(fileEntry);
       
    77         // mydirlink -> mydir
       
    78         Path link2Entry = Paths.get("mydirlink");
       
    79         if (supportsLinks)
       
    80             dir1.resolve(link2Entry).createSymbolicLink(dirEntry);
       
    81 
       
    82         // open directory and then move it so that it is no longer accessible
       
    83         // via its original path.
       
    84         SecureDirectoryStream stream =
       
    85             (SecureDirectoryStream)dir1.newDirectoryStream();
       
    86         dir1.moveTo(dir2);
       
    87 
       
    88         // Test: iterate over all entries
       
    89         int count = 0;
       
    90         for (Path entry: stream) { count++; }
       
    91         assertTrue(count == (supportsLinks ? 4 : 2));
       
    92 
       
    93         // Test: getFileAttributeView to access directory's attributes
       
    94         assertTrue(stream
       
    95             .getFileAttributeView(BasicFileAttributeView.class)
       
    96                 .readAttributes()
       
    97                     .isDirectory());
       
    98 
       
    99         // Test: dynamic access to directory's attributes
       
   100         BasicFileAttributeView view = stream.
       
   101             getFileAttributeView(BasicFileAttributeView.class);
       
   102         Map<String,?> attrs = view.readAttributes("*");
       
   103         assertTrue((Boolean)attrs.get("isDirectory"));
       
   104         attrs = view.readAttributes("isRegularFile", "size");
       
   105         assertTrue(!(Boolean)attrs.get("isRegularFile"));
       
   106         assertTrue((Long)attrs.get("size") >= 0);
       
   107         int linkCount = (Integer)view.getAttribute("linkCount");
       
   108         assertTrue(linkCount > 0);
       
   109         view.setAttribute("lastModifiedTime", 0L);
       
   110 
       
   111         // Test: getFileAttributeView to access attributes of entries
       
   112         assertTrue(stream
       
   113             .getFileAttributeView(fileEntry, BasicFileAttributeView.class)
       
   114                 .readAttributes()
       
   115                     .isRegularFile());
       
   116         assertTrue(stream
       
   117             .getFileAttributeView(fileEntry, BasicFileAttributeView.class, NOFOLLOW_LINKS)
       
   118                 .readAttributes()
       
   119                     .isRegularFile());
       
   120         assertTrue(stream
       
   121             .getFileAttributeView(dirEntry, BasicFileAttributeView.class)
       
   122                 .readAttributes()
       
   123                     .isDirectory());
       
   124         assertTrue(stream
       
   125             .getFileAttributeView(dirEntry, BasicFileAttributeView.class, NOFOLLOW_LINKS)
       
   126                 .readAttributes()
       
   127                     .isDirectory());
       
   128         if (supportsLinks) {
       
   129             assertTrue(stream
       
   130                 .getFileAttributeView(link1Entry, BasicFileAttributeView.class)
       
   131                     .readAttributes()
       
   132                         .isRegularFile());
       
   133             assertTrue(stream
       
   134                 .getFileAttributeView(link1Entry, BasicFileAttributeView.class, NOFOLLOW_LINKS)
       
   135                     .readAttributes()
       
   136                         .isSymbolicLink());
       
   137             assertTrue(stream
       
   138                 .getFileAttributeView(link2Entry, BasicFileAttributeView.class)
       
   139                     .readAttributes()
       
   140                         .isDirectory());
       
   141             assertTrue(stream
       
   142                 .getFileAttributeView(link2Entry, BasicFileAttributeView.class, NOFOLLOW_LINKS)
       
   143                     .readAttributes()
       
   144                         .isSymbolicLink());
       
   145         }
       
   146 
       
   147         // Test: dynamic access to entry attributes
       
   148         view = stream
       
   149              .getFileAttributeView(fileEntry, PosixFileAttributeView.class, NOFOLLOW_LINKS);
       
   150         if (view != null) {
       
   151             attrs = view.readAttributes("owner", "size");
       
   152             UserPrincipal owner = (UserPrincipal)attrs.get("owner");
       
   153             assertTrue(owner != null);
       
   154             assertTrue((Long)attrs.get("size") >= 0L);
       
   155             view.setAttribute("lastAccessTime", 0L);
       
   156         }
       
   157 
       
   158         // Test: newByteChannel
       
   159         Set<StandardOpenOption> opts = Collections.emptySet();
       
   160         stream.newByteChannel(fileEntry, opts).close();
       
   161         if (supportsLinks) {
       
   162             stream.newByteChannel(link1Entry, opts).close();
       
   163             try {
       
   164                 Set<OpenOption> mixed = new HashSet<OpenOption>();
       
   165                 mixed.add(READ);
       
   166                 mixed.add(NOFOLLOW_LINKS);
       
   167                 stream.newByteChannel(link1Entry, mixed).close();
       
   168                 shouldNotGetHere();
       
   169             } catch (IOException x) { }
       
   170         }
       
   171 
       
   172         // Test: newDirectoryStream
       
   173         stream.newDirectoryStream(dirEntry, true, null).close();
       
   174         stream.newDirectoryStream(dirEntry, false, null).close();
       
   175         if (supportsLinks) {
       
   176             stream.newDirectoryStream(link2Entry, true, null).close();
       
   177             try {
       
   178                 stream.newDirectoryStream(link2Entry, false, null).close();
       
   179                 shouldNotGetHere();
       
   180             } catch (IOException x) { }
       
   181         }
       
   182 
       
   183         // Test: delete
       
   184         if (supportsLinks) {
       
   185             stream.deleteFile(link1Entry);
       
   186             stream.deleteFile(link2Entry);
       
   187         }
       
   188         stream.deleteDirectory(dirEntry);
       
   189         stream.deleteFile(fileEntry);
       
   190 
       
   191         // Test: remove
       
   192         // (requires resetting environment to get new iterator)
       
   193         stream.close();
       
   194         dir2.moveTo(dir1);
       
   195         dir1.resolve(fileEntry).createFile();
       
   196         stream = (SecureDirectoryStream)dir1.newDirectoryStream();
       
   197         dir1.moveTo(dir2);
       
   198         Iterator<Path> iter = stream.iterator();
       
   199         int removed = 0;
       
   200         while (iter.hasNext()) {
       
   201             iter.next();
       
   202             iter.remove();
       
   203             removed++;
       
   204         }
       
   205         assertTrue(removed == 1);
       
   206 
       
   207         // clean-up
       
   208         stream.close();
       
   209         dir2.delete();
       
   210     }
       
   211 
       
   212     // Exercise SecureDirectoryStream's move method
       
   213     static void doMoveTests(Path dir) throws IOException {
       
   214         Path dir1 = dir.resolve("dir1").createDirectory();
       
   215         Path dir2 = dir.resolve("dir2").createDirectory();
       
   216 
       
   217         // create dir1/myfile, dir1/mydir, dir1/mylink
       
   218         Path fileEntry = Paths.get("myfile");
       
   219         dir1.resolve(fileEntry).createFile();
       
   220         Path dirEntry = Paths.get("mydir");
       
   221         dir1.resolve(dirEntry).createDirectory();
       
   222         Path linkEntry = Paths.get("mylink");
       
   223         if (supportsLinks)
       
   224             dir1.resolve(linkEntry).createSymbolicLink(Paths.get("missing"));
       
   225 
       
   226         // target name
       
   227         Path target = Paths.get("newfile");
       
   228 
       
   229         // open stream to both directories
       
   230         SecureDirectoryStream stream1 =
       
   231             (SecureDirectoryStream)dir1.newDirectoryStream();
       
   232         SecureDirectoryStream stream2 =
       
   233             (SecureDirectoryStream)dir2.newDirectoryStream();
       
   234 
       
   235         // Test: move dir1/myfile -> dir2/newfile
       
   236         stream1.move(fileEntry, stream2, target);
       
   237         assertTrue(dir1.resolve(fileEntry).notExists());
       
   238         assertTrue(dir2.resolve(target).exists());
       
   239         stream2.deleteFile(target);
       
   240 
       
   241         // Test: move dir1/mydir -> dir2/newfile
       
   242         stream1.move(dirEntry, stream2, target);
       
   243         assertTrue(dir1.resolve(dirEntry).notExists());
       
   244         assertTrue(dir2.resolve(target).exists());
       
   245         stream2.deleteDirectory(target);
       
   246 
       
   247         // Test: move dir1/mylink -> dir2/newfile
       
   248         if (supportsLinks) {
       
   249             stream1.move(linkEntry, stream2, target);
       
   250             assertTrue(dir2.resolve(target)
       
   251                 .getFileAttributeView(BasicFileAttributeView.class, NOFOLLOW_LINKS)
       
   252                 .readAttributes()
       
   253                 .isSymbolicLink());
       
   254             stream2.deleteFile(target);
       
   255         }
       
   256 
       
   257         // Test: move between devices
       
   258         String testDirAsString = System.getProperty("test.dir");
       
   259         if (testDirAsString != null) {
       
   260             Path testDir = Paths.get(testDirAsString);
       
   261             if (!dir1.getFileStore().equals(testDir.getFileStore())) {
       
   262                 SecureDirectoryStream ts =
       
   263                     (SecureDirectoryStream)testDir.newDirectoryStream();
       
   264                 dir1.resolve(fileEntry).createFile();
       
   265                 try {
       
   266                     stream1.move(fileEntry, ts, target);
       
   267                     shouldNotGetHere();
       
   268                 } catch (AtomicMoveNotSupportedException x) { }
       
   269                 ts.close();
       
   270                 stream1.deleteFile(fileEntry);
       
   271             }
       
   272         }
       
   273 
       
   274         // clean-up
       
   275         dir1.delete();
       
   276         dir2.delete();
       
   277     }
       
   278 
       
   279     // null and ClosedDirectoryStreamException
       
   280     static void miscTests(Path dir) throws IOException {
       
   281         Path file = Paths.get("file");
       
   282         dir.resolve(file).createFile();
       
   283 
       
   284         SecureDirectoryStream stream =
       
   285             (SecureDirectoryStream)dir.newDirectoryStream();
       
   286 
       
   287         // NullPointerException
       
   288         try {
       
   289             stream.getFileAttributeView(null);
       
   290             shouldNotGetHere();
       
   291         } catch (NullPointerException x) { }
       
   292         try {
       
   293             stream.getFileAttributeView(null, BasicFileAttributeView.class);
       
   294             shouldNotGetHere();
       
   295         } catch (NullPointerException x) { }
       
   296         try {
       
   297             stream.getFileAttributeView(file, null);
       
   298             shouldNotGetHere();
       
   299         } catch (NullPointerException x) { }
       
   300         try {
       
   301             stream.newByteChannel(null, EnumSet.of(CREATE,WRITE));
       
   302             shouldNotGetHere();
       
   303         } catch (NullPointerException x) { }
       
   304         try {
       
   305             stream.newByteChannel(null, EnumSet.of(CREATE,WRITE,null));
       
   306             shouldNotGetHere();
       
   307         } catch (NullPointerException x) { }
       
   308         try {
       
   309             stream.newByteChannel(file, null);
       
   310             shouldNotGetHere();
       
   311         } catch (NullPointerException x) { }
       
   312         try {
       
   313             stream.move(null, stream, file);
       
   314             shouldNotGetHere();
       
   315         } catch (NullPointerException x) { }
       
   316         try {
       
   317             stream.move(file, null, file);
       
   318             shouldNotGetHere();
       
   319         } catch (NullPointerException x) { }
       
   320         try {
       
   321             stream.move(file, stream, null);
       
   322             shouldNotGetHere();
       
   323         } catch (NullPointerException x) { }
       
   324         try {
       
   325             stream.newDirectoryStream(null, true, null);
       
   326             shouldNotGetHere();
       
   327         } catch (NullPointerException x) { }
       
   328         try {
       
   329             stream.deleteFile(null);
       
   330             shouldNotGetHere();
       
   331         } catch (NullPointerException x) { }
       
   332         try {
       
   333             stream.deleteDirectory(null);
       
   334             shouldNotGetHere();
       
   335         } catch (NullPointerException x) { }
       
   336 
       
   337         // close stream
       
   338         stream.close();
       
   339         stream.close();     // should be no-op
       
   340 
       
   341         // ClosedDirectoryStreamException
       
   342         try {
       
   343             stream.newDirectoryStream(file, true, null);
       
   344             shouldNotGetHere();
       
   345         } catch (ClosedDirectoryStreamException x) { }
       
   346         try {
       
   347             stream.newByteChannel(file, EnumSet.of(READ));
       
   348             shouldNotGetHere();
       
   349         } catch (ClosedDirectoryStreamException x) { }
       
   350         try {
       
   351             stream.move(file, stream, file);
       
   352             shouldNotGetHere();
       
   353         } catch (ClosedDirectoryStreamException x) { }
       
   354         try {
       
   355             stream.deleteFile(file);
       
   356             shouldNotGetHere();
       
   357         } catch (ClosedDirectoryStreamException x) { }
       
   358 
       
   359         // clean-up
       
   360         dir.resolve(file).delete();
       
   361     }
       
   362 
       
   363     static void assertTrue(boolean b) {
       
   364         if (!b) throw new RuntimeException("Assertion failed");
       
   365     }
       
   366 
       
   367     static void shouldNotGetHere() {
       
   368         assertTrue(false);
       
   369     }
       
   370 }