|
1 /* |
|
2 * Copyright (c) 2017, 2018, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
20 * or visit www.oracle.com if you need additional information or have any |
|
21 * questions. |
|
22 */ |
|
23 |
|
24 import jdk.test.lib.Platform; |
|
25 import jdk.test.lib.Utils; |
|
26 |
|
27 import java.io.File; |
|
28 import java.io.IOException; |
|
29 import java.io.InputStream; |
|
30 import java.io.OutputStream; |
|
31 import java.nio.file.Path; |
|
32 import java.nio.file.Paths; |
|
33 import java.util.Arrays; |
|
34 |
|
35 /** |
|
36 * Starts a new process to execute a command. |
|
37 * <p>Usage: --java|--cmd|--launcher <arg>+ |
|
38 * <p>If {@code --cmd} flag is specified, the arguments are treated as |
|
39 * a program to run and its arguments. Non-zero exit code of the created process |
|
40 * will be reported as an {@link AssertionError}. |
|
41 * <p>If {@code --java} flag is specified, the arguments are passed to {@code java} |
|
42 * from JDK under test. If exit code doesn't equal to 0 or 95, {@link AssertionError} |
|
43 * will be thrown. |
|
44 * <p>If {@code --launcher} flag is specified, the arguments treated similar as |
|
45 * for {@code --cmd}, but the started process will have the directory which |
|
46 * contains {@code jvm.so} in dynamic library path, and {@code test.class.path} |
|
47 * as CLASSPATH environment variable. Exit codes are checked as in |
|
48 * {@code --java}, i.e. 0 or 95 means pass. |
|
49 */ |
|
50 public class ExecDriver { |
|
51 public static void main(String[] args) throws IOException, InterruptedException { |
|
52 boolean java = false; |
|
53 boolean launcher = false; |
|
54 |
|
55 String type = args[0]; |
|
56 switch (type) { |
|
57 case "--java": |
|
58 String[] oldArgs = args; |
|
59 int count; |
|
60 String libraryPath = System.getProperty("test.nativepath"); |
|
61 if (libraryPath != null && !libraryPath.isEmpty()) { |
|
62 count = 4; |
|
63 args = new String[args.length + 3]; |
|
64 args[3] = "-Djava.library.path=" + libraryPath; |
|
65 } else { |
|
66 count = 3; |
|
67 args = new String[args.length + 2]; |
|
68 } |
|
69 args[0] = javaBin(); |
|
70 args[1] = "-cp"; |
|
71 args[2] = Utils.TEST_CLASS_PATH; |
|
72 System.arraycopy(oldArgs, 1, args, count, oldArgs.length - 1); |
|
73 java = true; |
|
74 break; |
|
75 case "--launcher": |
|
76 java = true; |
|
77 launcher = true; |
|
78 case "--cmd": |
|
79 args = Arrays.copyOfRange(args, 1, args.length); |
|
80 break; |
|
81 default: |
|
82 throw new Error("unknown type: " + type); |
|
83 } |
|
84 // adding 'test.vm.opts' and 'test.java.opts' |
|
85 if (java) { |
|
86 String[] oldArgs = args; |
|
87 String[] testJavaOpts = Utils.getTestJavaOpts(); |
|
88 if (testJavaOpts.length > 0) { |
|
89 args = new String[args.length + testJavaOpts.length]; |
|
90 // bin/java goes before options |
|
91 args[0] = oldArgs[0]; |
|
92 // then external java options |
|
93 System.arraycopy(testJavaOpts, 0, args, 1, testJavaOpts.length); |
|
94 // and then options and args from a test |
|
95 System.arraycopy(oldArgs, 1, args, 1 + testJavaOpts.length, oldArgs.length - 1); |
|
96 } |
|
97 } |
|
98 String command = Arrays.toString(args); |
|
99 System.out.println("exec " + command); |
|
100 |
|
101 ProcessBuilder pb = new ProcessBuilder(args); |
|
102 // adding jvm.so to library path |
|
103 if (launcher) { |
|
104 Path dir = Paths.get(Utils.TEST_JDK); |
|
105 String name; |
|
106 if (Platform.isWindows()) { |
|
107 dir = dir.resolve("bin") |
|
108 .resolve(variant()) |
|
109 .toAbsolutePath(); |
|
110 name = "PATH"; |
|
111 } else { |
|
112 dir = dir.resolve("lib") |
|
113 .resolve(variant()) |
|
114 .toAbsolutePath(); |
|
115 name = Platform.isOSX() ? "DYLD_LIBRARY_PATH" : "LD_LIBRARY_PATH"; |
|
116 } |
|
117 |
|
118 System.out.println(" with " + name + " = " + |
|
119 pb.environment() |
|
120 .merge(name, dir.toString(), (x, y) -> y + File.pathSeparator + x)); |
|
121 System.out.println(" with CLASSPATH = " + |
|
122 pb.environment() |
|
123 .put("CLASSPATH", Utils.TEST_CLASS_PATH)); |
|
124 } |
|
125 Process p = pb.start(); |
|
126 // inheritIO does not work as expected for @run driver |
|
127 new Thread(() -> copy(p.getInputStream(), System.out)).start(); |
|
128 new Thread(() -> copy(p.getErrorStream(), System.out)).start(); |
|
129 int exitCode = p.waitFor(); |
|
130 |
|
131 if (exitCode != 0 && (!java || exitCode != 95)) { |
|
132 throw new AssertionError(command + " exit code is " + exitCode); |
|
133 } |
|
134 } |
|
135 |
|
136 private static String variant() { |
|
137 if (Platform.isServer()) { |
|
138 return "server"; |
|
139 } else if (Platform.isClient()) { |
|
140 return "client"; |
|
141 } else if (Platform.isMinimal()) { |
|
142 return "minimal"; |
|
143 } else { |
|
144 throw new Error("TESTBUG: unsuppported vm variant"); |
|
145 } |
|
146 } |
|
147 |
|
148 |
|
149 private static void copy(InputStream is, OutputStream os) { |
|
150 byte[] buffer = new byte[1024]; |
|
151 int n; |
|
152 try (InputStream close = is) { |
|
153 while ((n = is.read(buffer)) != -1) { |
|
154 os.write(buffer, 0, n); |
|
155 } |
|
156 os.flush(); |
|
157 } catch (IOException e) { |
|
158 e.printStackTrace(); |
|
159 } |
|
160 } |
|
161 |
|
162 private static String javaBin() { |
|
163 return Paths.get(Utils.TEST_JDK) |
|
164 .resolve("bin") |
|
165 .resolve("java") |
|
166 .toAbsolutePath() |
|
167 .toString(); |
|
168 } |
|
169 } |
|
170 |