SecureDS.java revision 2362:00cd9dc3c2b5
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 // Test: remove 170 // (requires resetting environment to get new iterator) 171 stream.close(); 172 dir2.moveTo(dir1); 173 dir1.resolve(fileEntry).createFile(); 174 stream = (SecureDirectoryStream<Path>)dir1.newDirectoryStream(); 175 dir1.moveTo(dir2); 176 Iterator<Path> iter = stream.iterator(); 177 int removed = 0; 178 while (iter.hasNext()) { 179 iter.next(); 180 iter.remove(); 181 removed++; 182 } 183 assertTrue(removed == 1); 184 185 // clean-up 186 stream.close(); 187 dir2.delete(); 188 } 189 190 // Exercise SecureDirectoryStream's move method 191 static void doMoveTests(Path dir) throws IOException { 192 Path dir1 = dir.resolve("dir1").createDirectory(); 193 Path dir2 = dir.resolve("dir2").createDirectory(); 194 195 // create dir1/myfile, dir1/mydir, dir1/mylink 196 Path fileEntry = Paths.get("myfile"); 197 dir1.resolve(fileEntry).createFile(); 198 Path dirEntry = Paths.get("mydir"); 199 dir1.resolve(dirEntry).createDirectory(); 200 Path linkEntry = Paths.get("mylink"); 201 if (supportsLinks) 202 dir1.resolve(linkEntry).createSymbolicLink(Paths.get("missing")); 203 204 // target name 205 Path target = Paths.get("newfile"); 206 207 // open stream to both directories 208 SecureDirectoryStream<Path> stream1 = 209 (SecureDirectoryStream<Path>)dir1.newDirectoryStream(); 210 SecureDirectoryStream<Path> stream2 = 211 (SecureDirectoryStream<Path>)dir2.newDirectoryStream(); 212 213 // Test: move dir1/myfile -> dir2/newfile 214 stream1.move(fileEntry, stream2, target); 215 assertTrue(dir1.resolve(fileEntry).notExists()); 216 assertTrue(dir2.resolve(target).exists()); 217 stream2.deleteFile(target); 218 219 // Test: move dir1/mydir -> dir2/newfile 220 stream1.move(dirEntry, stream2, target); 221 assertTrue(dir1.resolve(dirEntry).notExists()); 222 assertTrue(dir2.resolve(target).exists()); 223 stream2.deleteDirectory(target); 224 225 // Test: move dir1/mylink -> dir2/newfile 226 if (supportsLinks) { 227 stream1.move(linkEntry, stream2, target); 228 assertTrue(dir2.resolve(target) 229 .getFileAttributeView(BasicFileAttributeView.class, NOFOLLOW_LINKS) 230 .readAttributes() 231 .isSymbolicLink()); 232 stream2.deleteFile(target); 233 } 234 235 // Test: move between devices 236 String testDirAsString = System.getProperty("test.dir"); 237 if (testDirAsString != null) { 238 Path testDir = Paths.get(testDirAsString); 239 if (!dir1.getFileStore().equals(testDir.getFileStore())) { 240 SecureDirectoryStream<Path> ts = 241 (SecureDirectoryStream<Path>)testDir.newDirectoryStream(); 242 dir1.resolve(fileEntry).createFile(); 243 try { 244 stream1.move(fileEntry, ts, target); 245 shouldNotGetHere(); 246 } catch (AtomicMoveNotSupportedException x) { } 247 ts.close(); 248 stream1.deleteFile(fileEntry); 249 } 250 } 251 252 // clean-up 253 dir1.delete(); 254 dir2.delete(); 255 } 256 257 // null and ClosedDirectoryStreamException 258 static void miscTests(Path dir) throws IOException { 259 Path file = Paths.get("file"); 260 dir.resolve(file).createFile(); 261 262 SecureDirectoryStream<Path> stream = 263 (SecureDirectoryStream<Path>)dir.newDirectoryStream(); 264 265 // NullPointerException 266 try { 267 stream.getFileAttributeView(null); 268 shouldNotGetHere(); 269 } catch (NullPointerException x) { } 270 try { 271 stream.getFileAttributeView(null, BasicFileAttributeView.class); 272 shouldNotGetHere(); 273 } catch (NullPointerException x) { } 274 try { 275 stream.getFileAttributeView(file, null); 276 shouldNotGetHere(); 277 } catch (NullPointerException x) { } 278 try { 279 stream.newByteChannel(null, EnumSet.of(CREATE,WRITE)); 280 shouldNotGetHere(); 281 } catch (NullPointerException x) { } 282 try { 283 stream.newByteChannel(null, EnumSet.of(CREATE,WRITE,null)); 284 shouldNotGetHere(); 285 } catch (NullPointerException x) { } 286 try { 287 stream.newByteChannel(file, null); 288 shouldNotGetHere(); 289 } catch (NullPointerException x) { } 290 try { 291 stream.move(null, stream, file); 292 shouldNotGetHere(); 293 } catch (NullPointerException x) { } 294 try { 295 stream.move(file, null, file); 296 shouldNotGetHere(); 297 } catch (NullPointerException x) { } 298 try { 299 stream.move(file, stream, null); 300 shouldNotGetHere(); 301 } catch (NullPointerException x) { } 302 try { 303 stream.newDirectoryStream(null); 304 shouldNotGetHere(); 305 } catch (NullPointerException x) { } 306 try { 307 stream.deleteFile(null); 308 shouldNotGetHere(); 309 } catch (NullPointerException x) { } 310 try { 311 stream.deleteDirectory(null); 312 shouldNotGetHere(); 313 } catch (NullPointerException x) { } 314 315 // close stream 316 stream.close(); 317 stream.close(); // should be no-op 318 319 // ClosedDirectoryStreamException 320 try { 321 stream.newDirectoryStream(file); 322 shouldNotGetHere(); 323 } catch (ClosedDirectoryStreamException x) { } 324 try { 325 stream.newByteChannel(file, EnumSet.of(READ)); 326 shouldNotGetHere(); 327 } catch (ClosedDirectoryStreamException x) { } 328 try { 329 stream.move(file, stream, file); 330 shouldNotGetHere(); 331 } catch (ClosedDirectoryStreamException x) { } 332 try { 333 stream.deleteFile(file); 334 shouldNotGetHere(); 335 } catch (ClosedDirectoryStreamException x) { } 336 337 // clean-up 338 dir.resolve(file).delete(); 339 } 340 341 static void assertTrue(boolean b) { 342 if (!b) throw new RuntimeException("Assertion failed"); 343 } 344 345 static void shouldNotGetHere() { 346 assertTrue(false); 347 } 348} 349