1 /*
2 * Copyright (c) 2015, 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
25 package org.graalvm.compiler.test;
26
27 import java.io.BufferedReader;
28 import java.io.File;
29 import java.io.IOException;
30 import java.io.InputStreamReader;
31 import java.nio.file.Files;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Formatter;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.regex.Matcher;
38 import java.util.regex.Pattern;
39
40 import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
41 import org.graalvm.util.CollectionsUtil;
42 import org.junit.Assume;
43
44 /**
45 * Utility methods for spawning a VM in a subprocess during unit tests.
46 */
47 public final class SubprocessUtil {
48
49 private SubprocessUtil() {
50 }
51
52 /**
53 * Gets the command line for the current process.
54 *
55 * @return the command line arguments for the current process or {@code null} if they are not
56 * available
85 return arg;
86 }
87 // See http://stackoverflow.com/a/1250279
88 return "'" + arg.replace("'", "'\"'\"'") + "'";
89 }
90
91 /**
92 * Returns a new copy {@code args} with debugger arguments removed.
93 */
94 public static List<String> withoutDebuggerArguments(List<String> args) {
95 List<String> result = new ArrayList<>(args.size());
96 for (String arg : args) {
97 if (!(arg.equals("-Xdebug") || arg.startsWith("-Xrunjdwp:"))) {
98 result.add(arg);
99 }
100 }
101 return result;
102 }
103
104 /**
105 * Gets the command line used to start the current Java VM, including all VM arguments, but not
106 * including the main class or any Java arguments. This can be used to spawn an identical VM,
107 * but running different Java code.
108 */
109 public static List<String> getVMCommandLine() {
110 List<String> args = getProcessCommandLine();
111 if (args == null) {
112 return null;
113 } else {
114 int index = findMainClassIndex(args);
115 return args.subList(0, index);
116 }
117 }
118
119 /**
120 * Detects whether a java agent is attached.
121 */
122 public static boolean isJavaAgentAttached() {
123 return SubprocessUtil.getVMCommandLine().stream().anyMatch(args -> args.startsWith("-javaagent"));
124 }
125
126 /**
127 * The details of a subprocess execution.
128 */
129 public static class Subprocess {
130
131 /**
132 * The command line of the subprocess.
133 */
134 public final List<String> command;
135
136 /**
137 * Exit code of the subprocess.
138 */
139 public final int exitCode;
140
141 /**
142 * Output from the subprocess broken into lines.
143 */
261 optionName.equals("--dry-run") ||
262 optionName.equals("--disable-@files") ||
263 optionName.equals("--dry-run") ||
264 optionName.equals("--help") ||
265 optionName.equals("--help-extra")) {
266 return false;
267 }
268 if (optionName.startsWith("--")) {
269 return optionName.indexOf('=') == -1;
270 }
271 }
272 return false;
273 }
274
275 private static int findMainClassIndex(List<String> commandLine) {
276 int i = 1; // Skip the java executable
277
278 while (i < commandLine.size()) {
279 String s = commandLine.get(i);
280 if (s.charAt(0) != '-') {
281 return i;
282 } else if (hasArg(s)) {
283 i += 2;
284 } else {
285 i++;
286 }
287 }
288 throw new InternalError();
289 }
290
291 }
|
1 /*
2 * Copyright (c) 2015, 2019, 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
25 package org.graalvm.compiler.test;
26
27 import java.io.BufferedReader;
28 import java.io.File;
29 import java.io.IOException;
30 import java.io.InputStreamReader;
31 import java.nio.file.Files;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Formatter;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.function.Predicate;
38 import java.util.regex.Matcher;
39 import java.util.regex.Pattern;
40
41 import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
42 import org.graalvm.util.CollectionsUtil;
43 import org.junit.Assume;
44
45 /**
46 * Utility methods for spawning a VM in a subprocess during unit tests.
47 */
48 public final class SubprocessUtil {
49
50 private SubprocessUtil() {
51 }
52
53 /**
54 * Gets the command line for the current process.
55 *
56 * @return the command line arguments for the current process or {@code null} if they are not
57 * available
86 return arg;
87 }
88 // See http://stackoverflow.com/a/1250279
89 return "'" + arg.replace("'", "'\"'\"'") + "'";
90 }
91
92 /**
93 * Returns a new copy {@code args} with debugger arguments removed.
94 */
95 public static List<String> withoutDebuggerArguments(List<String> args) {
96 List<String> result = new ArrayList<>(args.size());
97 for (String arg : args) {
98 if (!(arg.equals("-Xdebug") || arg.startsWith("-Xrunjdwp:"))) {
99 result.add(arg);
100 }
101 }
102 return result;
103 }
104
105 /**
106 * Gets the command line options to do the same package opening and exporting specified by the
107 * {@code --open-packages} option to the {@code mx unittest} command.
108 *
109 * Properties defined in {@code com.oracle.mxtool.junit.MxJUnitWrapper}.
110 */
111 public static List<String> getPackageOpeningOptions() {
112 List<String> result = new ArrayList<>();
113 String[] actions = {"opens", "exports"};
114 for (String action : actions) {
115 String opens = System.getProperty("com.oracle.mxtool.junit." + action);
116 if (opens != null && !opens.isEmpty()) {
117 for (String value : opens.split(System.lineSeparator())) {
118 result.add("--add-" + action + "=" + value);
119 }
120 }
121 }
122 return result;
123 }
124
125 /**
126 * Gets the command line used to start the current Java VM, including all VM arguments, but not
127 * including the main class or any Java arguments. This can be used to spawn an identical VM,
128 * but running different Java code.
129 */
130 public static List<String> getVMCommandLine() {
131 List<String> args = getProcessCommandLine();
132 if (args == null) {
133 return null;
134 } else {
135 int index = findMainClassIndex(args);
136 return args.subList(0, index);
137 }
138 }
139
140 /**
141 * Detects whether a Java agent matching {@code agentPredicate} is specified in the VM
142 * arguments.
143 *
144 * @param agentPredicate a predicate that is given the value of a {@code -javaagent} VM argument
145 */
146 public static boolean isJavaAgentAttached(Predicate<String> agentPredicate) {
147 return SubprocessUtil.getVMCommandLine().stream().//
148 filter(args -> args.startsWith("-javaagent:")).//
149 map(s -> s.substring("-javaagent:".length())).//
150 anyMatch(agentPredicate);
151 }
152
153 /**
154 * Detects whether a Java agent is specified in the VM arguments.
155 */
156 public static boolean isJavaAgentAttached() {
157 return isJavaAgentAttached(javaAgentValue -> true);
158 }
159
160 /**
161 * Detects whether the JaCoCo Java agent is specified in the VM arguments.
162 */
163 public static boolean isJaCoCoAttached() {
164 return isJavaAgentAttached(s -> s.toLowerCase().contains("jacoco"));
165 }
166
167 /**
168 * The details of a subprocess execution.
169 */
170 public static class Subprocess {
171
172 /**
173 * The command line of the subprocess.
174 */
175 public final List<String> command;
176
177 /**
178 * Exit code of the subprocess.
179 */
180 public final int exitCode;
181
182 /**
183 * Output from the subprocess broken into lines.
184 */
302 optionName.equals("--dry-run") ||
303 optionName.equals("--disable-@files") ||
304 optionName.equals("--dry-run") ||
305 optionName.equals("--help") ||
306 optionName.equals("--help-extra")) {
307 return false;
308 }
309 if (optionName.startsWith("--")) {
310 return optionName.indexOf('=') == -1;
311 }
312 }
313 return false;
314 }
315
316 private static int findMainClassIndex(List<String> commandLine) {
317 int i = 1; // Skip the java executable
318
319 while (i < commandLine.size()) {
320 String s = commandLine.get(i);
321 if (s.charAt(0) != '-') {
322 // https://bugs.openjdk.java.net/browse/JDK-8027634
323 if (isJava8OrEarlier || s.charAt(0) != '@') {
324 return i;
325 }
326 i++;
327 } else if (hasArg(s)) {
328 i += 2;
329 } else {
330 i++;
331 }
332 }
333 throw new InternalError();
334 }
335
336 }
|