1 /* 2 * Copyright (c) 2012, 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 /* 25 * @test 26 * @bug 6244047 27 * @author Jim Gish 28 * @summary throw more precise IOException when pattern specifies invalid directory 29 * 30 * @run main/othervm CheckLockLocationTest 31 */ 32 import java.io.File; 33 import java.io.IOException; 34 import java.nio.file.AccessDeniedException; 35 import java.nio.file.FileSystemException; 36 import java.nio.file.Files; 37 import java.nio.file.NoSuchFileException; 38 import java.nio.file.Path; 39 import java.util.logging.FileHandler; 40 public class CheckLockLocationTest { 41 42 private static final String NON_WRITABLE_DIR = "non-writable-dir"; 43 private static final String NOT_A_DIR = "not-a-dir"; 44 private static final String WRITABLE_DIR = "writable-dir"; 45 private static final String NON_EXISTENT_DIR = "non-existent-dir"; 46 private static boolean runNonWritableDirTest; 47 48 public static void main(String... args) throws IOException { 49 // we'll base all file creation attempts on the system temp directory, 50 // %t and also try specifying non-existent directories and plain files 51 // that should be directories, and non-writable directories, 52 // to exercise all code paths of checking the lock location 53 // Note that on platforms like Windows that don't support 54 // setWritable() on a directory, we'll skip the non-writable 55 // directory test if setWritable(false) returns false. 56 // 57 File writableDir = setup(); 58 // we now have three files/directories to work with: 59 // writableDir 60 // notAdir 61 // nonWritableDir (may not be possible on some platforms) 62 // nonExistentDir (which doesn't exist) 63 runTests(writableDir); 64 } 65 66 /** 67 * @param writableDir in which log and lock file are created 68 * @throws SecurityException 69 * @throws RuntimeException 70 * @throws IOException 71 */ 72 private static void runTests(File writableDir) throws SecurityException, 73 RuntimeException, IOException { 74 // Test 1: make sure we can create FileHandler in writable directory 75 try { 76 new FileHandler("%t/" + WRITABLE_DIR + "/log.log"); 77 } catch (IOException ex) { 78 throw new RuntimeException("Test failed: should have been able" 79 + " to create FileHandler for " + "%t/" + WRITABLE_DIR 80 + "/log.log in writable directory.", ex); 81 } finally { 82 // the above test leaves files in the directory. Get rid of the 83 // files created and the directory 84 delete(writableDir); 85 } 86 87 // Test 2: creating FileHandler in non-writable directory should fail 88 if (runNonWritableDirTest) { 89 try { 90 new FileHandler("%t/" + NON_WRITABLE_DIR + "/log.log"); 91 throw new RuntimeException("Test failed: should not have been able" 92 + " to create FileHandler for " + "%t/" + NON_WRITABLE_DIR 93 + "/log.log in non-writable directory."); 94 } catch (AccessDeniedException ex) { 95 // the right exception was thrown, so continue. 96 } catch (IOException ex) { 97 throw new RuntimeException( 98 "Test failed: Expected exception was not an " 99 + "AccessDeniedException", ex); 100 } 101 } 102 103 // Test 3: creating FileHandler in non-directory should fail 104 try { 105 new FileHandler("%t/" + NOT_A_DIR + "/log.log"); 106 throw new RuntimeException("Test failed: should not have been able" 107 + " to create FileHandler for " + "%t/" + NOT_A_DIR 108 + "/log.log in non-directory."); 109 } catch (FileSystemException ex) { 110 // the right exception was thrown, so continue. 111 } catch (IOException ex) { 112 throw new RuntimeException("Test failed: exception thrown was not a " 113 + "FileSystemException", ex); 114 } 115 116 // Test 4: make sure we can't create a FileHandler in a non-existent dir 117 try { 118 new FileHandler("%t/" + NON_EXISTENT_DIR + "/log.log"); 119 throw new RuntimeException("Test failed: should not have been able" 120 + " to create FileHandler for " + "%t/" + NON_EXISTENT_DIR 121 + "/log.log in a non-existent directory."); 122 } catch (NoSuchFileException ex) { 123 // the right exception was thrown, so continue. 124 } catch (IOException ex) { 125 throw new RuntimeException("Test failed: Expected exception " 126 + "was not a NoSuchFileException", ex); 127 } 128 } 129 130 /** 131 * Setup all the files and directories needed for the tests 132 * 133 * @return writable directory created that needs to be deleted when done 134 * @throws RuntimeException 135 */ 136 private static File setup() throws RuntimeException { 137 // First do some setup in the temporary directory (using same logic as 138 // FileHandler for %t pattern) 139 String tmpDir = System.getProperty("java.io.tmpdir"); // i.e. %t 140 if (tmpDir == null) { 141 tmpDir = System.getProperty("user.home"); 142 } 143 File tmpOrHomeDir = new File(tmpDir); 144 // Create a writable directory here (%t/writable-dir) 145 File writableDir = new File(tmpOrHomeDir, WRITABLE_DIR); 146 if (!createFile(writableDir, true)) { 147 throw new RuntimeException("Test setup failed: unable to create" 148 + " writable working directory " 149 + writableDir.getAbsolutePath() ); 150 } 151 // writableDirectory and its contents will be deleted after the test 152 // that uses it 153 154 // Create a plain file which we will attempt to use as a directory 155 // (%t/not-a-dir) 156 File notAdir = new File(tmpOrHomeDir, NOT_A_DIR); 157 if (!createFile(notAdir, false)) { 158 throw new RuntimeException("Test setup failed: unable to a plain" 159 + " working file " + notAdir.getAbsolutePath() ); 160 } 161 notAdir.deleteOnExit(); 162 163 // Create a non-writable directory (%t/non-writable-dir) 164 File nonWritableDir = new File(tmpOrHomeDir, NON_WRITABLE_DIR); 165 if (!createFile(nonWritableDir, true)) { 166 throw new RuntimeException("Test setup failed: unable to create" 167 + " a non-" 168 + "writable working directory " 169 + nonWritableDir.getAbsolutePath() ); 170 } 171 nonWritableDir.deleteOnExit(); 172 173 // make it non-writable 174 Path path = nonWritableDir.toPath(); 175 final boolean nonWritable = nonWritableDir.setWritable(false); 176 final boolean isWritable = Files.isWritable(path); 177 if (nonWritable && !isWritable) { 178 runNonWritableDirTest = true; 179 System.out.println("Created non writable dir at: " + path.toString()); 180 } else { 181 runNonWritableDirTest = false; 182 System.out.println( "Test Setup WARNING: unable to make" 183 + " working directory " + nonWritableDir.getAbsolutePath() 184 + " non-writable on platform " + System.getProperty("os.name")); 185 186 } 187 188 // make sure non-existent directory really doesn't exist 189 File nonExistentDir = new File(tmpOrHomeDir, NON_EXISTENT_DIR); 190 if (nonExistentDir.exists()) { 191 nonExistentDir.delete(); 192 } 193 System.out.println("Setup completed - writableDir is: " + writableDir.getPath()); 194 return writableDir; 195 } 196 197 /** 198 * @param newFile 199 * @return true if file already exists or creation succeeded 200 */ 201 private static boolean createFile(File newFile, boolean makeDirectory) { 202 if (newFile.exists()) { 203 return true; 204 } 205 if (makeDirectory) { 206 return newFile.mkdir(); 207 } else { 208 try { 209 return newFile.createNewFile(); 210 } catch (IOException ioex) { 211 ioex.printStackTrace(); 212 return false; 213 } 214 } 215 } 216 217 /* 218 * Recursively delete all files starting at specified file 219 */ 220 private static void delete(File f) { 221 if (f != null && f.isDirectory()) { 222 for (File c : f.listFiles()) 223 delete(c); 224 } 225 if (!f.delete()) 226 System.err.println( 227 "WARNING: unable to delete/cleanup writable test directory: " 228 + f ); 229 } 230 }