J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright 2002-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| 20 | * CA 95054 USA or visit www.sun.com if you need additional information or |
| 21 | * have any questions. |
| 22 | */ |
| 23 | |
| 24 | /* @test |
| 25 | @bug 4759207 4403166 4165006 4403166 6182812 6274272 |
| 26 | @summary Test to see if win32 path length can be greater than 260 |
| 27 | */ |
| 28 | |
| 29 | import java.io.*; |
| 30 | |
| 31 | public class MaxPathLength { |
| 32 | private static String sep = File.separator; |
| 33 | private static String pathComponent = sep + |
| 34 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; |
| 35 | private static String fileName = |
| 36 | "areallylongfilenamethatsforsur"; |
| 37 | private static boolean isWindows = false; |
| 38 | private static long totalSpace; |
| 39 | private static long freeSpace; |
| 40 | private static long usableSpace; |
| 41 | private static long ONEMEGA = 1024*1024; |
| 42 | |
| 43 | public static void main(String[] args) throws Exception { |
| 44 | String osName = System.getProperty("os.name"); |
| 45 | if (osName.startsWith("Windows")) { |
| 46 | isWindows = true; |
| 47 | if (osName.startsWith("Windows 9") || |
| 48 | osName.startsWith("Windows Me")) |
| 49 | return; // win9x/Me cannot handle long paths |
| 50 | } |
| 51 | |
| 52 | if (osName.startsWith("SunOS")) { |
| 53 | return; // We don't run this test on Solaris either. |
| 54 | // Some Solaris machines have very "slow" disk |
| 55 | // access performance which causes this one |
| 56 | // to timeout. |
| 57 | } |
| 58 | |
| 59 | if (isWindows) { |
| 60 | File f = new File("."); |
| 61 | totalSpace = f.getTotalSpace()/ONEMEGA; |
| 62 | freeSpace = f.getFreeSpace()/ONEMEGA; |
| 63 | usableSpace = f.getUsableSpace()/ONEMEGA; |
| 64 | } |
| 65 | |
| 66 | for (int i = 4; i < 7; i++) { |
| 67 | String name = fileName; |
| 68 | while (name.length() < 256) { |
| 69 | testLongPath (i, name, false); |
| 70 | testLongPath (i, name, true); |
| 71 | name += "A"; |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | // Testing below will not be run if "-extra" is not |
| 76 | if (args.length == 0 || |
| 77 | !"-extra".equals(args[0]) || |
| 78 | !isWindows) |
| 79 | return; |
| 80 | |
| 81 | /* Testings below should not be run on a remote |
| 82 | dir that exists on a Solaris machine */ |
| 83 | for (int i = 20; i < 21; i++) { |
| 84 | String name = fileName; |
| 85 | while (name.length() < 256) { |
| 86 | testLongPath (i, name, false); |
| 87 | testLongPath (i, name, true); |
| 88 | name += "A"; |
| 89 | } |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | private static int lastMax = 0; |
| 94 | static void testLongPath(int max, String fn, |
| 95 | boolean tryAbsolute) throws Exception { |
| 96 | String[] created = new String[max]; |
| 97 | String pathString = "."; |
| 98 | for (int i = 0; i < max -1; i++) { |
| 99 | pathString = pathString + pathComponent; |
| 100 | created[max - 1 -i] = pathString; |
| 101 | |
| 102 | } |
| 103 | File dirFile = new File(pathString); |
| 104 | File f = new File(pathString + sep + fn); |
| 105 | |
| 106 | String tPath = f.getPath(); |
| 107 | if (tryAbsolute) { |
| 108 | tPath = f.getCanonicalPath(); |
| 109 | } |
| 110 | created[0] = tPath; |
| 111 | |
| 112 | //for getCanonicalPath testing on win32 |
| 113 | File fu = new File(pathString + sep + fn.toUpperCase()); |
| 114 | |
| 115 | if (dirFile.exists()) { |
| 116 | System.err.println("Warning: Test directory structure exists already!"); |
| 117 | return; |
| 118 | } |
| 119 | boolean couldMakeTestDirectory = dirFile.mkdirs(); |
| 120 | if (!couldMakeTestDirectory) { |
| 121 | throw new RuntimeException ("Could not create test directory structure"); |
| 122 | } |
| 123 | try { |
| 124 | if (tryAbsolute) |
| 125 | dirFile = new File(dirFile.getCanonicalPath()); |
| 126 | if (!dirFile.isDirectory()) |
| 127 | throw new RuntimeException ("File.isDirectory() failed"); |
| 128 | if (isWindows && lastMax != max) { |
| 129 | long diff = totalSpace - dirFile.getTotalSpace()/ONEMEGA; |
| 130 | if (diff < -5 || diff > 5) |
| 131 | throw new RuntimeException ("File.getTotalSpace() failed"); |
| 132 | diff = freeSpace - dirFile.getFreeSpace()/ONEMEGA; |
| 133 | if (diff < -5 || diff > 5) |
| 134 | throw new RuntimeException ("File.getFreeSpace() failed"); |
| 135 | diff = usableSpace - dirFile.getUsableSpace()/ONEMEGA; |
| 136 | if (diff < -5 || diff > 5) |
| 137 | throw new RuntimeException ("File.getUsableSpace() failed"); |
| 138 | lastMax = max; |
| 139 | } |
| 140 | f = new File(tPath); |
| 141 | if (!f.createNewFile()) { |
| 142 | throw new RuntimeException ("File.createNewFile() failed"); |
| 143 | } |
| 144 | if (!f.exists()) |
| 145 | throw new RuntimeException ("File.exists() failed"); |
| 146 | if (!f.isFile()) |
| 147 | throw new RuntimeException ("File.isFile() failed"); |
| 148 | if (!f.canRead()) |
| 149 | throw new RuntimeException ("File.canRead() failed"); |
| 150 | if (!f.canWrite()) |
| 151 | throw new RuntimeException ("File.canWrite() failed"); |
| 152 | if (!f.delete()) |
| 153 | throw new RuntimeException ("File.delete() failed"); |
| 154 | FileOutputStream fos = new FileOutputStream(f); |
| 155 | fos.write(1); |
| 156 | fos.close(); |
| 157 | if (f.length() != 1) |
| 158 | throw new RuntimeException ("File.length() failed"); |
| 159 | long time = System.currentTimeMillis(); |
| 160 | if (!f.setLastModified(time)) |
| 161 | throw new RuntimeException ("File.setLastModified() failed"); |
| 162 | if (f.lastModified() == 0) { |
| 163 | throw new RuntimeException ("File.lastModified() failed"); |
| 164 | } |
| 165 | String[] list = dirFile.list(); |
| 166 | if (list == null || !fn.equals(list[0])) { |
| 167 | throw new RuntimeException ("File.list() failed"); |
| 168 | } |
| 169 | |
| 170 | File[] flist = dirFile.listFiles(); |
| 171 | if (flist == null || !fn.equals(flist[0].getName())) |
| 172 | throw new RuntimeException ("File.listFiles() failed"); |
| 173 | |
| 174 | if (isWindows && |
| 175 | !fu.getCanonicalPath().equals(f.getCanonicalPath())) |
| 176 | throw new RuntimeException ("getCanonicalPath() failed"); |
| 177 | |
| 178 | char[] cc = tPath.toCharArray(); |
| 179 | cc[cc.length-1] = 'B'; |
| 180 | File nf = new File(new String(cc)); |
| 181 | if (!f.renameTo(nf)) { |
| 182 | /*there is a known issue that renameTo fails if |
| 183 | (1)the path is a UNC path and |
| 184 | (2)the path length is bigger than 1092 |
| 185 | so don't stop if above are true |
| 186 | */ |
| 187 | String abPath = f.getAbsolutePath(); |
| 188 | if (!abPath.startsWith("\\\\") || |
| 189 | abPath.length() < 1093) { |
| 190 | throw new RuntimeException ("File.renameTo() failed for lenth=" |
| 191 | + abPath.length()); |
| 192 | } |
| 193 | return; |
| 194 | } |
| 195 | if (!nf.canRead()) |
| 196 | throw new RuntimeException ("Renamed file is not readable"); |
| 197 | if (!nf.canWrite()) |
| 198 | throw new RuntimeException ("Renamed file is not writable"); |
| 199 | if (nf.length() != 1) |
| 200 | throw new RuntimeException ("Renamed file's size is not correct"); |
| 201 | nf.renameTo(f); |
| 202 | /* add a script to test these two if we got a regression later |
| 203 | if (!f.setReadOnly()) |
| 204 | throw new RuntimeException ("File.setReadOnly() failed"); |
| 205 | f.deleteOnExit(); |
| 206 | */ |
| 207 | } finally { |
| 208 | // Clean up |
| 209 | for (int i = 0; i < max; i++) { |
| 210 | pathString = created[i]; |
| 211 | // Only works with completex canonical paths |
| 212 | File df = new File(pathString); |
| 213 | pathString = df.getCanonicalPath(); |
| 214 | df = new File(pathString); |
| 215 | if (!df.delete()) |
| 216 | System.out.printf("Delete failed->%s\n", pathString); |
| 217 | } |
| 218 | } |
| 219 | } |
| 220 | } |