1 /* |
1 /* |
2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
935 pb.redirectError(efile); |
935 pb.redirectError(efile); |
936 equal(pb.redirectError().file(), efile); |
936 equal(pb.redirectError().file(), efile); |
937 equal(pb.redirectError(), Redirect.to(efile)); |
937 equal(pb.redirectError(), Redirect.to(efile)); |
938 |
938 |
939 THROWS(IllegalArgumentException.class, |
939 THROWS(IllegalArgumentException.class, |
940 new Fun(){void f() { |
940 () -> pb.redirectInput(Redirect.to(ofile)), |
941 pb.redirectInput(Redirect.to(ofile)); }}, |
941 () -> pb.redirectOutput(Redirect.from(ifile)), |
942 new Fun(){void f() { |
942 () -> pb.redirectError(Redirect.from(ifile))); |
943 pb.redirectInput(Redirect.appendTo(ofile)); }}, |
|
944 new Fun(){void f() { |
|
945 pb.redirectOutput(Redirect.from(ifile)); }}, |
|
946 new Fun(){void f() { |
|
947 pb.redirectError(Redirect.from(ifile)); }}); |
|
948 |
943 |
949 THROWS(IOException.class, |
944 THROWS(IOException.class, |
950 // Input file does not exist |
945 // Input file does not exist |
951 new Fun(){void f() throws Throwable { pb.start(); }}); |
946 () -> pb.start()); |
952 setFileContents(ifile, "standard input"); |
947 setFileContents(ifile, "standard input"); |
953 |
948 |
954 //---------------------------------------------------------------- |
949 //---------------------------------------------------------------- |
955 // Writing to non-existent files |
950 // Writing to non-existent files |
956 //---------------------------------------------------------------- |
951 //---------------------------------------------------------------- |
1082 = new FilePermission("<<ALL FILES>>", "write,execute"); |
1077 = new FilePermission("<<ALL FILES>>", "write,execute"); |
1083 final Permission rwxPermission |
1078 final Permission rwxPermission |
1084 = new FilePermission("<<ALL FILES>>", "read,write,execute"); |
1079 = new FilePermission("<<ALL FILES>>", "read,write,execute"); |
1085 |
1080 |
1086 THROWS(SecurityException.class, |
1081 THROWS(SecurityException.class, |
1087 new Fun() { void f() throws IOException { |
1082 () -> { policy.setPermissions(xPermission); |
1088 policy.setPermissions(xPermission); |
1083 redirectIO(pb, from(tmpFile), PIPE, PIPE); |
1089 redirectIO(pb, from(tmpFile), PIPE, PIPE); |
1084 pb.start();}, |
1090 pb.start();}}, |
1085 () -> { policy.setPermissions(rxPermission); |
1091 new Fun() { void f() throws IOException { |
1086 redirectIO(pb, PIPE, to(ofile), PIPE); |
1092 policy.setPermissions(rxPermission); |
1087 pb.start();}, |
1093 redirectIO(pb, PIPE, to(ofile), PIPE); |
1088 () -> { policy.setPermissions(rxPermission); |
1094 pb.start();}}, |
1089 redirectIO(pb, PIPE, PIPE, to(efile)); |
1095 new Fun() { void f() throws IOException { |
1090 pb.start();}); |
1096 policy.setPermissions(rxPermission); |
|
1097 redirectIO(pb, PIPE, PIPE, to(efile)); |
|
1098 pb.start();}}); |
|
1099 |
1091 |
1100 { |
1092 { |
1101 policy.setPermissions(rxPermission); |
1093 policy.setPermissions(rxPermission); |
1102 redirectIO(pb, from(tmpFile), PIPE, PIPE); |
1094 redirectIO(pb, from(tmpFile), PIPE, PIPE); |
1103 ProcessResults r = run(pb); |
1095 ProcessResults r = run(pb); |
1256 |
1248 |
1257 //---------------------------------------------------------------- |
1249 //---------------------------------------------------------------- |
1258 // System.getenv() is read-only. |
1250 // System.getenv() is read-only. |
1259 //---------------------------------------------------------------- |
1251 //---------------------------------------------------------------- |
1260 THROWS(UnsupportedOperationException.class, |
1252 THROWS(UnsupportedOperationException.class, |
1261 new Fun(){void f(){ getenv().put("FOO","BAR");}}, |
1253 () -> getenv().put("FOO","BAR"), |
1262 new Fun(){void f(){ getenv().remove("PATH");}}, |
1254 () -> getenv().remove("PATH"), |
1263 new Fun(){void f(){ getenv().keySet().remove("PATH");}}, |
1255 () -> getenv().keySet().remove("PATH"), |
1264 new Fun(){void f(){ getenv().values().remove("someValue");}}); |
1256 () -> getenv().values().remove("someValue")); |
1265 |
1257 |
1266 try { |
1258 try { |
1267 Collection<Map.Entry<String,String>> c = getenv().entrySet(); |
1259 Collection<Map.Entry<String,String>> c = getenv().entrySet(); |
1268 if (! c.isEmpty()) |
1260 if (! c.isEmpty()) |
1269 try { |
1261 try { |
1284 // or an env var name or value containing NUL. |
1276 // or an env var name or value containing NUL. |
1285 //---------------------------------------------------------------- |
1277 //---------------------------------------------------------------- |
1286 { |
1278 { |
1287 final Map<String,String> m = new ProcessBuilder().environment(); |
1279 final Map<String,String> m = new ProcessBuilder().environment(); |
1288 THROWS(IllegalArgumentException.class, |
1280 THROWS(IllegalArgumentException.class, |
1289 new Fun(){void f(){ m.put("FOO=","BAR");}}, |
1281 () -> m.put("FOO=","BAR"), |
1290 new Fun(){void f(){ m.put("FOO\u0000","BAR");}}, |
1282 () -> m.put("FOO\u0000","BAR"), |
1291 new Fun(){void f(){ m.put("FOO","BAR\u0000");}}); |
1283 () -> m.put("FOO","BAR\u0000")); |
1292 } |
1284 } |
1293 |
1285 |
1294 //---------------------------------------------------------------- |
1286 //---------------------------------------------------------------- |
1295 // Commands must never be null. |
1287 // Commands must never be null. |
1296 //---------------------------------------------------------------- |
1288 //---------------------------------------------------------------- |
1297 THROWS(NullPointerException.class, |
1289 THROWS(NullPointerException.class, |
1298 new Fun(){void f(){ |
1290 () -> new ProcessBuilder((List<String>)null), |
1299 new ProcessBuilder((List<String>)null);}}, |
1291 () -> new ProcessBuilder().command((List<String>)null)); |
1300 new Fun(){void f(){ |
|
1301 new ProcessBuilder().command((List<String>)null);}}); |
|
1302 |
1292 |
1303 //---------------------------------------------------------------- |
1293 //---------------------------------------------------------------- |
1304 // Put in a command; get the same one back out. |
1294 // Put in a command; get the same one back out. |
1305 //---------------------------------------------------------------- |
1295 //---------------------------------------------------------------- |
1306 try { |
1296 try { |
1321 |
1311 |
1322 //---------------------------------------------------------------- |
1312 //---------------------------------------------------------------- |
1323 // Commands must contain at least one element. |
1313 // Commands must contain at least one element. |
1324 //---------------------------------------------------------------- |
1314 //---------------------------------------------------------------- |
1325 THROWS(IndexOutOfBoundsException.class, |
1315 THROWS(IndexOutOfBoundsException.class, |
1326 new Fun() { void f() throws IOException { |
1316 () -> new ProcessBuilder().start(), |
1327 new ProcessBuilder().start();}}, |
1317 () -> new ProcessBuilder(new ArrayList<String>()).start(), |
1328 new Fun() { void f() throws IOException { |
1318 () -> Runtime.getRuntime().exec(new String[]{})); |
1329 new ProcessBuilder(new ArrayList<String>()).start();}}, |
|
1330 new Fun() { void f() throws IOException { |
|
1331 Runtime.getRuntime().exec(new String[]{});}}); |
|
1332 |
1319 |
1333 //---------------------------------------------------------------- |
1320 //---------------------------------------------------------------- |
1334 // Commands must not contain null elements at start() time. |
1321 // Commands must not contain null elements at start() time. |
1335 //---------------------------------------------------------------- |
1322 //---------------------------------------------------------------- |
1336 THROWS(NullPointerException.class, |
1323 THROWS(NullPointerException.class, |
1337 new Fun() { void f() throws IOException { |
1324 () -> new ProcessBuilder("foo",null,"bar").start(), |
1338 new ProcessBuilder("foo",null,"bar").start();}}, |
1325 () -> new ProcessBuilder((String)null).start(), |
1339 new Fun() { void f() throws IOException { |
1326 () -> new ProcessBuilder(new String[]{null}).start(), |
1340 new ProcessBuilder((String)null).start();}}, |
1327 () -> new ProcessBuilder(new String[]{"foo",null,"bar"}).start()); |
1341 new Fun() { void f() throws IOException { |
|
1342 new ProcessBuilder(new String[]{null}).start();}}, |
|
1343 new Fun() { void f() throws IOException { |
|
1344 new ProcessBuilder(new String[]{"foo",null,"bar"}).start();}}); |
|
1345 |
1328 |
1346 //---------------------------------------------------------------- |
1329 //---------------------------------------------------------------- |
1347 // Command lists are growable. |
1330 // Command lists are growable. |
1348 //---------------------------------------------------------------- |
1331 //---------------------------------------------------------------- |
1349 try { |
1332 try { |
1356 // Nulls in environment updates generate NullPointerException |
1339 // Nulls in environment updates generate NullPointerException |
1357 //---------------------------------------------------------------- |
1340 //---------------------------------------------------------------- |
1358 try { |
1341 try { |
1359 final Map<String,String> env = new ProcessBuilder().environment(); |
1342 final Map<String,String> env = new ProcessBuilder().environment(); |
1360 THROWS(NullPointerException.class, |
1343 THROWS(NullPointerException.class, |
1361 new Fun(){void f(){ env.put("foo",null);}}, |
1344 () -> env.put("foo",null), |
1362 new Fun(){void f(){ env.put(null,"foo");}}, |
1345 () -> env.put(null,"foo"), |
1363 new Fun(){void f(){ env.remove(null);}}, |
1346 () -> env.remove(null), |
1364 new Fun(){void f(){ |
1347 () -> { for (Map.Entry<String,String> e : env.entrySet()) |
1365 for (Map.Entry<String,String> e : env.entrySet()) |
1348 e.setValue(null);}, |
1366 e.setValue(null);}}, |
1349 () -> Runtime.getRuntime().exec(new String[]{"foo"}, |
1367 new Fun() { void f() throws IOException { |
1350 new String[]{null})); |
1368 Runtime.getRuntime().exec(new String[]{"foo"}, |
|
1369 new String[]{null});}}); |
|
1370 } catch (Throwable t) { unexpected(t); } |
1351 } catch (Throwable t) { unexpected(t); } |
1371 |
1352 |
1372 //---------------------------------------------------------------- |
1353 //---------------------------------------------------------------- |
1373 // Non-String types in environment updates generate ClassCastException |
1354 // Non-String types in environment updates generate ClassCastException |
1374 //---------------------------------------------------------------- |
1355 //---------------------------------------------------------------- |
1375 try { |
1356 try { |
1376 final Map<String,String> env = new ProcessBuilder().environment(); |
1357 final Map<String,String> env = new ProcessBuilder().environment(); |
1377 THROWS(ClassCastException.class, |
1358 THROWS(ClassCastException.class, |
1378 new Fun(){void f(){ env.remove(TRUE);}}, |
1359 () -> env.remove(TRUE), |
1379 new Fun(){void f(){ env.keySet().remove(TRUE);}}, |
1360 () -> env.keySet().remove(TRUE), |
1380 new Fun(){void f(){ env.values().remove(TRUE);}}, |
1361 () -> env.values().remove(TRUE), |
1381 new Fun(){void f(){ env.entrySet().remove(TRUE);}}); |
1362 () -> env.entrySet().remove(TRUE)); |
1382 } catch (Throwable t) { unexpected(t); } |
1363 } catch (Throwable t) { unexpected(t); } |
1383 |
1364 |
1384 //---------------------------------------------------------------- |
1365 //---------------------------------------------------------------- |
1385 // Check query operations on environment maps |
1366 // Check query operations on environment maps |
1386 //---------------------------------------------------------------- |
1367 //---------------------------------------------------------------- |
1392 for (final Map<String,String> env : envs) { |
1373 for (final Map<String,String> env : envs) { |
1393 //---------------------------------------------------------------- |
1374 //---------------------------------------------------------------- |
1394 // Nulls in environment queries are forbidden. |
1375 // Nulls in environment queries are forbidden. |
1395 //---------------------------------------------------------------- |
1376 //---------------------------------------------------------------- |
1396 THROWS(NullPointerException.class, |
1377 THROWS(NullPointerException.class, |
1397 new Fun(){void f(){ getenv(null);}}, |
1378 () -> getenv(null), |
1398 new Fun(){void f(){ env.get(null);}}, |
1379 () -> env.get(null), |
1399 new Fun(){void f(){ env.containsKey(null);}}, |
1380 () -> env.containsKey(null), |
1400 new Fun(){void f(){ env.containsValue(null);}}, |
1381 () -> env.containsValue(null), |
1401 new Fun(){void f(){ env.keySet().contains(null);}}, |
1382 () -> env.keySet().contains(null), |
1402 new Fun(){void f(){ env.values().contains(null);}}); |
1383 () -> env.values().contains(null)); |
1403 |
1384 |
1404 //---------------------------------------------------------------- |
1385 //---------------------------------------------------------------- |
1405 // Non-String types in environment queries are forbidden. |
1386 // Non-String types in environment queries are forbidden. |
1406 //---------------------------------------------------------------- |
1387 //---------------------------------------------------------------- |
1407 THROWS(ClassCastException.class, |
1388 THROWS(ClassCastException.class, |
1408 new Fun(){void f(){ env.get(TRUE);}}, |
1389 () -> env.get(TRUE), |
1409 new Fun(){void f(){ env.containsKey(TRUE);}}, |
1390 () -> env.containsKey(TRUE), |
1410 new Fun(){void f(){ env.containsValue(TRUE);}}, |
1391 () -> env.containsValue(TRUE), |
1411 new Fun(){void f(){ env.keySet().contains(TRUE);}}, |
1392 () -> env.keySet().contains(TRUE), |
1412 new Fun(){void f(){ env.values().contains(TRUE);}}); |
1393 () -> env.values().contains(TRUE)); |
1413 |
1394 |
1414 //---------------------------------------------------------------- |
1395 //---------------------------------------------------------------- |
1415 // Illegal String values in environment queries are (grumble) OK |
1396 // Illegal String values in environment queries are (grumble) OK |
1416 //---------------------------------------------------------------- |
1397 //---------------------------------------------------------------- |
1417 equal(env.get("\u0000"), null); |
1398 equal(env.get("\u0000"), null); |
1425 |
1406 |
1426 try { |
1407 try { |
1427 final Set<Map.Entry<String,String>> entrySet = |
1408 final Set<Map.Entry<String,String>> entrySet = |
1428 new ProcessBuilder().environment().entrySet(); |
1409 new ProcessBuilder().environment().entrySet(); |
1429 THROWS(NullPointerException.class, |
1410 THROWS(NullPointerException.class, |
1430 new Fun(){void f(){ entrySet.contains(null);}}); |
1411 () -> entrySet.contains(null)); |
1431 THROWS(ClassCastException.class, |
1412 THROWS(ClassCastException.class, |
1432 new Fun(){void f(){ entrySet.contains(TRUE);}}, |
1413 () -> entrySet.contains(TRUE), |
1433 new Fun(){void f(){ |
1414 () -> entrySet.contains( |
1434 entrySet.contains( |
1415 new SimpleImmutableEntry<Boolean,String>(TRUE,""))); |
1435 new SimpleImmutableEntry<Boolean,String>(TRUE,""));}}); |
|
1436 |
1416 |
1437 check(! entrySet.contains |
1417 check(! entrySet.contains |
1438 (new SimpleImmutableEntry<String,String>("", ""))); |
1418 (new SimpleImmutableEntry<String,String>("", ""))); |
1439 } catch (Throwable t) { unexpected(t); } |
1419 } catch (Throwable t) { unexpected(t); } |
1440 |
1420 |
1900 new File("suBdiR").mkdirs(); |
1880 new File("suBdiR").mkdirs(); |
1901 copy("/bin/true", "suBdiR/unliKely"); |
1881 copy("/bin/true", "suBdiR/unliKely"); |
1902 final ProcessBuilder pb = |
1882 final ProcessBuilder pb = |
1903 new ProcessBuilder(new String[]{"unliKely"}); |
1883 new ProcessBuilder(new String[]{"unliKely"}); |
1904 pb.environment().put("PATH", "suBdiR"); |
1884 pb.environment().put("PATH", "suBdiR"); |
1905 THROWS(IOException.class, |
1885 THROWS(IOException.class, () -> pb.start()); |
1906 new Fun() {void f() throws Throwable {pb.start();}}); |
|
1907 } catch (Throwable t) { unexpected(t); |
1886 } catch (Throwable t) { unexpected(t); |
1908 } finally { |
1887 } finally { |
1909 new File("suBdiR/unliKely").delete(); |
1888 new File("suBdiR/unliKely").delete(); |
1910 new File("suBdiR").delete(); |
1889 new File("suBdiR").delete(); |
1911 } |
1890 } |
1974 print4095(p.getOutputStream(), (byte) '!'); // Might hang! |
1953 print4095(p.getOutputStream(), (byte) '!'); // Might hang! |
1975 p.waitFor(); // Might hang! |
1954 p.waitFor(); // Might hang! |
1976 equal(SIZE, p.getInputStream().available()); |
1955 equal(SIZE, p.getInputStream().available()); |
1977 equal(SIZE, p.getErrorStream().available()); |
1956 equal(SIZE, p.getErrorStream().available()); |
1978 THROWS(IOException.class, |
1957 THROWS(IOException.class, |
1979 new Fun(){void f() throws IOException { |
1958 () -> { p.getOutputStream().write((byte) '!'); |
1980 p.getOutputStream().write((byte) '!'); |
1959 p.getOutputStream().flush();}); |
1981 p.getOutputStream().flush(); |
|
1982 }}); |
|
1983 |
1960 |
1984 final byte[] bytes = new byte[SIZE + 1]; |
1961 final byte[] bytes = new byte[SIZE + 1]; |
1985 equal(SIZE, p.getInputStream().read(bytes)); |
1962 equal(SIZE, p.getInputStream().read(bytes)); |
1986 for (int i = 0; i < SIZE; i++) |
1963 for (int i = 0; i < SIZE; i++) |
1987 equal((byte) '!', bytes[i]); |
1964 equal((byte) '!', bytes[i]); |
2004 try { p.getOutputStream().close(); } catch (IOException flushFailed) { } |
1981 try { p.getOutputStream().close(); } catch (IOException flushFailed) { } |
2005 |
1982 |
2006 InputStream[] streams = { p.getInputStream(), p.getErrorStream() }; |
1983 InputStream[] streams = { p.getInputStream(), p.getErrorStream() }; |
2007 for (final InputStream in : streams) { |
1984 for (final InputStream in : streams) { |
2008 Fun[] ops = { |
1985 Fun[] ops = { |
2009 new Fun(){void f() throws IOException { |
1986 () -> in.read(), |
2010 in.read(); }}, |
1987 () -> in.read(bytes), |
2011 new Fun(){void f() throws IOException { |
1988 () -> in.available() |
2012 in.read(bytes); }}, |
|
2013 new Fun(){void f() throws IOException { |
|
2014 in.available(); }} |
|
2015 }; |
1989 }; |
2016 for (Fun op : ops) { |
1990 for (Fun op : ops) { |
2017 try { |
1991 try { |
2018 op.f(); |
1992 op.f(); |
2019 fail(); |
1993 fail(); |
2213 new ProcessBuilder("env").directory(new File("dir")).directory(); |
2187 new ProcessBuilder("env").directory(new File("dir")).directory(); |
2214 new ProcessBuilder("env").command("??").command(); |
2188 new ProcessBuilder("env").command("??").command(); |
2215 } catch (Throwable t) { unexpected(t); } |
2189 } catch (Throwable t) { unexpected(t); } |
2216 |
2190 |
2217 THROWS(SecurityException.class, |
2191 THROWS(SecurityException.class, |
2218 new Fun() { void f() throws IOException { |
2192 () -> { policy.setPermissions(/* Nothing */); |
2219 policy.setPermissions(/* Nothing */); |
2193 System.getenv("foo");}, |
2220 System.getenv("foo");}}, |
2194 () -> { policy.setPermissions(/* Nothing */); |
2221 new Fun() { void f() throws IOException { |
2195 System.getenv();}, |
2222 policy.setPermissions(/* Nothing */); |
2196 () -> { policy.setPermissions(/* Nothing */); |
2223 System.getenv();}}, |
2197 new ProcessBuilder("echo").start();}, |
2224 new Fun() { void f() throws IOException { |
2198 () -> { policy.setPermissions(/* Nothing */); |
2225 policy.setPermissions(/* Nothing */); |
2199 Runtime.getRuntime().exec("echo");}, |
2226 new ProcessBuilder("echo").start();}}, |
2200 () -> { policy.setPermissions( |
2227 new Fun() { void f() throws IOException { |
2201 new RuntimePermission("getenv.bar")); |
2228 policy.setPermissions(/* Nothing */); |
2202 System.getenv("foo");}); |
2229 Runtime.getRuntime().exec("echo");}}, |
|
2230 new Fun() { void f() throws IOException { |
|
2231 policy.setPermissions(new RuntimePermission("getenv.bar")); |
|
2232 System.getenv("foo");}}); |
|
2233 |
2203 |
2234 try { |
2204 try { |
2235 policy.setPermissions(new RuntimePermission("getenv.foo")); |
2205 policy.setPermissions(new RuntimePermission("getenv.foo")); |
2236 System.getenv("foo"); |
2206 System.getenv("foo"); |
2237 |
2207 |
2244 |
2214 |
2245 final Permission execPermission |
2215 final Permission execPermission |
2246 = new FilePermission("<<ALL FILES>>", "execute"); |
2216 = new FilePermission("<<ALL FILES>>", "execute"); |
2247 |
2217 |
2248 THROWS(SecurityException.class, |
2218 THROWS(SecurityException.class, |
2249 new Fun() { void f() throws IOException { |
2219 () -> { // environment permission by itself insufficient |
2250 // environment permission by itself insufficient |
2220 policy.setPermissions(new RuntimePermission("getenv.*")); |
2251 policy.setPermissions(new RuntimePermission("getenv.*")); |
2221 ProcessBuilder pb = new ProcessBuilder("env"); |
2252 ProcessBuilder pb = new ProcessBuilder("env"); |
2222 pb.environment().put("foo","bar"); |
2253 pb.environment().put("foo","bar"); |
2223 pb.start();}, |
2254 pb.start();}}, |
2224 () -> { // exec permission by itself insufficient |
2255 new Fun() { void f() throws IOException { |
2225 policy.setPermissions(execPermission); |
2256 // exec permission by itself insufficient |
2226 ProcessBuilder pb = new ProcessBuilder("env"); |
2257 policy.setPermissions(execPermission); |
2227 pb.environment().put("foo","bar"); |
2258 ProcessBuilder pb = new ProcessBuilder("env"); |
2228 pb.start();}); |
2259 pb.environment().put("foo","bar"); |
|
2260 pb.start();}}); |
|
2261 |
2229 |
2262 try { |
2230 try { |
2263 // Both permissions? OK. |
2231 // Both permissions? OK. |
2264 policy.setPermissions(new RuntimePermission("getenv.*"), |
2232 policy.setPermissions(new RuntimePermission("getenv.*"), |
2265 execPermission); |
2233 execPermission); |
2583 |
2551 |
2584 public static void main(String[] args) throws Throwable { |
2552 public static void main(String[] args) throws Throwable { |
2585 try {realMain(args);} catch (Throwable t) {unexpected(t);} |
2553 try {realMain(args);} catch (Throwable t) {unexpected(t);} |
2586 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); |
2554 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); |
2587 if (failed > 0) throw new AssertionError("Some tests failed");} |
2555 if (failed > 0) throw new AssertionError("Some tests failed");} |
2588 private static abstract class Fun {abstract void f() throws Throwable;} |
2556 interface Fun {void f() throws Throwable;} |
2589 static void THROWS(Class<? extends Throwable> k, Fun... fs) { |
2557 static void THROWS(Class<? extends Throwable> k, Fun... fs) { |
2590 for (Fun f : fs) |
2558 for (Fun f : fs) |
2591 try { f.f(); fail("Expected " + k.getName() + " not thrown"); } |
2559 try { f.f(); fail("Expected " + k.getName() + " not thrown"); } |
2592 catch (Throwable t) { |
2560 catch (Throwable t) { |
2593 if (k.isAssignableFrom(t.getClass())) pass(); |
2561 if (k.isAssignableFrom(t.getClass())) pass(); |