Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/tools/jstatd/JstatdTest.java
38838 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.File;
25
import java.net.UnknownHostException;
26
import java.rmi.RemoteException;
27
import java.rmi.registry.LocateRegistry;
28
import java.rmi.registry.Registry;
29
import java.util.Arrays;
30
import java.util.regex.Pattern;
31
32
import static jdk.testlibrary.Asserts.*;
33
import jdk.testlibrary.JDKToolLauncher;
34
import jdk.testlibrary.OutputAnalyzer;
35
import jdk.testlibrary.ProcessThread;
36
import jdk.testlibrary.TestThread;
37
import jdk.testlibrary.Utils;
38
import jdk.testlibrary.ProcessTools;
39
40
/**
41
* The base class for tests of jstatd.
42
*
43
* The test sequence for TestJstatdDefaults for example is:
44
* <pre>
45
* {@code
46
* // start jstatd process
47
* jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy
48
*
49
* // run jps and verify its output
50
* jps -J-XX:+UsePerfData hostname
51
*
52
* // run jstat and verify its output
53
* jstat -J-XX:+UsePerfData -J-Duser.language=en -gcutil pid@hostname 250 5
54
*
55
* // stop jstatd process and verify that no unexpected exceptions have been thrown
56
* }
57
* </pre>
58
*/
59
public final class JstatdTest {
60
61
/**
62
* jstat gcutil option: takes JSTAT_GCUTIL_SAMPLES samples at
63
* JSTAT_GCUTIL_INTERVAL_MS millisecond intervals
64
*/
65
private static final int JSTAT_GCUTIL_SAMPLES = 5;
66
private static final int JSTAT_GCUTIL_INTERVAL_MS = 250;
67
private static final String JPS_OUTPUT_REGEX = "^\\d+\\s*.*";
68
69
private boolean useDefaultPort = true;
70
private String port;
71
private String serverName;
72
private String jstatdPid;
73
private boolean withExternalRegistry = false;
74
75
public void setServerName(String serverName) {
76
this.serverName = serverName;
77
}
78
79
public void setUseDefaultPort(boolean useDefaultPort) {
80
this.useDefaultPort = useDefaultPort;
81
}
82
83
public void setWithExternalRegistry(boolean withExternalRegistry) {
84
this.withExternalRegistry = withExternalRegistry;
85
}
86
87
/**
88
* Parse pid from jps output
89
*/
90
private String parsePid(String tool, OutputAnalyzer output) throws Exception {
91
String[] lines = output.getOutput().split(Utils.NEW_LINE);
92
String pid = null;
93
int count = 0;
94
String processName = tool;
95
if (tool == "rmiregistry") {
96
processName = "registryimpl";
97
}
98
99
Pattern toolInJpsPattern =
100
Pattern.compile("^\\d+\\s{1}" + processName + "\\s{1}.*-dparent\\.pid\\." + ProcessTools.getProcessId() + ".*");
101
for (String line : lines) {
102
if (toolInJpsPattern.matcher(line.toLowerCase()).matches()) {
103
pid = line.split(" ")[0];
104
count++;
105
}
106
}
107
if (count > 1) {
108
throw new Exception("Expected one " + tool
109
+ " process, got " + count + ". Test will be canceled.");
110
}
111
112
return pid;
113
}
114
115
private String getToolPid(String tool)
116
throws Exception {
117
OutputAnalyzer output = runJps();
118
return parsePid(tool, output);
119
}
120
121
private String waitOnTool(String tool, TestThread thread) throws Throwable {
122
while (true) {
123
String pid = getToolPid(tool);
124
125
if (pid != null) {
126
System.out.println(tool + " pid: " + pid);
127
return pid;
128
}
129
130
Throwable t = thread.getUncaught();
131
if (t != null) {
132
if (t.getMessage().contains(
133
"java.rmi.server.ExportException: Port already in use")) {
134
System.out.println("Port already in use. Trying to restart with a new one...");
135
Thread.sleep(100);
136
return null;
137
} else {
138
// Something unexpected has happened
139
throw new Throwable(t);
140
}
141
}
142
143
System.out.println("Waiting until " + tool + " is running...");
144
Thread.sleep(100);
145
}
146
}
147
148
private void log(String caption, String... cmd) {
149
System.out.println(Utils.NEW_LINE + caption + ":");
150
System.out.println(Arrays.toString(cmd).replace(",", ""));
151
}
152
153
private String getDestination() throws UnknownHostException {
154
String option = Utils.getHostname();
155
if (port != null) {
156
option += ":" + port;
157
}
158
if (serverName != null) {
159
option += "/" + serverName;
160
}
161
return option;
162
}
163
164
/**
165
* Depending on test settings command line can look like:
166
*
167
* jps -J-XX:+UsePerfData hostname
168
* jps -J-XX:+UsePerfData hostname:port
169
* jps -J-XX:+UsePerfData hostname/serverName
170
* jps -J-XX:+UsePerfData hostname:port/serverName
171
*/
172
private OutputAnalyzer runJps() throws Exception {
173
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jps");
174
launcher.addVMArg("-XX:+UsePerfData");
175
// Run jps with -v flag to obtain -Dparent.pid.<pid>
176
launcher.addToolArg("-v");
177
launcher.addToolArg(getDestination());
178
179
String[] cmd = launcher.getCommand();
180
log("Start jps", cmd);
181
182
ProcessBuilder processBuilder = new ProcessBuilder(cmd);
183
OutputAnalyzer output = new OutputAnalyzer(processBuilder.start());
184
System.out.println(output.getOutput());
185
186
return output;
187
}
188
189
/**
190
* Verifies output form jps contains pids and programs' name information.
191
* The function will discard any lines that come before the first line with pid.
192
* This can happen if the JVM outputs a warning message for some reason
193
* before running jps.
194
*
195
* The output can look like:
196
* 35536 Jstatd
197
* 35417 Main
198
* 31103 org.eclipse.equinox.launcher_1.3.0.v20120522-1813.jar
199
*/
200
private void verifyJpsOutput(OutputAnalyzer output) throws Exception {
201
output.shouldHaveExitValue(0);
202
assertFalse(output.getOutput().isEmpty(), "Output should not be empty");
203
204
boolean foundFirstLineWithPid = false;
205
String[] lines = output.getOutput().split(Utils.NEW_LINE);
206
for (String line : lines) {
207
if (!foundFirstLineWithPid) {
208
foundFirstLineWithPid = line.matches(JPS_OUTPUT_REGEX);
209
continue;
210
}
211
assertTrue(line.matches(JPS_OUTPUT_REGEX),
212
"Output does not match the pattern" + Utils.NEW_LINE + line);
213
}
214
assertTrue(foundFirstLineWithPid, "Invalid output");
215
}
216
217
/**
218
* Depending on test settings command line can look like:
219
*
220
* jstat -J-XX:+UsePerfData -J-Duser.language=en -gcutil pid@hostname 250 5
221
* jstat -J-XX:+UsePerfData -J-Duser.language=en -gcutil pid@hostname:port 250 5
222
* jstat -J-XX:+UsePerfData -J-Duser.language=en -gcutil pid@hostname/serverName 250 5
223
* jstat -J-XX:+UsePerfData -J-Duser.language=en -gcutil pid@hostname:port/serverName 250 5
224
*/
225
private OutputAnalyzer runJstat() throws Exception {
226
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jstat");
227
launcher.addVMArg("-XX:+UsePerfData");
228
launcher.addVMArg("-Duser.language=en");
229
launcher.addToolArg("-gcutil");
230
launcher.addToolArg(jstatdPid + "@" + getDestination());
231
launcher.addToolArg(Integer.toString(JSTAT_GCUTIL_INTERVAL_MS));
232
launcher.addToolArg(Integer.toString(JSTAT_GCUTIL_SAMPLES));
233
234
String[] cmd = launcher.getCommand();
235
log("Start jstat", cmd);
236
237
ProcessBuilder processBuilder = new ProcessBuilder(cmd);
238
OutputAnalyzer output = new OutputAnalyzer(processBuilder.start());
239
System.out.println(output.getOutput());
240
241
return output;
242
}
243
244
private void verifyJstatOutput(OutputAnalyzer output)
245
throws Exception {
246
output.shouldHaveExitValue(0);
247
assertFalse(output.getOutput().isEmpty(), "Output should not be empty");
248
249
JstatGCUtilParser gcUtilParser = new JstatGCUtilParser(
250
output.getOutput());
251
gcUtilParser.parse(JSTAT_GCUTIL_SAMPLES);
252
}
253
254
private void runToolsAndVerify() throws Exception {
255
OutputAnalyzer output = runJps();
256
verifyJpsOutput(output);
257
258
output = runJstat();
259
verifyJstatOutput(output);
260
}
261
262
private Registry startRegistry()
263
throws InterruptedException, RemoteException {
264
Registry registry = null;
265
try {
266
System.out.println("Start rmiregistry on port " + port);
267
registry = LocateRegistry
268
.createRegistry(Integer.parseInt(port));
269
} catch (RemoteException e) {
270
if (e.getMessage().contains("Port already in use")) {
271
System.out.println("Port already in use. Trying to restart with a new one...");
272
Thread.sleep(100);
273
return null;
274
} else {
275
throw e;
276
}
277
}
278
return registry;
279
}
280
281
private void cleanUpThread(ProcessThread thread) throws Throwable {
282
if (thread != null) {
283
thread.stopProcess();
284
thread.joinAndThrow();
285
}
286
}
287
288
/**
289
* Depending on test settings command line can look like:
290
*
291
* jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy
292
* jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy -p port
293
* jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy -n serverName
294
* jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy -p port -n serverName
295
*/
296
private String[] getJstatdCmd() throws Exception {
297
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jstatd");
298
launcher.addVMArg("-XX:+UsePerfData");
299
String testSrc = System.getProperty("test.src");
300
File policy = new File(testSrc, "all.policy");
301
assertTrue(policy.exists() && policy.isFile(),
302
"Security policy " + policy.getAbsolutePath() + " does not exist or not a file");
303
launcher.addVMArg("-Djava.security.policy=" + policy.getAbsolutePath());
304
// -Dparent.pid.<pid> will help to identify jstad process started by this test
305
launcher.addVMArg("-Dparent.pid." + ProcessTools.getProcessId());
306
if (port != null) {
307
launcher.addToolArg("-p");
308
launcher.addToolArg(port);
309
}
310
if (serverName != null) {
311
launcher.addToolArg("-n");
312
launcher.addToolArg(serverName);
313
}
314
315
String[] cmd = launcher.getCommand();
316
log("Start jstatd", cmd);
317
return cmd;
318
}
319
320
private ProcessThread tryToSetupJstatdProcess() throws Throwable {
321
ProcessThread jstatdThread = new ProcessThread("Jstatd-Thread",
322
getJstatdCmd());
323
try {
324
jstatdThread.start();
325
// Make sure jstatd is up and running
326
jstatdPid = waitOnTool("jstatd", jstatdThread);
327
if (jstatdPid == null) {
328
// The port is already in use. Cancel and try with new one.
329
jstatdThread.stopProcess();
330
jstatdThread.join();
331
return null;
332
}
333
} catch (Throwable t) {
334
// Something went wrong in the product - clean up!
335
cleanUpThread(jstatdThread);
336
throw t;
337
}
338
339
return jstatdThread;
340
}
341
342
public void doTest() throws Throwable {
343
ProcessThread jstatdThread = null;
344
try {
345
while (jstatdThread == null) {
346
if (!useDefaultPort || withExternalRegistry) {
347
port = Integer.toString(Utils.getFreePort());
348
}
349
350
if (withExternalRegistry) {
351
Registry registry = startRegistry();
352
if (registry == null) {
353
// The port is already in use. Cancel and try with new one.
354
continue;
355
}
356
}
357
358
jstatdThread = tryToSetupJstatdProcess();
359
}
360
361
runToolsAndVerify();
362
} finally {
363
cleanUpThread(jstatdThread);
364
}
365
366
// Verify output from jstatd
367
OutputAnalyzer output = jstatdThread.getOutput();
368
assertTrue(output.getOutput().isEmpty(),
369
"jstatd should get an empty output, got: "
370
+ Utils.NEW_LINE + output.getOutput());
371
assertNotEquals(output.getExitValue(), 0,
372
"jstatd process exited with unexpected exit code");
373
}
374
375
}
376
377