Path: blob/master/test/hotspot/jtreg/vmTestbase/vm/share/process/ProcessExecutor.java
41159 views
/*1* Copyright (c) 2011, 2018, 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*/22package vm.share.process;2324import nsk.share.TestBug;25import nsk.share.TestFailure;26import nsk.share.log.Log;27import vm.share.ProcessUtils;2829import java.io.InputStream;30import java.io.InputStreamReader;31import java.io.BufferedReader;32import java.io.OutputStream;33import java.io.PrintStream;34import java.io.PipedInputStream;35import java.io.PipedOutputStream;36import java.io.IOException;37import java.util.*;38import java.lang.reflect.Field;3940public class ProcessExecutor {41private static long CLEANUP_TIMEOUT = 60000;42private Process process;43private StreamReader stdoutReader = new StreamReader("stdout");44private StreamReader stderrReader = new StreamReader("stderr");45private Waiter waiter = new Waiter();46private OutputStream stdin;47private volatile boolean running;48private volatile int result = -1;49private List<String> args = new ArrayList<String>();5051public int getResult() {52return result;53}5455public void clearArgs() {56this.args.clear();57}5859public void addArg(String arg) {60this.args.add(arg);61}6263public void addArgs(String[] args) {64for (String arg : args) {65this.args.add(arg);66}67}6869public void addArgs(Collection<String> args) {70this.args.addAll(args);71}7273private void printCommandLine() {74for (String arg : args) {75System.out.println(arg);76}77}7879/*80* Start process.81*/82public void start() {83if (process != null) {84throw new TestBug("Process is already started");85}86printCommandLine();87try {88process = createProcess();89stdoutReader.setDescription("stdout: " + toString());90stdoutReader.setStream(process.getInputStream());91stderrReader.setDescription("stderr: " + toString());92stderrReader.setStream(process.getErrorStream());93stdin = process.getOutputStream();94stdoutReader.start();95stderrReader.start();96waiter.start();97} catch (IOException e) {98throw new TestFailure("Error running process: " + toString(), e);99}100}101102protected Process createProcess() throws IOException {103String[] commandLine = args.toArray(new String[args.size()]);104return Runtime.getRuntime().exec(commandLine);105}106107/**108* Run and wait for completion.109*/110public int execute(long timeout) {111if (timeout <= 0) {112throw new TestBug("Positive timeout is required");113}114start();115return waitFor(timeout);116}117118public int waitFor(long timeout) {119if (process == null) {120throw new TestBug("Process is not yet started");121}122if (timeout <= 0) {123throw new TestBug("Positive timeout is required");124}125long timeleft = timeout;126long startTime = 0;127while (timeleft > 0) {128try {129startTime = System.currentTimeMillis();130waiter.join(timeout);131return result;132} catch (InterruptedException e) {133e.printStackTrace();134}135timeleft -= (System.currentTimeMillis() - startTime);136}137return -1;138}139140public int getPid() {141return ProcessUtils.getPid(process);142}143144public OutputStream getStdIn() {145if (process == null) {146throw new TestBug(147"Process is not running; prepare writers after it is started");148}149return stdin;150}151152public PrintStream getStdInPrint() {153return new PrintStream(getStdIn(),154true); // Autoflush is important here.155}156157/*158public InputStream getStdOut() {159if (process != null)160throw new TestBug("Process is already running; prepare readers before it is started or some output may be missed");161return stdoutReader.getInputStream();162}163164public BufferedReader getStdOutReader() {165return new BufferedReader(new InputStreamReader(getStdOut()));166}167168public InputStream getStdErr() {169if (process != null)170throw new TestBug("Process is already running; prepare readers before it is started or some output may be missed");171return stderrReader.getInputStream();172}173174public BufferedReader getStdErrReader() {175return new BufferedReader(new InputStreamReader(getStdOut()));176}177178public String getStdoutOutput() {179if (stdoutReader == null)180throw new TestBug("Process is not running");181return stdoutReader.getOutput();182}183184public String getStderrOutput() {185if (stderrReader == null)186throw new TestBug("Process is not running");187return stderrReader.getOutput();188}189*/190191public void addStdOutListener(StreamListener l) {192stdoutReader.addListener(l);193}194195public void addStdErrListener(StreamListener l) {196stderrReader.addListener(l);197}198199public void logStdOut(String prefix, Log log) {200stdoutReader.addListener(new StreamLogger(prefix, log));201}202203public void logStdErr(String prefix, Log log) {204stderrReader.addListener(new StreamLogger(prefix, log));205}206207public void logStdOutErr(String prefix, Log log) {208logStdOut(prefix, log);209logStdErr("(stderr)" + prefix, log);210}211212public boolean isStarted() {213return (process != null);214}215216public void kill() {217if (process == null) {218throw new TestBug("Process is not running");219}220process.destroy();221if (stdoutReader != null) {222stdoutReader.kill();223}224if (stderrReader != null) {225stderrReader.kill();226}227if (waiter != null && waiter.isAlive()) {228waiter.kill();229}230process = null;231}232233public void finish() {234if (stdoutReader != null) {235try {236stdoutReader.join(CLEANUP_TIMEOUT);237} catch (InterruptedException e) {238e.printStackTrace();239}240stdoutReader = null;241}242if (stderrReader != null) {243try {244stderrReader.join(CLEANUP_TIMEOUT);245} catch (InterruptedException e) {246e.printStackTrace();247}248stderrReader = null;249}250process = null;251}252253public String toString() {254String ts = "";255if (args != null) {256for (String s : args) {257ts += s;258ts += " ";259}260}261return ts;262}263264private class Waiter extends Thread {265public Waiter() {266super("Process Waiter: (not setup)");267setDaemon(true);268}269270public void run() {271setName("Process Waiter: " + ProcessExecutor.this);272try {273result = process.waitFor();274} catch (InterruptedException e) {275// Ignore276}277}278279public void kill() {280this.interrupt();281long timeleft = CLEANUP_TIMEOUT;282long startTime = 0;283while (timeleft > 0) {284try {285startTime = System.currentTimeMillis();286this.join(timeleft);287return;288} catch (InterruptedException e) {289e.printStackTrace();290}291timeleft -= (System.currentTimeMillis() - startTime);292}293}294}295}296297298