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