SecureDS.java revision 1319
893N/A/*
893N/A * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
893N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
893N/A *
893N/A * This code is free software; you can redistribute it and/or modify it
893N/A * under the terms of the GNU General Public License version 2 only, as
893N/A * published by the Free Software Foundation.
893N/A *
893N/A * This code is distributed in the hope that it will be useful, but WITHOUT
893N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
893N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
893N/A * version 2 for more details (a copy is included in the LICENSE file that
893N/A * accompanied this code).
893N/A *
893N/A * You should have received a copy of the GNU General Public License version
893N/A * 2 along with this work; if not, write to the Free Software Foundation,
893N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
893N/A *
893N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
893N/A * CA 95054 USA or visit www.sun.com if you need additional information or
893N/A * have any questions.
893N/A */
893N/A
893N/A/* @test
1319N/A * @bug 4313887 6838333
893N/A * @summary Unit test for java.nio.file.SecureDirectoryStream
893N/A * @library ..
893N/A */
893N/A
893N/Aimport java.nio.file.*;
893N/Aimport static java.nio.file.StandardOpenOption.*;
893N/Aimport static java.nio.file.LinkOption.*;
893N/Aimport java.nio.file.attribute.*;
893N/Aimport java.nio.channels.*;
893N/Aimport java.io.IOException;
893N/Aimport java.util.*;
893N/A
893N/Apublic class SecureDS {
893N/A static boolean supportsLinks;
893N/A
893N/A public static void main(String[] args) throws IOException {
893N/A Path dir = TestUtil.createTemporaryDirectory();
893N/A try {
1319N/A DirectoryStream<Path> stream = dir.newDirectoryStream();
893N/A stream.close();
893N/A if (!(stream instanceof SecureDirectoryStream)) {
893N/A System.out.println("SecureDirectoryStream not supported.");
893N/A return;
893N/A }
893N/A
893N/A supportsLinks = TestUtil.supportsLinks(dir);
893N/A
893N/A // run tests
893N/A doBasicTests(dir);
893N/A doMoveTests(dir);
893N/A miscTests(dir);
893N/A
893N/A } finally {
893N/A TestUtil.removeAll(dir);
893N/A }
893N/A }
893N/A
893N/A // Exercise each of SecureDirectoryStream's method (except move)
893N/A static void doBasicTests(Path dir) throws IOException {
893N/A Path dir1 = dir.resolve("dir1").createDirectory();
893N/A Path dir2 = dir.resolve("dir2");
893N/A
893N/A // create a file, directory, and two sym links in the directory
893N/A Path fileEntry = Paths.get("myfile");
893N/A dir1.resolve(fileEntry).createFile();
893N/A Path dirEntry = Paths.get("mydir");
893N/A dir1.resolve(dirEntry).createDirectory();
893N/A // myfilelink -> myfile
893N/A Path link1Entry = Paths.get("myfilelink");
893N/A if (supportsLinks)
893N/A dir1.resolve(link1Entry).createSymbolicLink(fileEntry);
893N/A // mydirlink -> mydir
893N/A Path link2Entry = Paths.get("mydirlink");
893N/A if (supportsLinks)
893N/A dir1.resolve(link2Entry).createSymbolicLink(dirEntry);
893N/A
893N/A // open directory and then move it so that it is no longer accessible
893N/A // via its original path.
1319N/A SecureDirectoryStream<Path> stream =
1319N/A (SecureDirectoryStream<Path>)dir1.newDirectoryStream();
893N/A dir1.moveTo(dir2);
893N/A
893N/A // Test: iterate over all entries
893N/A int count = 0;
893N/A for (Path entry: stream) { count++; }
893N/A assertTrue(count == (supportsLinks ? 4 : 2));
893N/A
893N/A // Test: getFileAttributeView to access directory's attributes
893N/A assertTrue(stream
893N/A .getFileAttributeView(BasicFileAttributeView.class)
893N/A .readAttributes()
893N/A .isDirectory());
893N/A
893N/A // Test: getFileAttributeView to access attributes of entries
893N/A assertTrue(stream
893N/A .getFileAttributeView(fileEntry, BasicFileAttributeView.class)
893N/A .readAttributes()
893N/A .isRegularFile());
893N/A assertTrue(stream
893N/A .getFileAttributeView(fileEntry, BasicFileAttributeView.class, NOFOLLOW_LINKS)
893N/A .readAttributes()
893N/A .isRegularFile());
893N/A assertTrue(stream
893N/A .getFileAttributeView(dirEntry, BasicFileAttributeView.class)
893N/A .readAttributes()
893N/A .isDirectory());
893N/A assertTrue(stream
893N/A .getFileAttributeView(dirEntry, BasicFileAttributeView.class, NOFOLLOW_LINKS)
893N/A .readAttributes()
893N/A .isDirectory());
893N/A if (supportsLinks) {
893N/A assertTrue(stream
893N/A .getFileAttributeView(link1Entry, BasicFileAttributeView.class)
893N/A .readAttributes()
893N/A .isRegularFile());
893N/A assertTrue(stream
893N/A .getFileAttributeView(link1Entry, BasicFileAttributeView.class, NOFOLLOW_LINKS)
893N/A .readAttributes()
893N/A .isSymbolicLink());
893N/A assertTrue(stream
893N/A .getFileAttributeView(link2Entry, BasicFileAttributeView.class)
893N/A .readAttributes()
893N/A .isDirectory());
893N/A assertTrue(stream
893N/A .getFileAttributeView(link2Entry, BasicFileAttributeView.class, NOFOLLOW_LINKS)
893N/A .readAttributes()
893N/A .isSymbolicLink());
893N/A }
893N/A
893N/A // Test: newByteChannel
893N/A Set<StandardOpenOption> opts = Collections.emptySet();
893N/A stream.newByteChannel(fileEntry, opts).close();
893N/A if (supportsLinks) {
893N/A stream.newByteChannel(link1Entry, opts).close();
893N/A try {
893N/A Set<OpenOption> mixed = new HashSet<OpenOption>();
893N/A mixed.add(READ);
893N/A mixed.add(NOFOLLOW_LINKS);
893N/A stream.newByteChannel(link1Entry, mixed).close();
893N/A shouldNotGetHere();
893N/A } catch (IOException x) { }
893N/A }
893N/A
893N/A // Test: newDirectoryStream
1319N/A stream.newDirectoryStream(dirEntry).close();
1319N/A stream.newDirectoryStream(dirEntry, LinkOption.NOFOLLOW_LINKS).close();
893N/A if (supportsLinks) {
1319N/A stream.newDirectoryStream(link2Entry).close();
893N/A try {
1319N/A stream.newDirectoryStream(link2Entry, LinkOption.NOFOLLOW_LINKS)
1319N/A .close();
893N/A shouldNotGetHere();
893N/A } catch (IOException x) { }
893N/A }
893N/A
893N/A // Test: delete
893N/A if (supportsLinks) {
893N/A stream.deleteFile(link1Entry);
893N/A stream.deleteFile(link2Entry);
893N/A }
893N/A stream.deleteDirectory(dirEntry);
893N/A stream.deleteFile(fileEntry);
893N/A
893N/A // Test: remove
893N/A // (requires resetting environment to get new iterator)
893N/A stream.close();
893N/A dir2.moveTo(dir1);
893N/A dir1.resolve(fileEntry).createFile();
1319N/A stream = (SecureDirectoryStream<Path>)dir1.newDirectoryStream();
893N/A dir1.moveTo(dir2);
893N/A Iterator<Path> iter = stream.iterator();
893N/A int removed = 0;
893N/A while (iter.hasNext()) {
893N/A iter.next();
893N/A iter.remove();
893N/A removed++;
893N/A }
893N/A assertTrue(removed == 1);
893N/A
893N/A // clean-up
893N/A stream.close();
893N/A dir2.delete();
893N/A }
893N/A
893N/A // Exercise SecureDirectoryStream's move method
893N/A static void doMoveTests(Path dir) throws IOException {
893N/A Path dir1 = dir.resolve("dir1").createDirectory();
893N/A Path dir2 = dir.resolve("dir2").createDirectory();
893N/A
893N/A // create dir1/myfile, dir1/mydir, dir1/mylink
893N/A Path fileEntry = Paths.get("myfile");
893N/A dir1.resolve(fileEntry).createFile();
893N/A Path dirEntry = Paths.get("mydir");
893N/A dir1.resolve(dirEntry).createDirectory();
893N/A Path linkEntry = Paths.get("mylink");
893N/A if (supportsLinks)
893N/A dir1.resolve(linkEntry).createSymbolicLink(Paths.get("missing"));
893N/A
893N/A // target name
893N/A Path target = Paths.get("newfile");
893N/A
893N/A // open stream to both directories
1319N/A SecureDirectoryStream<Path> stream1 =
1319N/A (SecureDirectoryStream<Path>)dir1.newDirectoryStream();
1319N/A SecureDirectoryStream<Path> stream2 =
1319N/A (SecureDirectoryStream<Path>)dir2.newDirectoryStream();
893N/A
893N/A // Test: move dir1/myfile -> dir2/newfile
893N/A stream1.move(fileEntry, stream2, target);
893N/A assertTrue(dir1.resolve(fileEntry).notExists());
893N/A assertTrue(dir2.resolve(target).exists());
893N/A stream2.deleteFile(target);
893N/A
893N/A // Test: move dir1/mydir -> dir2/newfile
893N/A stream1.move(dirEntry, stream2, target);
893N/A assertTrue(dir1.resolve(dirEntry).notExists());
893N/A assertTrue(dir2.resolve(target).exists());
893N/A stream2.deleteDirectory(target);
893N/A
893N/A // Test: move dir1/mylink -> dir2/newfile
893N/A if (supportsLinks) {
893N/A stream1.move(linkEntry, stream2, target);
893N/A assertTrue(dir2.resolve(target)
893N/A .getFileAttributeView(BasicFileAttributeView.class, NOFOLLOW_LINKS)
893N/A .readAttributes()
893N/A .isSymbolicLink());
893N/A stream2.deleteFile(target);
893N/A }
893N/A
893N/A // Test: move between devices
893N/A String testDirAsString = System.getProperty("test.dir");
893N/A if (testDirAsString != null) {
893N/A Path testDir = Paths.get(testDirAsString);
893N/A if (!dir1.getFileStore().equals(testDir.getFileStore())) {
1319N/A SecureDirectoryStream<Path> ts =
1319N/A (SecureDirectoryStream<Path>)testDir.newDirectoryStream();
893N/A dir1.resolve(fileEntry).createFile();
893N/A try {
893N/A stream1.move(fileEntry, ts, target);
893N/A shouldNotGetHere();
893N/A } catch (AtomicMoveNotSupportedException x) { }
893N/A ts.close();
893N/A stream1.deleteFile(fileEntry);
893N/A }
893N/A }
893N/A
893N/A // clean-up
893N/A dir1.delete();
893N/A dir2.delete();
893N/A }
893N/A
893N/A // null and ClosedDirectoryStreamException
893N/A static void miscTests(Path dir) throws IOException {
893N/A Path file = Paths.get("file");
893N/A dir.resolve(file).createFile();
893N/A
1319N/A SecureDirectoryStream<Path> stream =
1319N/A (SecureDirectoryStream<Path>)dir.newDirectoryStream();
893N/A
893N/A // NullPointerException
893N/A try {
893N/A stream.getFileAttributeView(null);
893N/A shouldNotGetHere();
893N/A } catch (NullPointerException x) { }
893N/A try {
893N/A stream.getFileAttributeView(null, BasicFileAttributeView.class);
893N/A shouldNotGetHere();
893N/A } catch (NullPointerException x) { }
893N/A try {
893N/A stream.getFileAttributeView(file, null);
893N/A shouldNotGetHere();
893N/A } catch (NullPointerException x) { }
893N/A try {
893N/A stream.newByteChannel(null, EnumSet.of(CREATE,WRITE));
893N/A shouldNotGetHere();
893N/A } catch (NullPointerException x) { }
893N/A try {
893N/A stream.newByteChannel(null, EnumSet.of(CREATE,WRITE,null));
893N/A shouldNotGetHere();
893N/A } catch (NullPointerException x) { }
893N/A try {
893N/A stream.newByteChannel(file, null);
893N/A shouldNotGetHere();
893N/A } catch (NullPointerException x) { }
893N/A try {
893N/A stream.move(null, stream, file);
893N/A shouldNotGetHere();
893N/A } catch (NullPointerException x) { }
893N/A try {
893N/A stream.move(file, null, file);
893N/A shouldNotGetHere();
893N/A } catch (NullPointerException x) { }
893N/A try {
893N/A stream.move(file, stream, null);
893N/A shouldNotGetHere();
893N/A } catch (NullPointerException x) { }
893N/A try {
1319N/A stream.newDirectoryStream(null);
893N/A shouldNotGetHere();
893N/A } catch (NullPointerException x) { }
893N/A try {
893N/A stream.deleteFile(null);
893N/A shouldNotGetHere();
893N/A } catch (NullPointerException x) { }
893N/A try {
893N/A stream.deleteDirectory(null);
893N/A shouldNotGetHere();
893N/A } catch (NullPointerException x) { }
893N/A
893N/A // close stream
893N/A stream.close();
893N/A stream.close(); // should be no-op
893N/A
893N/A // ClosedDirectoryStreamException
893N/A try {
1319N/A stream.newDirectoryStream(file);
893N/A shouldNotGetHere();
893N/A } catch (ClosedDirectoryStreamException x) { }
893N/A try {
893N/A stream.newByteChannel(file, EnumSet.of(READ));
893N/A shouldNotGetHere();
893N/A } catch (ClosedDirectoryStreamException x) { }
893N/A try {
893N/A stream.move(file, stream, file);
893N/A shouldNotGetHere();
893N/A } catch (ClosedDirectoryStreamException x) { }
893N/A try {
893N/A stream.deleteFile(file);
893N/A shouldNotGetHere();
893N/A } catch (ClosedDirectoryStreamException x) { }
893N/A
893N/A // clean-up
893N/A dir.resolve(file).delete();
893N/A }
893N/A
893N/A static void assertTrue(boolean b) {
893N/A if (!b) throw new RuntimeException("Assertion failed");
893N/A }
893N/A
893N/A static void shouldNotGetHere() {
893N/A assertTrue(false);
893N/A }
893N/A}