blob: 345c3384668bb1042c0b2703f7f34f6ddbf2473d [file] [log] [blame]
duke6e45e102007-12-01 00:00:00 +00001/*
2 * Copyright 2005-2006 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/**
25 * @test
26 * @bug 4057701 6286712 6364377
ohairbcda26e2009-03-31 16:14:14 -070027 * @ignore until 6492634 and 6501010 is fixed
duke6e45e102007-12-01 00:00:00 +000028 * @run build GetXSpace
29 * @run shell GetXSpace.sh
30 * @summary Basic functionality of File.get-X-Space methods.
31 */
32
33import java.io.BufferedReader;
34import java.io.File;
35import java.io.FilePermission;
36import java.io.InputStreamReader;
37import java.io.IOException;
38import java.security.Permission;
39import java.util.ArrayList;
40import java.util.regex.Matcher;
41import java.util.regex.Pattern;
42
43import static java.lang.System.out;
44
45public class GetXSpace {
46
47 private static SecurityManager [] sma = { null, new Allow(), new DenyFSA(),
48 new DenyRead() };
49
50 private static final String name = System.getProperty("os.name");
51 private static final String dfFormat;
52 static {
53 if (name.equals("SunOS") || name.equals("Linux")) {
54 // FileSystem Total Used Available Use% MountedOn
55 dfFormat = "([^\\s]+)\\s+(\\d+)\\s+\\d+\\s+(\\d+)\\s+\\d+%\\s+([^\\s]+)";
56 } else if (name.startsWith("Windows")) {
57 // Drive (MountedOn) Available/Total
58 dfFormat = "([^\\s]+)\\s+\\(([^\\s]+)\\)\\s+(\\d+)\\/(\\d+)\\s+";
59 } else {
60 throw new RuntimeException("unrecognized system:"
61 + " os.name == " + name);
62 }
63 }
64 private static Pattern dfPattern = Pattern.compile(dfFormat);
65
66 private static int fail = 0;
67 private static int pass = 0;
68 private static Throwable first;
69
70 static void pass() {
71 pass++;
72 }
73
74 static void fail(String p) {
75 if (first == null)
76 setFirst(p);
77 System.err.format("FAILED: %s%n", p);
78 fail++;
79 }
80
81 static void fail(String p, long exp, String cmp, long got) {
82 String s = String.format("'%s': %d %s %d", p, exp, cmp, got);
83 if (first == null)
84 setFirst(s);
85 System.err.format("FAILED: %s%n", s);
86 fail++;
87 }
88
89 private static void fail(String p, Class ex) {
90 String s = String.format("'%s': expected %s - FAILED%n", p, ex.getName());
91 if (first == null)
92 setFirst(s);
93 System.err.format("FAILED: %s%n", s);
94 fail++;
95 }
96
97 private static void setFirst(String s) {
98 try {
99 throw new RuntimeException(s);
100 } catch (RuntimeException x) {
101 first = x;
102 }
103 }
104
105 private static class Space {
106 private static final long KSIZE = 1024;
107 private String name;
108 private long total;
109 private long free;
110
111 Space(String total, String free, String name) {
112 try {
113 this.total = Long.valueOf(total) * KSIZE;
114 this.free = Long.valueOf(free) * KSIZE;
115 } catch (NumberFormatException x) {
116 // the regex should have caught this
117 assert false;
118 }
119 this.name = name;
120 }
121
122 String name() { return name; }
123 long total() { return total; }
124 long free() { return free; }
125 boolean woomFree(long freeSpace) {
126 return ((freeSpace >= (free / 10)) && (freeSpace <= (free * 10)));
127 }
128 public String toString() {
129 return String.format("%s (%d/%d)", name, free, total);
130 }
131 }
132
133 private static ArrayList space(String f) throws IOException {
134 ArrayList al = new ArrayList();
135
136 Process p = null;
137 String cmd = "df -k" + (f == null ? "" : " " + f);
138 p = Runtime.getRuntime().exec(cmd);
139 BufferedReader in = new BufferedReader
140 (new InputStreamReader(p.getInputStream()));
141 String s;
142 int i = 0;
143 StringBuilder sb = new StringBuilder();
144 while ((s = in.readLine()) != null) {
145 // skip header
146 if (i++ == 0 && !name.startsWith("Windows")) continue;
147 sb.append(s).append("\n");
148 }
149
150 Matcher m = dfPattern.matcher(sb);
151 int j = 0;
152 while (j < sb.length()) {
153 if (m.find(j)) {
154 if (!name.startsWith("Windows")) {
155 // swap can change while this test is running
156 if (!m.group(1).equals("swap")) {
157 String name = (f == null ? m.group(4): f);
158 al.add(new Space(m.group(2), m.group(3), name));;
159 }
160 } else {
161 String name = (f == null ? m.group(2) : f);
162 al.add(new Space(m.group(4), m.group(3), name ));;
163 }
164 j = m.end() + 1;
165 } else {
166 throw new RuntimeException("unrecognized df output format: "
167 + "charAt(" + j + ") = '"
168 + sb.charAt(j) + "'");
169 }
170 }
171
172 if (al.size() == 0) {
173 // df did not produce output
174 String name = (f == null ? "" : f);
175 al.add(new Space("0", "0", name));
176 }
177 in.close();
178 return al;
179 }
180
181 private static void tryCatch(Space s) {
182 out.format("%s:%n", s.name());
183 File f = new File(s.name());
184 SecurityManager sm = System.getSecurityManager();
185 if (sm instanceof Deny) {
186 String fmt = " %14s: \"%s\" thrown as expected%n";
187 try {
188 f.getTotalSpace();
189 fail(s.name(), SecurityException.class);
190 } catch (SecurityException x) {
191 out.format(fmt, "getTotalSpace", x);
192 pass();
193 }
194 try {
195 f.getFreeSpace();
196 fail(s.name(), SecurityException.class);
197 } catch (SecurityException x) {
198 out.format(fmt, "getFreeSpace", x);
199 pass();
200 }
201 try {
202 f.getUsableSpace();
203 fail(s.name(), SecurityException.class);
204 } catch (SecurityException x) {
205 out.format(fmt, "getUsableSpace", x);
206 pass();
207 }
208 }
209 }
210
211 private static void compare(Space s) {
212 File f = new File(s.name());
213 long ts = f.getTotalSpace();
214 long fs = f.getFreeSpace();
215 long us = f.getUsableSpace();
216
217 out.format("%s:%n", s.name());
218 String fmt = " %-4s total= %12d free = %12d usable = %12d%n";
219 out.format(fmt, "df", s.total(), 0, s.free());
220 out.format(fmt, "getX", ts, fs, us);
221
222 // if the file system can dynamically change size, this check will fail
223 if (ts != s.total())
224 fail(s.name(), s.total(), "!=", ts);
225 else
226 pass();
227
228 // unix df returns statvfs.f_bavail
229 long tsp = (!name.startsWith("Windows") ? us : fs);
230 if (!s.woomFree(tsp))
231 fail(s.name(), s.free(), "??", tsp);
232 else
233 pass();
234
235 if (fs > s.total())
236 fail(s.name(), s.total(), ">", fs);
237 else
238 pass();
239
240 if (us > s.total())
241 fail(s.name(), s.total(), ">", us);
242 else
243 pass();
244 }
245
246 private static String FILE_PREFIX = "/getSpace.";
247 private static void compareZeroNonExist() {
248 File f;
249 while (true) {
250 f = new File(FILE_PREFIX + Math.random());
251 if (f.exists())
252 continue;
253 break;
254 }
255
256 long [] s = { f.getTotalSpace(), f.getFreeSpace(), f.getUsableSpace() };
257
258 for (int i = 0; i < s.length; i++) {
259 if (s[i] != 0L)
260 fail(f.getName(), s[i], "!=", 0L);
261 else
262 pass();
263 }
264 }
265
266 private static void compareZeroExist() {
267 try {
268 File f = File.createTempFile("tmp", null, new File("."));
269
270 long [] s = { f.getTotalSpace(), f.getFreeSpace(), f.getUsableSpace() };
271
272 for (int i = 0; i < s.length; i++) {
273 if (s[i] == 0L)
274 fail(f.getName(), s[i], "==", 0L);
275 else
276 pass();
277 }
278 } catch (IOException x) {
279 fail("Couldn't create temp file for test");
280 }
281 }
282
283 private static class Allow extends SecurityManager {
284 public void checkRead(String file) {}
285 public void checkPermission(Permission p) {}
286 public void checkPermission(Permission p, Object context) {}
287 }
288
289 private static class Deny extends SecurityManager {
290 public void checkPermission(Permission p) {
291 if (p.implies(new RuntimePermission("setSecurityManager"))
292 || p.implies(new RuntimePermission("getProtectionDomain")))
293 return;
294 super.checkPermission(p);
295 }
296
297 public void checkPermission(Permission p, Object context) {
298 if (p.implies(new RuntimePermission("setSecurityManager"))
299 || p.implies(new RuntimePermission("getProtectionDomain")))
300 return;
301 super.checkPermission(p, context);
302 }
303 }
304
305 private static class DenyFSA extends Deny {
306 private String err = "sorry - getFileSystemAttributes";
307
308 public void checkPermission(Permission p) {
309 if (p.implies(new RuntimePermission("getFileSystemAttributes")))
310 throw new SecurityException(err);
311 super.checkPermission(p);
312 }
313
314 public void checkPermission(Permission p, Object context) {
315 if (p.implies(new RuntimePermission("getFileSystemAttributes")))
316 throw new SecurityException(err);
317 super.checkPermission(p, context);
318 }
319 }
320
321 private static class DenyRead extends Deny {
322 private String err = "sorry - checkRead()";
323
324 public void checkRead(String file) {
325 throw new SecurityException(err);
326 }
327 }
328
329 private static void testFile(String dirName) {
330 out.format("--- Testing %s%n", dirName);
331 ArrayList l;
332 try {
333 l = space(dirName);
334 } catch (IOException x) {
335 throw new RuntimeException(dirName + " can't get file system information", x);
336 }
337 compare((GetXSpace.Space) l.get(0));
338 }
339
340 private static void testDF() {
341 out.format("--- Testing df");
342 // Find all of the partitions on the machine and verify that the size
343 // returned by "df" is equivalent to File.getXSpace() values.
344 ArrayList l;
345 try {
346 l = space(null);
347 } catch (IOException x) {
348 throw new RuntimeException("can't get file system information", x);
349 }
350 if (l.size() == 0)
351 throw new RuntimeException("no partitions?");
352
353 for (int i = 0; i < sma.length; i++) {
354 System.setSecurityManager(sma[i]);
355 SecurityManager sm = System.getSecurityManager();
356 if (sma[i] != null && sm == null)
357 throw new RuntimeException("Test configuration error "
358 + " - can't set security manager");
359
360 out.format("%nSecurityManager = %s%n" ,
361 (sm == null ? "null" : sm.getClass().getName()));
362 for (int j = 0; j < l.size(); j++) {
363 Space s = (GetXSpace.Space) l.get(j);
364 if (sm instanceof Deny) {
365 tryCatch(s);
366 } else {
367 compare(s);
368 compareZeroNonExist();
369 compareZeroExist();
370 }
371 }
372 }
373 }
374
375 public static void main(String [] args) {
376 if (args.length > 0) {
377 testFile(args[0]);
378 } else {
379 testDF();
380 }
381
382 if (fail != 0)
383 throw new RuntimeException((fail + pass) + " tests: "
384 + fail + " failure(s), first", first);
385 else
386 out.format("all %d tests passed%n", fail + pass);
387 }
388}