Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/com/sun/tools/attach/RunnerUtil.java
38855 views
1
/*
2
* Copyright (c) 2013, 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
import java.util.regex.Pattern;
29
import java.util.regex.Matcher;
30
31
import jdk.testlibrary.OutputAnalyzer;
32
import jdk.testlibrary.ProcessTools;
33
import jdk.testlibrary.Utils;
34
import jdk.testlibrary.ProcessThread;
35
36
/*
37
* Utility functions for test runners.
38
* (Test runner = class that launch a test)
39
*/
40
public class RunnerUtil {
41
42
/**
43
* The Application process must be run concurrently with our tests since
44
* the tests will attach to the Application.
45
* We will run the Application process in a separate thread.
46
*
47
* The Application must be started with flag "-Xshare:off" for the Retransform
48
* test in TestBasics to pass on all platforms.
49
*
50
* The Application will write its pid and shutdownPort in the given outFile.
51
*/
52
public static ProcessThread startApplication(String outFile, String... additionalOpts) throws Throwable {
53
String classpath = System.getProperty("test.class.path", ".");
54
String[] myArgs = concat(additionalOpts, new String [] { "-Dattach.test=true", "-classpath", classpath, "Application", outFile });
55
String[] args = Utils.addTestJavaOpts(myArgs);
56
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
57
ProcessThread pt = new ProcessThread("runApplication", 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 port The shut down port.
85
* @param processThread The process to stop.
86
*/
87
public static void stopApplication(int port, ProcessThread processThread) throws Throwable {
88
if (processThread == null) {
89
System.out.println("RunnerUtil.stopApplication ignored since proc is null");
90
return;
91
}
92
try {
93
System.out.println("RunnerUtil.stopApplication waiting to for shutdown");
94
OutputAnalyzer output = ProcessTools.executeTestJvm(
95
"-classpath",
96
System.getProperty("test.class.path", "."),
97
"Shutdown",
98
Integer.toString(port));
99
// Verify that both the Shutdown command and the Application finished ok.
100
output.shouldHaveExitValue(0);
101
processThread.joinAndThrow();
102
processThread.getOutput().shouldHaveExitValue(0);
103
} catch (Throwable t) {
104
System.out.println("RunnerUtil.stopApplication failed. Will kill it hard: " + t);
105
processThread.stopProcess();
106
throw t;
107
}
108
}
109
110
/**
111
* Creates a jar file.
112
* @param args Command to the jar tool.
113
*/
114
public static void createJar(String... args) {
115
System.out.println("Running: jar " + Arrays.toString(args));
116
sun.tools.jar.Main jar = new sun.tools.jar.Main(System.out, System.err, "jar");
117
if (!jar.run(args)) {
118
throw new RuntimeException("jar failed: args=" + Arrays.toString(args));
119
}
120
}
121
122
/**
123
* Read process info for the running Application.
124
* The Application writes its info to a file with this format:
125
* shutdownPort=42994
126
* pid=19597
127
* done
128
*
129
* The final "done" is used to make sure the complete file has been written
130
* before we try to read it.
131
* This function will wait until the file is available.
132
*
133
* @param filename Path to file to read.
134
* @return The ProcessInfo containing pid and shutdownPort.
135
*/
136
public static ProcessInfo readProcessInfo(String filename) throws Throwable {
137
System.out.println("Reading port and pid from file: " + filename);
138
File file = new File(filename);
139
String content = null;
140
141
// Read file or wait for it to be created.
142
long startTime = System.currentTimeMillis();
143
long lastWarningTime = 0;
144
while (true) {
145
content = readFile(file);
146
if (content != null && content.indexOf("done") >= 0) {
147
break;
148
}
149
Thread.sleep(100);
150
long elapsedTime = (System.currentTimeMillis() - startTime) / 1000;
151
if (elapsedTime > lastWarningTime) {
152
lastWarningTime = elapsedTime;
153
System.out.println("Waited " + elapsedTime + " seconds for file.");
154
}
155
}
156
157
ProcessInfo info = new ProcessInfo();
158
// search for a line with format: key=nnn
159
Pattern pattern = Pattern.compile("(\\w*)=([0-9]+)\\r?\\n");
160
Matcher matcher = pattern.matcher(content);
161
while (matcher.find()) {
162
String key = matcher.group(1);
163
int value = Integer.parseInt(matcher.group(2));
164
if ("pid".equals(key)) {
165
info.pid = value;
166
} else if ("shutdownPort".equals(key)) {
167
info.shutdownPort = value;
168
}
169
}
170
System.out.println("processInfo.pid:" + info.pid);
171
System.out.println("processInfo.shutdownPort:" + info.shutdownPort);
172
return info;
173
}
174
175
/**
176
* Read the content of a file.
177
* @param file The file to read.
178
* @return The file content or null if file does not exists.
179
*/
180
public static String readFile(File file) throws IOException {
181
if (!file.exists()) {
182
return null;
183
}
184
try {
185
byte[] bytes = Files.readAllBytes(file.toPath());
186
String content = new String(bytes);
187
return content;
188
} catch (IOException e) {
189
e.printStackTrace();
190
throw e;
191
}
192
}
193
194
/**
195
* Helper class with info of the running Application.
196
*/
197
public static class ProcessInfo {
198
public int pid = -1;
199
public int shutdownPort = -1;
200
}
201
202
}
203
204