1 /*
   2  * Copyright (c) 2013, 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 java.io.IOException;
  25 import java.io.File;
  26 import java.nio.file.Files;
  27 import java.util.Arrays;
  28 
  29 import jdk.test.lib.thread.ProcessThread;
  30 import jdk.test.lib.process.ProcessTools;
  31 import jdk.test.lib.Utils;
  32 
  33 /*
  34  * Utility functions for test runners.
  35  * (Test runner = class that launch a test)
  36  */
  37 public class RunnerUtil {
  38 
  39     /**
  40      * The Application process must be run concurrently with our tests since
  41      * the tests will attach to the Application.
  42      * We will run the Application process in a separate thread.
  43      *
  44      * The Application must be started with flag "-Xshare:off" for the Retransform
  45      * test in TestBasics to pass on all platforms.
  46      *
  47      * The Application will write its pid and shutdownPort in the given outFile.
  48      */
  49     public static ProcessThread startApplication(String... additionalOpts) throws Throwable {
  50         String classpath = System.getProperty("test.class.path", ".");
  51         String[] myArgs = concat(additionalOpts, new String [] {
  52             "-XX:+UsePerfData", "-XX:+EnableDynamicAgentLoading",
  53             "-Dattach.test=true", "-classpath", classpath, "Application"
  54         });
  55         String[] args = Utils.addTestJavaOpts(myArgs);
  56         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
  57         ProcessThread pt = new ProcessThread("runApplication", (line) -> line.equals(Application.READY_MSG), pb);
  58         pt.start();
  59         return pt;
  60     }
  61 
  62     public static String[] concat(String[] a, String[] b) {
  63         if (a == null) {
  64             return b;
  65         }
  66         if (b == null) {
  67             return a;
  68         }
  69         int aLen = a.length;
  70         int bLen = b.length;
  71         String[] c = new String[aLen + bLen];
  72         System.arraycopy(a, 0, c, 0, aLen);
  73         System.arraycopy(b, 0, c, aLen, bLen);
  74         return c;
  75      }
  76 
  77     /**
  78      * Will stop the running Application.
  79      * First tries to shutdown nicely by connecting to the shut down port.
  80      * If that fails, the process will be killed hard with stopProcess().
  81      *
  82      * If the nice shutdown fails, then an Exception is thrown and the test should fail.
  83      *
  84      * @param processThread The process to stop.
  85      */
  86     public static void stopApplication(ProcessThread processThread) throws Throwable {
  87         if (processThread == null) {
  88             System.out.println("RunnerUtil.stopApplication ignored since proc is null");
  89             return;
  90         }
  91         try {
  92             System.out.println("RunnerUtil.stopApplication waiting for shutdown");
  93             processThread.sendMessage(Application.SHUTDOWN_MSG);
  94             processThread.joinAndThrow();
  95             processThread.getOutput().shouldHaveExitValue(0);
  96         } catch (Throwable t) {
  97             System.out.println("RunnerUtil.stopApplication failed. Will kill it hard: " + t);
  98             processThread.stopProcess();
  99             throw t;
 100         }
 101     }
 102 
 103     /**
 104      * Creates a jar file.
 105      * @param args Command to the jar tool.
 106      */
 107     public static void createJar(String... args) {
 108         System.out.println("Running: jar " + Arrays.toString(args));
 109         sun.tools.jar.Main jar = new sun.tools.jar.Main(System.out, System.err, "jar");
 110         if (!jar.run(args)) {
 111             throw new RuntimeException("jar failed: args=" + Arrays.toString(args));
 112         }
 113     }
 114 
 115     /**
 116      * Read the content of a file.
 117      * @param file The file to read.
 118      * @return The file content or null if file does not exists.
 119      */
 120     public static String readFile(File file) throws IOException {
 121         if (!file.exists()) {
 122             return null;
 123         }
 124         try {
 125             byte[] bytes = Files.readAllBytes(file.toPath());
 126             String content = new String(bytes);
 127             return content;
 128         } catch (IOException e) {
 129             e.printStackTrace();
 130             throw e;
 131         }
 132     }
 133 }