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