Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/com/sun/tools/attach/RunnerUtil.java
38855 views
/*1* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.io.IOException;24import java.io.File;25import java.nio.file.Files;26import java.util.Arrays;27import java.util.regex.Pattern;28import java.util.regex.Matcher;2930import jdk.testlibrary.OutputAnalyzer;31import jdk.testlibrary.ProcessTools;32import jdk.testlibrary.Utils;33import jdk.testlibrary.ProcessThread;3435/*36* Utility functions for test runners.37* (Test runner = class that launch a test)38*/39public class RunnerUtil {4041/**42* The Application process must be run concurrently with our tests since43* the tests will attach to the Application.44* We will run the Application process in a separate thread.45*46* The Application must be started with flag "-Xshare:off" for the Retransform47* test in TestBasics to pass on all platforms.48*49* The Application will write its pid and shutdownPort in the given outFile.50*/51public static ProcessThread startApplication(String outFile, String... additionalOpts) throws Throwable {52String classpath = System.getProperty("test.class.path", ".");53String[] myArgs = concat(additionalOpts, new String [] { "-Dattach.test=true", "-classpath", classpath, "Application", outFile });54String[] args = Utils.addTestJavaOpts(myArgs);55ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);56ProcessThread pt = new ProcessThread("runApplication", pb);57pt.start();58return pt;59}6061public static String[] concat(String[] a, String[] b) {62if (a == null) {63return b;64}65if (b == null) {66return a;67}68int aLen = a.length;69int bLen = b.length;70String[] c = new String[aLen + bLen];71System.arraycopy(a, 0, c, 0, aLen);72System.arraycopy(b, 0, c, aLen, bLen);73return c;74}7576/**77* Will stop the running Application.78* First tries to shutdown nicely by connecting to the shut down port.79* If that fails, the process will be killed hard with stopProcess().80*81* If the nice shutdown fails, then an Exception is thrown and the test should fail.82*83* @param port The shut down port.84* @param processThread The process to stop.85*/86public static void stopApplication(int port, ProcessThread processThread) throws Throwable {87if (processThread == null) {88System.out.println("RunnerUtil.stopApplication ignored since proc is null");89return;90}91try {92System.out.println("RunnerUtil.stopApplication waiting to for shutdown");93OutputAnalyzer output = ProcessTools.executeTestJvm(94"-classpath",95System.getProperty("test.class.path", "."),96"Shutdown",97Integer.toString(port));98// Verify that both the Shutdown command and the Application finished ok.99output.shouldHaveExitValue(0);100processThread.joinAndThrow();101processThread.getOutput().shouldHaveExitValue(0);102} catch (Throwable t) {103System.out.println("RunnerUtil.stopApplication failed. Will kill it hard: " + t);104processThread.stopProcess();105throw t;106}107}108109/**110* Creates a jar file.111* @param args Command to the jar tool.112*/113public static void createJar(String... args) {114System.out.println("Running: jar " + Arrays.toString(args));115sun.tools.jar.Main jar = new sun.tools.jar.Main(System.out, System.err, "jar");116if (!jar.run(args)) {117throw new RuntimeException("jar failed: args=" + Arrays.toString(args));118}119}120121/**122* Read process info for the running Application.123* The Application writes its info to a file with this format:124* shutdownPort=42994125* pid=19597126* done127*128* The final "done" is used to make sure the complete file has been written129* before we try to read it.130* This function will wait until the file is available.131*132* @param filename Path to file to read.133* @return The ProcessInfo containing pid and shutdownPort.134*/135public static ProcessInfo readProcessInfo(String filename) throws Throwable {136System.out.println("Reading port and pid from file: " + filename);137File file = new File(filename);138String content = null;139140// Read file or wait for it to be created.141long startTime = System.currentTimeMillis();142long lastWarningTime = 0;143while (true) {144content = readFile(file);145if (content != null && content.indexOf("done") >= 0) {146break;147}148Thread.sleep(100);149long elapsedTime = (System.currentTimeMillis() - startTime) / 1000;150if (elapsedTime > lastWarningTime) {151lastWarningTime = elapsedTime;152System.out.println("Waited " + elapsedTime + " seconds for file.");153}154}155156ProcessInfo info = new ProcessInfo();157// search for a line with format: key=nnn158Pattern pattern = Pattern.compile("(\\w*)=([0-9]+)\\r?\\n");159Matcher matcher = pattern.matcher(content);160while (matcher.find()) {161String key = matcher.group(1);162int value = Integer.parseInt(matcher.group(2));163if ("pid".equals(key)) {164info.pid = value;165} else if ("shutdownPort".equals(key)) {166info.shutdownPort = value;167}168}169System.out.println("processInfo.pid:" + info.pid);170System.out.println("processInfo.shutdownPort:" + info.shutdownPort);171return info;172}173174/**175* Read the content of a file.176* @param file The file to read.177* @return The file content or null if file does not exists.178*/179public static String readFile(File file) throws IOException {180if (!file.exists()) {181return null;182}183try {184byte[] bytes = Files.readAllBytes(file.toPath());185String content = new String(bytes);186return content;187} catch (IOException e) {188e.printStackTrace();189throw e;190}191}192193/**194* Helper class with info of the running Application.195*/196public static class ProcessInfo {197public int pid = -1;198public int shutdownPort = -1;199}200201}202203204