SecureDS.java revision 2748:55eb9f25bf7a
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 26 * @summary Unit test for java.nio.file.SecureDirectoryStream 27 * @library .. 28 */ 29 30import java.nio.file.*; 31import static java.nio.file.StandardOpenOption.*; 32import static java.nio.file.LinkOption.*; 33import java.nio.file.attribute.*; 34import java.nio.channels.*; 35import java.io.IOException; 36import java.util.*; 37 38public 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<Path> 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<Path> stream = 85 (SecureDirectoryStream<Path>)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: getFileAttributeView to access attributes of entries 100 assertTrue(stream 101 .getFileAttributeView(fileEntry, BasicFileAttributeView.class) 102 .readAttributes() 103 .isRegularFile()); 104 assertTrue(stream 105 .getFileAttributeView(fileEntry, BasicFileAttributeView.class, NOFOLLOW_LINKS) 106 .readAttributes() 107 .isRegularFile()); 108 assertTrue(stream 109 .getFileAttributeView(dirEntry, BasicFileAttributeView.class) 110 .readAttributes() 111 .isDirectory()); 112 assertTrue(stream 113 .getFileAttributeView(dirEntry, BasicFileAttributeView.class, NOFOLLOW_LINKS) 114 .readAttributes() 115 .isDirectory()); 116 if (supportsLinks) { 117 assertTrue(stream 118 .getFileAttributeView(link1Entry, BasicFileAttributeView.class) 119 .readAttributes() 120 .isRegularFile()); 121 assertTrue(stream 122 .getFileAttributeView(link1Entry, BasicFileAttributeView.class, NOFOLLOW_LINKS) 123 .readAttributes() 124 .isSymbolicLink()); 125 assertTrue(stream 126 .getFileAttributeView(link2Entry, BasicFileAttributeView.class) 127 .readAttributes() 128 .isDirectory()); 129 assertTrue(stream 130 .getFileAttributeView(link2Entry, BasicFileAttributeView.class, NOFOLLOW_LINKS) 131 .readAttributes() 132 .isSymbolicLink()); 133 } 134 135 // Test: newByteChannel 136 Set<StandardOpenOption> opts = Collections.emptySet(); 137 stream.newByteChannel(fileEntry, opts).close(); 138 if (supportsLinks) { 139 stream.newByteChannel(link1Entry, opts).close(); 140 try { 141 Set<OpenOption> mixed = new HashSet<OpenOption>(); 142 mixed.add(READ); 143 mixed.add(NOFOLLOW_LINKS); 144 stream.newByteChannel(link1Entry, mixed).close(); 145 shouldNotGetHere(); 146 } catch (IOException x) { } 147 } 148 149 // Test: newDirectoryStream 150 stream.newDirectoryStream(dirEntry).close(); 151 stream.newDirectoryStream(dirEntry, LinkOption.NOFOLLOW_LINKS).close(); 152 if (supportsLinks) { 153 stream.newDirectoryStream(link2Entry).close(); 154 try { 155 stream.newDirectoryStream(link2Entry, LinkOption.NOFOLLOW_LINKS) 156 .close(); 157 shouldNotGetHere(); 158 } catch (IOException x) { } 159 } 160 161 // Test: delete 162 if (supportsLinks) { 163 stream.deleteFile(link1Entry); 164 stream.deleteFile(link2Entry); 165 } 166 stream.deleteDirectory(dirEntry); 167 stream.deleteFile(fileEntry); 168 169 // clean-up 170 stream.close(); 171 dir2.delete(); 172 } 173 174 // Exercise SecureDirectoryStream's move method 175 static void doMoveTests(Path dir) throws IOException { 176 Path dir1 = dir.resolve("dir1").createDirectory(); 177 Path dir2 = dir.resolve("dir2").createDirectory(); 178 179 // create dir1/myfile, dir1/mydir, dir1/mylink 180 Path fileEntry = Paths.get("myfile"); 181 dir1.resolve(fileEntry).createFile(); 182 Path dirEntry = Paths.get("mydir"); 183 dir1.resolve(dirEntry).createDirectory(); 184 Path linkEntry = Paths.get("mylink"); 185 if (supportsLinks) 186 dir1.resolve(linkEntry).createSymbolicLink(Paths.get("missing")); 187 188 // target name 189 Path target = Paths.get("newfile"); 190 191 // open stream to both directories 192 SecureDirectoryStream<Path> stream1 = 193 (SecureDirectoryStream<Path>)dir1.newDirectoryStream(); 194 SecureDirectoryStream<Path> stream2 = 195 (SecureDirectoryStream<Path>)dir2.newDirectoryStream(); 196 197 // Test: move dir1/myfile -> dir2/newfile 198 stream1.move(fileEntry, stream2, target); 199 assertTrue(dir1.resolve(fileEntry).notExists()); 200 assertTrue(dir2.resolve(target).exists()); 201 stream2.deleteFile(target); 202 203 // Test: move dir1/mydir -> dir2/newfile 204 stream1.move(dirEntry, stream2, target); 205 assertTrue(dir1.resolve(dirEntry).notExists()); 206 assertTrue(dir2.resolve(target).exists()); 207 stream2.deleteDirectory(target); 208 209 // Test: move dir1/mylink -> dir2/newfile 210 if (supportsLinks) { 211 stream1.move(linkEntry, stream2, target); 212 assertTrue(dir2.resolve(target) 213 .getFileAttributeView(BasicFileAttributeView.class, NOFOLLOW_LINKS) 214 .readAttributes() 215 .isSymbolicLink()); 216 stream2.deleteFile(target); 217 } 218 219 // Test: move between devices 220 String testDirAsString = System.getProperty("test.dir"); 221 if (testDirAsString != null) { 222 Path testDir = Paths.get(testDirAsString); 223 if (!dir1.getFileStore().equals(testDir.getFileStore())) { 224 SecureDirectoryStream<Path> ts = 225 (SecureDirectoryStream<Path>)testDir.newDirectoryStream(); 226 dir1.resolve(fileEntry).createFile(); 227 try { 228 stream1.move(fileEntry, ts, target); 229 shouldNotGetHere(); 230 } catch (AtomicMoveNotSupportedException x) { } 231 ts.close(); 232 stream1.deleteFile(fileEntry); 233 } 234 } 235 236 // clean-up 237 dir1.delete(); 238 dir2.delete(); 239 } 240 241 // null and ClosedDirectoryStreamException 242 static void miscTests(Path dir) throws IOException { 243 Path file = Paths.get("file"); 244 dir.resolve(file).createFile(); 245 246 SecureDirectoryStream<Path> stream = 247 (SecureDirectoryStream<Path>)dir.newDirectoryStream(); 248 249 // NullPointerException 250 try { 251 stream.getFileAttributeView(null); 252 shouldNotGetHere(); 253 } catch (NullPointerException x) { } 254 try { 255 stream.getFileAttributeView(null, BasicFileAttributeView.class); 256 shouldNotGetHere(); 257 } catch (NullPointerException x) { } 258 try { 259 stream.getFileAttributeView(file, null); 260 shouldNotGetHere(); 261 } catch (NullPointerException x) { } 262 try { 263 stream.newByteChannel(null, EnumSet.of(CREATE,WRITE)); 264 shouldNotGetHere(); 265 } catch (NullPointerException x) { } 266 try { 267 stream.newByteChannel(null, EnumSet.of(CREATE,WRITE,null)); 268 shouldNotGetHere(); 269 } catch (NullPointerException x) { } 270 try { 271 stream.newByteChannel(file, null); 272 shouldNotGetHere(); 273 } catch (NullPointerException x) { } 274 try { 275 stream.move(null, stream, file); 276 shouldNotGetHere(); 277 } catch (NullPointerException x) { } 278 try { 279 stream.move(file, null, file); 280 shouldNotGetHere(); 281 } catch (NullPointerException x) { } 282 try { 283 stream.move(file, stream, null); 284 shouldNotGetHere(); 285 } catch (NullPointerException x) { } 286 try { 287 stream.newDirectoryStream(null); 288 shouldNotGetHere(); 289 } catch (NullPointerException x) { } 290 try { 291 stream.deleteFile(null); 292 shouldNotGetHere(); 293 } catch (NullPointerException x) { } 294 try { 295 stream.deleteDirectory(null); 296 shouldNotGetHere(); 297 } catch (NullPointerException x) { } 298 299 // close stream 300 stream.close(); 301 stream.close(); // should be no-op 302 303 // ClosedDirectoryStreamException 304 try { 305 stream.newDirectoryStream(file); 306 shouldNotGetHere(); 307 } catch (ClosedDirectoryStreamException x) { } 308 try { 309 stream.newByteChannel(file, EnumSet.of(READ)); 310 shouldNotGetHere(); 311 } catch (ClosedDirectoryStreamException x) { } 312 try { 313 stream.move(file, stream, file); 314 shouldNotGetHere(); 315 } catch (ClosedDirectoryStreamException x) { } 316 try { 317 stream.deleteFile(file); 318 shouldNotGetHere(); 319 } catch (ClosedDirectoryStreamException x) { } 320 321 // clean-up 322 dir.resolve(file).delete(); 323 } 324 325 static void assertTrue(boolean b) { 326 if (!b) throw new RuntimeException("Assertion failed"); 327 } 328 329 static void shouldNotGetHere() { 330 assertTrue(false); 331 } 332} 333