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