1 /*
2  * Copyright (c) 2013, 2015, 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.testlibrary.ProcessTools;
30 import jdk.testlibrary.Utils;
31 import jdk.testlibrary.ProcessThread;
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      */
startApplication(String... additionalOpts)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 
concat(String[] a, String[] b)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      */
stopApplication(ProcessThread processThread)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      */
createJar(String... args)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      */
readFile(File file)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 }
134