6943190: TEST_BUG: some tests in java/lang/Runtime/exec have hard-coded path to shell commands
Reviewed-by: martin, rriggs, alanb
--- a/jdk/test/java/lang/Runtime/exec/ConcurrentRead.java Mon Mar 24 10:40:19 2014 +0100
+++ b/jdk/test/java/lang/Runtime/exec/ConcurrentRead.java Mon Mar 24 14:14:03 2014 +0400
@@ -30,21 +30,19 @@
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.File;
-import java.io.IOException;
public class ConcurrentRead {
static volatile Exception savedException;
- static final String TEE = "/usr/bin/tee";
public static void main(String[] args) throws Exception {
+ if (! UnixCommands.isUnix) {
+ System.out.println("For UNIX only");
+ return;
+ }
+ UnixCommands.ensureCommandsAvailable("tee");
- if (File.separatorChar == '\\' || // Windows
- !new File(TEE).exists()) // no tee
- return;
-
- Process p = Runtime.getRuntime().exec(TEE);
+ Process p = Runtime.getRuntime().exec(UnixCommands.tee());
OutputStream out = p.getOutputStream();
InputStream in = p.getInputStream();
Thread t1 = new WriterThread(out, in);
--- a/jdk/test/java/lang/Runtime/exec/ExecWithDir.java Mon Mar 24 10:40:19 2014 +0100
+++ b/jdk/test/java/lang/Runtime/exec/ExecWithDir.java Mon Mar 24 14:14:03 2014 +0400
@@ -28,21 +28,25 @@
* directory is specified
*/
-import java.io.*;
+import java.io.File;
public class ExecWithDir {
- private static final String CMD = "/bin/true";
private static final int N = 500;
public static void main(String args[]) throws Exception {
- if (! new File(CMD).canExecute())
+ if (! UnixCommands.isUnix) {
+ System.out.println("For UNIX only");
return;
+ }
+ UnixCommands.ensureCommandsAvailable("true");
+
+ final String trueCmd = UnixCommands.findCommand("true");
File dir = new File(".");
for (int i = 1; i <= N; i++) {
System.out.print(i);
System.out.print(" e");
- Process p = Runtime.getRuntime().exec(CMD, null, dir);
+ Process p = Runtime.getRuntime().exec(trueCmd, null, dir);
System.out.print('w');
int s = p.waitFor();
System.out.println("x " + s);
--- a/jdk/test/java/lang/Runtime/exec/ExecWithInput.java Mon Mar 24 10:40:19 2014 +0100
+++ b/jdk/test/java/lang/Runtime/exec/ExecWithInput.java Mon Mar 24 14:14:03 2014 +0400
@@ -39,7 +39,6 @@
public class ExecWithInput {
- private static final String CAT = "/bin/cat";
private static final int N = 200;
static int go(int i) throws Exception {
@@ -50,8 +49,7 @@
* program exits. Under 1.4.1, cat sometimes gets stuck on a pipe
* read and never terminates.
*/
- //Process p = Runtime.getRuntime().exec(new String[] { CAT } );
- Process p = Runtime.getRuntime().exec(CAT);
+ Process p = Runtime.getRuntime().exec(UnixCommands.cat());
String input = i + ": line 1\n" + i + ": line 2\n";
StringBufferInputStream in = new StringBufferInputStream(input);
@@ -65,12 +63,12 @@
}
public static void main(String[] args) throws Exception {
- if (!System.getProperty("os.name").equals("Linux"))
- return;
- if (File.separatorChar == '\\') {
- // no /bin/cat on windows
+ if (! UnixCommands.isLinux) {
+ System.out.println("For Linux only");
return;
}
+ UnixCommands.ensureCommandsAvailable("cat");
+
for (int i = 0; i < N; i++)
go(i);
}
@@ -93,7 +91,6 @@
public void run() {
try {
- int c;
byte[] buf = new byte[8192];
int n;
while ((n = in.read(buf)) != -1) {
--- a/jdk/test/java/lang/Runtime/exec/ExitValue.java Mon Mar 24 10:40:19 2014 +0100
+++ b/jdk/test/java/lang/Runtime/exec/ExitValue.java Mon Mar 24 14:14:03 2014 +0400
@@ -68,13 +68,18 @@
int expectedExitValue)
throws Exception
{
- checkExitValue(new String[] { "/bin/sh", "-c", posixShellProgram },
+ checkExitValue(new String[] { UnixCommands.sh(), "-c", posixShellProgram },
expectedExitValue);
}
final static int EXIT_CODE = 5;
public static void main(String[] args) throws Exception {
+ if (! UnixCommands.isUnix) {
+ System.out.println("For UNIX only");
+ return;
+ }
+ UnixCommands.ensureCommandsAvailable("sh", "true", "kill");
String java = join(File.separator, new String []
{ System.getProperty("java.home"), "bin", "java" });
@@ -85,17 +90,14 @@
"ExitValue$Run", String.valueOf(EXIT_CODE)
}, EXIT_CODE);
- checkExitValue(new String[] { "/bin/true" }, 0);
+ checkExitValue(new String[] { UnixCommands.findCommand("true") }, 0);
checkPosixShellExitValue("exit", 0);
checkPosixShellExitValue("exit 7", 7);
- if (new File("/bin/kill").exists()) {
- int sigoffset =
- System.getProperty("os.name").equals("SunOS") ? 0 : 128;
- checkPosixShellExitValue("/bin/kill -9 $$", sigoffset+9);
- }
+ int sigoffset = UnixCommands.isSunOS ? 0 : 128;
+ checkPosixShellExitValue(UnixCommands.kill() + " -9 $$", sigoffset+9);
}
public static class Run {
--- a/jdk/test/java/lang/Runtime/exec/LotsOfDestroys.java Mon Mar 24 10:40:19 2014 +0100
+++ b/jdk/test/java/lang/Runtime/exec/LotsOfDestroys.java Mon Mar 24 14:14:03 2014 +0400
@@ -28,19 +28,19 @@
* @author kladko
*/
-import java.io.File;
-
public class LotsOfDestroys {
static final int RUNS = 400;
- static final String ECHO = "/usr/bin/echo";
public static void main(String[] args) throws Exception {
- if (File.separatorChar == '\\' || // Windows
- !new File(ECHO).exists()) // no echo
+ if (! UnixCommands.isUnix) {
+ System.out.println("For UNIX only");
return;
+ }
+ UnixCommands.ensureCommandsAvailable("echo");
- for (int i = 0; i<= RUNS; i++) {
- Process process = Runtime.getRuntime().exec(ECHO + " x");
+ for (int i = 0; i <= RUNS; i++) {
+ Process process = Runtime.getRuntime().exec(
+ UnixCommands.echo() + " x");
process.destroy();
}
}
--- a/jdk/test/java/lang/Runtime/exec/LotsOfOutput.java Mon Mar 24 10:40:19 2014 +0100
+++ b/jdk/test/java/lang/Runtime/exec/LotsOfOutput.java Mon Mar 24 14:14:03 2014 +0400
@@ -28,16 +28,16 @@
* @author kladko
*/
-import java.io.File;
-
public class LotsOfOutput {
- static final String CAT = "/usr/bin/cat";
- public static void main(String[] args) throws Exception{
- if (File.separatorChar == '\\' || // Windows
- !new File(CAT).exists()) // no cat
+ public static void main(String[] args) throws Exception {
+ if (! UnixCommands.isUnix) {
+ System.out.println("For UNIX only");
return;
- Process p = Runtime.getRuntime().exec(CAT + " /dev/zero");
+ }
+ UnixCommands.ensureCommandsAvailable("cat");
+
+ Process p = Runtime.getRuntime().exec(UnixCommands.cat() + " /dev/zero");
long initMemory = Runtime.getRuntime().totalMemory();
for (int i=1; i< 10; i++) {
Thread.sleep(100);
--- a/jdk/test/java/lang/Runtime/exec/SleepyCat.java Mon Mar 24 10:40:19 2014 +0100
+++ b/jdk/test/java/lang/Runtime/exec/SleepyCat.java Mon Mar 24 14:14:03 2014 +0400
@@ -73,8 +73,8 @@
// slower, making the child more likely to win the race!
int iterations = 20;
int timeout = 30;
- String[] catArgs = new String[] {"/bin/cat"};
- String[] sleepArgs = new String[] {"/bin/sleep",
+ String[] catArgs = new String[] {UnixCommands.cat()};
+ String[] sleepArgs = new String[] {UnixCommands.sleep(),
String.valueOf(timeout+1)};
Process[] cats = new Process[iterations];
Process[] sleeps = new Process[iterations];
@@ -126,8 +126,9 @@
timer.schedule(sleeperExecutioner, timeout * 1000);
byte[] buffer = new byte[10];
String[] args =
- new String[] {"/bin/sh", "-c",
- "exec sleep " + (timeout+1) + " >/dev/null"};
+ new String[] {UnixCommands.sh(), "-c",
+ "exec " + UnixCommands.sleep() + " "
+ + (timeout+1) + " >/dev/null"};
for (int i = 0;
i < backgroundSleepers.length && !sleeperExecutioner.timedOut();
@@ -153,12 +154,13 @@
}
public static void main (String[] args) throws Exception {
- try {
- if (hang1() | hang2())
- throw new Exception("Read from closed pipe hangs");
- } catch (IOException e) {
- // We will get here on non-Posix systems,
- // which don't have cat and sleep and sh.
+ if (! UnixCommands.isUnix) {
+ System.out.println("For UNIX only");
+ return;
}
+ UnixCommands.ensureCommandsAvailable("sh", "cat", "sleep");
+
+ if (hang1() | hang2())
+ throw new Exception("Read from closed pipe hangs");
}
}
--- a/jdk/test/java/lang/Runtime/exec/Status.java Mon Mar 24 10:40:19 2014 +0100
+++ b/jdk/test/java/lang/Runtime/exec/Status.java Mon Mar 24 14:14:03 2014 +0400
@@ -35,10 +35,15 @@
public static void main(String args[])
throws Exception
{
- if (!System.getProperty("os.name").equals("Linux"))
+ if (!System.getProperty("os.name").equals("Linux")) {
+ System.out.println("Only for Linux");
return;
+ }
+ UnixCommands.ensureCommandsAvailable("false");
+
+ final String falseCmd = UnixCommands.findCommand("false");
for (int i = 0; i < N; i++) {
- Process p = Runtime.getRuntime().exec("false");
+ Process p = Runtime.getRuntime().exec(falseCmd);
int s = p.waitFor();
System.out.print(s);
System.out.print(' ');
--- a/jdk/test/java/lang/Runtime/exec/StreamsSurviveDestroy.java Mon Mar 24 10:40:19 2014 +0100
+++ b/jdk/test/java/lang/Runtime/exec/StreamsSurviveDestroy.java Mon Mar 24 14:14:03 2014 +0400
@@ -102,7 +102,7 @@
CountDownLatch latch = new CountDownLatch(2);
System.err.println("test");
- Process p = Runtime.getRuntime().exec("/bin/cat");
+ Process p = Runtime.getRuntime().exec(UnixCommands.cat());
Copier cp1 = new Copier("out", p.getInputStream(), System.err,
false, false, latch);
Copier cp2 = new Copier("err", p.getErrorStream(), System.err,
@@ -122,7 +122,7 @@
CountDownLatch latch = new CountDownLatch(2);
System.err.println("testCloseBeforeDestroy");
- Process p = Runtime.getRuntime().exec("/bin/cat");
+ Process p = Runtime.getRuntime().exec(UnixCommands.cat());
Copier cp1 = new Copier("out", p.getInputStream(), System.err,
true, false, latch);
Copier cp2 = new Copier("err", p.getErrorStream(), System.err,
@@ -143,7 +143,7 @@
static void testCloseAfterDestroy() throws Exception {
CountDownLatch latch = new CountDownLatch(2);
System.err.println("testCloseAfterDestroy");
- Process p = Runtime.getRuntime().exec("/bin/cat");
+ Process p = Runtime.getRuntime().exec(UnixCommands.cat());
Copier cp1 = new Copier("out", p.getInputStream(), System.err,
true, false,latch);
Copier cp2 = new Copier("err", p.getErrorStream(), System.err,
@@ -165,7 +165,7 @@
static void testInterrupt() throws Exception {
CountDownLatch latch = new CountDownLatch(2);
System.err.println("testInterrupt");
- Process p = Runtime.getRuntime().exec("/bin/cat");
+ Process p = Runtime.getRuntime().exec(UnixCommands.cat());
Copier cp1 = new Copier("out", p.getInputStream(), System.err,
false, true, latch);
Copier cp2 = new Copier("err", p.getErrorStream(), System.err,
@@ -186,10 +186,13 @@
public static void main(String[] args) throws Exception {
- // Applies only to Solaris; Linux and Windows
- // behave a little differently
- if (!System.getProperty("os.name").equals("SunOS"))
+ // Applies only to Solaris;
+ // Linux and Windows behave a little differently
+ if (! UnixCommands.isSunOS) {
+ System.out.println("For SunOS only");
return;
+ }
+ UnixCommands.ensureCommandsAvailable("cat");
test();
testCloseBeforeDestroy();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Runtime/exec/UnixCommands.java Mon Mar 24 14:14:03 2014 +0400
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Utility class for finding the command on the current system
+ */
+public class UnixCommands {
+
+ public static final boolean isUnix = ! System.getProperty("os.name").startsWith("Windows");
+ public static final boolean isLinux = System.getProperty("os.name").startsWith("Linux");
+ public static final boolean isSunOS = System.getProperty("os.name").equals("SunOS");
+
+ private static final String[] paths = {"/bin", "/usr/bin"};
+
+ private static Map<String,String> nameToCommand = new HashMap<>(16);
+
+ /**
+ * Throws Error unless every listed command is available on the system
+ */
+ public static void ensureCommandsAvailable(String... commands) {
+ for (String command : commands) {
+ if (findCommand(command) == null) {
+ throw new Error("Command '" + command + "' not found; bailing out");
+ }
+ }
+ }
+
+ /**
+ * If the path to the command could be found, returns the command with the full path.
+ * Otherwise, returns null.
+ */
+ public static String cat() { return findCommand("cat"); }
+ public static String sh() { return findCommand("sh"); }
+ public static String kill() { return findCommand("kill"); }
+ public static String sleep() { return findCommand("sleep"); }
+ public static String tee() { return findCommand("tee"); }
+ public static String echo() { return findCommand("echo"); }
+
+ public static String findCommand(String name) {
+ if (nameToCommand.containsKey(name)) {
+ return nameToCommand.get(name);
+ }
+ String command = findCommand0(name);
+ nameToCommand.put(name, command);
+ return command;
+ }
+
+ private static String findCommand0(String name) {
+ for (String path : paths) {
+ File file = new File(path, name);
+ if (file.canExecute()) {
+ return file.getPath();
+ }
+ }
+ return null;
+ }
+}