1 /* 2 * Copyright (c) 2008, 2010, 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 30 import java.nio.file.*; 31 import static java.nio.file.Files.*; 32 import static java.nio.file.StandardOpenOption.*; 33 import static java.nio.file.LinkOption.*; 34 import java.nio.file.attribute.*; 35 import java.nio.channels.*; 36 import java.io.IOException; 37 import java.util.*; 38 39 public class SecureDS { 40 static boolean supportsLinks; 41 42 public static void main(String[] args) throws IOException { 43 Path dir = TestUtil.createTemporaryDirectory(); 44 try { 45 DirectoryStream<Path> stream = newDirectoryStream(dir); 46 stream.close(); 47 if (!(stream instanceof SecureDirectoryStream)) { 48 System.out.println("SecureDirectoryStream not supported."); 49 return; 50 } 51 52 supportsLinks = TestUtil.supportsLinks(dir); 53 54 // run tests 55 doBasicTests(dir); 56 doMoveTests(dir); 57 miscTests(dir); 58 59 } finally { 60 TestUtil.removeAll(dir); 61 } 62 } 63 64 // Exercise each of SecureDirectoryStream's method (except move) 65 static void doBasicTests(Path dir) throws IOException { 66 Path dir1 = createDirectory(dir.resolve("dir1")); 67 Path dir2 = dir.resolve("dir2"); 68 69 // create a file, directory, and two sym links in the directory 70 Path fileEntry = Paths.get("myfile"); 71 createFile(dir1.resolve(fileEntry)); 72 Path dirEntry = Paths.get("mydir"); 73 createDirectory(dir1.resolve(dirEntry)); 74 // myfilelink -> myfile 75 Path link1Entry = Paths.get("myfilelink"); 76 if (supportsLinks) 77 createSymbolicLink(dir1.resolve(link1Entry), fileEntry); 78 // mydirlink -> mydir 79 Path link2Entry = Paths.get("mydirlink"); 80 if (supportsLinks) 81 createSymbolicLink(dir1.resolve(link2Entry), dirEntry); 82 83 // open directory and then move it so that it is no longer accessible 84 // via its original path. 85 SecureDirectoryStream<Path> stream = 86 (SecureDirectoryStream<Path>)newDirectoryStream(dir1); 87 move(dir1, dir2); 88 89 // Test: iterate over all entries 90 int count = 0; 91 for (Path entry: stream) { count++; } 92 assertTrue(count == (supportsLinks ? 4 : 2)); 93 94 // Test: getFileAttributeView to access directory's attributes 95 assertTrue(stream 96 .getFileAttributeView(BasicFileAttributeView.class) 97 .readAttributes() 98 .isDirectory()); 99 100 // Test: getFileAttributeView to access attributes of entries 101 assertTrue(stream 102 .getFileAttributeView(fileEntry, BasicFileAttributeView.class) 103 .readAttributes() 104 .isRegularFile()); 105 assertTrue(stream 106 .getFileAttributeView(fileEntry, BasicFileAttributeView.class, NOFOLLOW_LINKS) 107 .readAttributes() 108 .isRegularFile()); 109 assertTrue(stream 110 .getFileAttributeView(dirEntry, BasicFileAttributeView.class) 111 .readAttributes() 112 .isDirectory()); 113 assertTrue(stream 114 .getFileAttributeView(dirEntry, BasicFileAttributeView.class, NOFOLLOW_LINKS) 115 .readAttributes() 116 .isDirectory()); 117 if (supportsLinks) { 118 assertTrue(stream 119 .getFileAttributeView(link1Entry, BasicFileAttributeView.class) 120 .readAttributes() 121 .isRegularFile()); 122 assertTrue(stream 123 .getFileAttributeView(link1Entry, BasicFileAttributeView.class, NOFOLLOW_LINKS) 124 .readAttributes() 125 .isSymbolicLink()); 126 assertTrue(stream 127 .getFileAttributeView(link2Entry, BasicFileAttributeView.class) 128 .readAttributes() 129 .isDirectory()); 130 assertTrue(stream 131 .getFileAttributeView(link2Entry, BasicFileAttributeView.class, NOFOLLOW_LINKS) 132 .readAttributes() 133 .isSymbolicLink()); 134 } 135 136 // Test: newByteChannel 137 Set<StandardOpenOption> opts = Collections.emptySet(); 138 stream.newByteChannel(fileEntry, opts).close(); 139 if (supportsLinks) { 140 stream.newByteChannel(link1Entry, opts).close(); 141 try { 142 Set<OpenOption> mixed = new HashSet<>(); 143 mixed.add(READ); 144 mixed.add(NOFOLLOW_LINKS); 145 stream.newByteChannel(link1Entry, mixed).close(); 146 shouldNotGetHere(); 147 } catch (IOException x) { } 148 } 149 150 // Test: newDirectoryStream 151 stream.newDirectoryStream(dirEntry).close(); 152 stream.newDirectoryStream(dirEntry, LinkOption.NOFOLLOW_LINKS).close(); 153 if (supportsLinks) { 154 stream.newDirectoryStream(link2Entry).close(); 155 try { 156 stream.newDirectoryStream(link2Entry, LinkOption.NOFOLLOW_LINKS) 157 .close(); 158 shouldNotGetHere(); 159 } catch (IOException x) { } 160 } 161 162 // Test: delete 163 if (supportsLinks) { 164 stream.deleteFile(link1Entry); 165 stream.deleteFile(link2Entry); 166 } 167 stream.deleteDirectory(dirEntry); 168 stream.deleteFile(fileEntry); 169 170 // clean-up 171 stream.close(); 172 delete(dir2); 173 } 174 175 // Exercise SecureDirectoryStream's move method 176 static void doMoveTests(Path dir) throws IOException { 177 Path dir1 = createDirectory(dir.resolve("dir1")); 178 Path dir2 = createDirectory(dir.resolve("dir2")); 179 180 // create dir1/myfile, dir1/mydir, dir1/mylink 181 Path fileEntry = Paths.get("myfile"); 182 createFile(dir1.resolve(fileEntry)); 183 Path dirEntry = Paths.get("mydir"); 184 createDirectory(dir1.resolve(dirEntry)); 185 Path linkEntry = Paths.get("mylink"); 186 if (supportsLinks) 187 createSymbolicLink(dir1.resolve(linkEntry), Paths.get("missing")); 188 189 // target name 190 Path target = Paths.get("newfile"); 191 192 // open stream to both directories 193 SecureDirectoryStream<Path> stream1 = 194 (SecureDirectoryStream<Path>)newDirectoryStream(dir1); 195 SecureDirectoryStream<Path> stream2 = 196 (SecureDirectoryStream<Path>)newDirectoryStream(dir2); 197 198 // Test: move dir1/myfile -> dir2/newfile 199 stream1.move(fileEntry, stream2, target); 200 assertTrue(notExists(dir1.resolve(fileEntry))); 201 assertTrue(exists(dir2.resolve(target))); 202 stream2.deleteFile(target); 203 204 // Test: move dir1/mydir -> dir2/newfile 205 stream1.move(dirEntry, stream2, target); 206 assertTrue(notExists(dir1.resolve(dirEntry))); 207 assertTrue(exists(dir2.resolve(target))); 208 stream2.deleteDirectory(target); 209 210 // Test: move dir1/mylink -> dir2/newfile 211 if (supportsLinks) { 212 stream1.move(linkEntry, stream2, target); 213 assertTrue(isSymbolicLink(dir2.resolve(target))); 214 stream2.deleteFile(target); 215 } 216 217 // Test: move between devices 218 String testDirAsString = System.getProperty("test.dir"); 219 if (testDirAsString != null) { 220 Path testDir = Paths.get(testDirAsString); 221 if (!getFileStore(dir1).equals(getFileStore(testDir))) { 222 SecureDirectoryStream<Path> ts = 223 (SecureDirectoryStream<Path>)newDirectoryStream(testDir); 224 createFile(dir1.resolve(fileEntry)); 225 try { 226 stream1.move(fileEntry, ts, target); 227 shouldNotGetHere(); 228 } catch (AtomicMoveNotSupportedException x) { } 229 ts.close(); 230 stream1.deleteFile(fileEntry); 231 } 232 } 233 234 // clean-up 235 delete(dir1); 236 delete(dir2); 237 } 238 239 // null and ClosedDirectoryStreamException 240 static void miscTests(Path dir) throws IOException { 241 Path file = Paths.get("file"); 242 createFile(dir.resolve(file)); 243 244 SecureDirectoryStream<Path> stream = 245 (SecureDirectoryStream<Path>)newDirectoryStream(dir); 246 247 // NullPointerException 248 try { 249 stream.getFileAttributeView(null); 250 shouldNotGetHere(); 251 } catch (NullPointerException x) { } 252 try { 253 stream.getFileAttributeView(null, BasicFileAttributeView.class); 254 shouldNotGetHere(); 255 } catch (NullPointerException x) { } 256 try { 257 stream.getFileAttributeView(file, null); 258 shouldNotGetHere(); 259 } catch (NullPointerException x) { } 260 try { 261 stream.newByteChannel(null, EnumSet.of(CREATE,WRITE)); 262 shouldNotGetHere(); 263 } catch (NullPointerException x) { } 264 try { 265 stream.newByteChannel(null, EnumSet.of(CREATE,WRITE,null)); 266 shouldNotGetHere(); 267 } catch (NullPointerException x) { } 268 try { 269 stream.newByteChannel(file, null); 270 shouldNotGetHere(); 271 } catch (NullPointerException x) { } 272 try { 273 stream.move(null, stream, file); 274 shouldNotGetHere(); 275 } catch (NullPointerException x) { } 276 try { 277 stream.move(file, null, file); 278 shouldNotGetHere(); 279 } catch (NullPointerException x) { } 280 try { 281 stream.move(file, stream, null); 282 shouldNotGetHere(); 283 } catch (NullPointerException x) { } 284 try { 285 stream.newDirectoryStream(null); 286 shouldNotGetHere(); 287 } catch (NullPointerException x) { } 288 try { 289 stream.deleteFile(null); 290 shouldNotGetHere(); 291 } catch (NullPointerException x) { } 292 try { 293 stream.deleteDirectory(null); 294 shouldNotGetHere(); 295 } catch (NullPointerException x) { } 296 297 // close stream 298 stream.close(); 299 stream.close(); // should be no-op 300 301 // ClosedDirectoryStreamException 302 try { 303 stream.newDirectoryStream(file); 304 shouldNotGetHere(); 305 } catch (ClosedDirectoryStreamException x) { } 306 try { 307 stream.newByteChannel(file, EnumSet.of(READ)); 308 shouldNotGetHere(); 309 } catch (ClosedDirectoryStreamException x) { } 310 try { 311 stream.move(file, stream, file); 312 shouldNotGetHere(); 313 } catch (ClosedDirectoryStreamException x) { } 314 try { 315 stream.deleteFile(file); 316 shouldNotGetHere(); 317 } catch (ClosedDirectoryStreamException x) { } 318 319 // clean-up 320 delete(dir.resolve(file)); 321 } 322 323 static void assertTrue(boolean b) { 324 if (!b) throw new RuntimeException("Assertion failed"); 325 } 326 327 static void shouldNotGetHere() { 328 assertTrue(false); 329 } 330 }