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