Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/RASagent.java
40948 views
1
/*
2
* Copyright (c) 2002, 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
package nsk.share;
25
26
import java.io.*;
27
import java.lang.reflect.Method;
28
import java.util.*;
29
30
/**
31
* Class used as an agent for Java serviceability reliability testing (RAS).
32
* It sets different RAS options and/or modes for a special agent which
33
* actually performs the specified RAS testing.<br>
34
* The agent recognizes arguments, started with ''<code>-ras.</code>''. They
35
* may be as follows:<p>
36
* <li><code>-ras.help</code> - print usage message and exit
37
* <li><code>-ras.verbose</code> - verbose mode
38
* <li><code>-ras.invoke_run</code> - invoke the method <i>run(String[],PrintStream)</i>
39
* of the test instead of <i>main(String[])</i> which is invoked by default.
40
* <li><code>-ras.hotswap=&lt;stress_level&gt;</code> - enable JVMTI hotswap of
41
* the currently running test classes. Here are the possible HotSwap stress
42
* levels:<br>
43
* 0 - HotSwap off<br>
44
* 2 - HotSwap tested class in every JVMTI method entry event of running test
45
* (default mode)<br>
46
* 20 - HotSwap tested class in every JVMTI method entry event of every class<br>
47
* 3 - HotSwap tested class in every JVMTI single step event of running test<br>
48
* 4 - HotSwap tested class in every JVMTI exception event of running test<br>
49
* 40 - HotSwap tested class in every JVMTI exception event of every class<p>
50
*/
51
public class RASagent {
52
static final int HOTSWAP_OFF = 0;
53
static final int HOTSWAP_EVERY_METHOD_ENTRY = 2;
54
static final int HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS = 20;
55
static final int HOTSWAP_EVERY_SINGLE_STEP = 3;
56
static final int HOTSWAP_EVERY_EXCEPTION = 4;
57
static final int HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS = 40;
58
59
// path to the directory with class files of the invoked test
60
static String clfBasePath = null;
61
62
private static boolean verbose = false;
63
64
private static PrintStream out;
65
66
native static int setHotSwapMode(boolean vrb, int stress_lev,
67
String shortName);
68
69
public static void main(String argv[]) {
70
System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE);
71
}
72
73
public static int run(String argv[], PrintStream out) {
74
return new RASagent().runThis(argv, out);
75
}
76
77
private int runThis(String argv[], PrintStream out) {
78
int skipArgs = 1; // number of arguments which must be skipped
79
// for the invoked test
80
boolean invokeRun = false; // invoke the method "main" by default
81
int hotSwapMode = HOTSWAP_EVERY_METHOD_ENTRY; // HotSwap default stress level
82
int res;
83
String hotSwapModeName = "HOTSWAP_EVERY_METHOD_ENTRY";
84
85
RASagent.out = out;
86
87
if (argv.length != 0) {
88
// parse arguments for the RASagent and then skip them
89
while(argv[skipArgs-1].startsWith("-ras.")) {
90
if (argv[skipArgs-1].equals("-ras.verbose")) {
91
verbose = true;
92
} else if (argv[skipArgs-1].equals("-ras.help")) {
93
printHelp();
94
return Consts.TEST_FAILED;
95
} else if (argv[skipArgs-1].equals("-ras.invoke_run")) {
96
invokeRun = true;
97
} else if (argv[skipArgs-1].startsWith("-ras.hotswap=")) {
98
try {
99
hotSwapMode = Integer.parseInt(
100
argv[skipArgs-1].substring(argv[skipArgs-1].lastIndexOf("=")+1));
101
} catch (NumberFormatException e) {
102
e.printStackTrace();
103
out.println("\nERROR: RASagent: specified HotSwap mode \""
104
+ hotSwapMode + "\" is not an integer");
105
printHelp();
106
return Consts.TEST_FAILED;
107
}
108
switch(hotSwapMode) {
109
case HOTSWAP_EVERY_METHOD_ENTRY:
110
hotSwapModeName = "HOTSWAP_EVERY_METHOD_ENTRY";
111
break;
112
case HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS:
113
hotSwapModeName = "HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS";
114
break;
115
case HOTSWAP_EVERY_SINGLE_STEP:
116
hotSwapModeName = "HOTSWAP_EVERY_SINGLE_STEP";
117
break;
118
case HOTSWAP_EVERY_EXCEPTION:
119
hotSwapModeName = "HOTSWAP_EVERY_EXCEPTION";
120
break;
121
case HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS:
122
hotSwapModeName = "HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS";
123
break;
124
default:
125
out.println("\nERROR: RASagent: specified HotSwap mode \""
126
+ hotSwapMode + "\" is unrecognized");
127
printHelp();
128
return Consts.TEST_FAILED;
129
}
130
}
131
skipArgs++;
132
}
133
134
String shortTestName = getTestNameAndPath(argv[skipArgs-1]);
135
136
display("\n#### RASagent: setting hotswap mode \""
137
+ hotSwapModeName + "\" for class \""
138
+ shortTestName + "\" ...");
139
if ((res = setHotSwapMode(verbose, hotSwapMode, shortTestName)) != 0) {
140
out.println("\nERROR: RASagent: unable to set HotSwap stress level for \""
141
+ shortTestName + "\", exiting");
142
return Consts.TEST_FAILED;
143
}
144
display("\n#### RASagent: ... setting hotswap mode done");
145
146
try {
147
Class testCls = Class.forName(argv[skipArgs-1]);
148
display("\n#### RASagent: main class \""
149
+ testCls.toString() + "\" loaded");
150
151
// copy arguments for the invoked test
152
String args[] = new String[argv.length-skipArgs];
153
System.arraycopy(argv, skipArgs, args, 0, args.length);
154
155
// invoke the test
156
if (invokeRun)
157
return invokeRunMethod(testCls, args);
158
else
159
return invokeMainMethod(testCls, args);
160
} catch(ClassNotFoundException e) {
161
// just pass: the invoked test is already a RAS specific one
162
out.println("\nWARNING: the test was not really run due to the following error:"
163
+ "\n\tunable to get the Class object for \""
164
+ argv[skipArgs-1] + "\"\n\tcaught: " + e);
165
return Consts.TEST_PASSED;
166
}
167
168
} else {
169
out.println("\nERROR: RASagent: required test name is absent in parameters list");
170
return Consts.TEST_FAILED;
171
}
172
}
173
174
/**
175
* Verify that test's class file exists with a path given as a parameter
176
* and, if so, store that path in the static field "clfBasePath".
177
*/
178
private boolean pathValid(String pathToCheck, String testName) {
179
String fullPath = pathToCheck + File.separator
180
+ testName.replace('.', File.separatorChar) + ".class";
181
File classFile = null;
182
183
display("\n#### RASagent: verifying class path\n<RASagent>\t"
184
+ pathToCheck + " ...");
185
try {
186
classFile = new File(fullPath);
187
} catch (NullPointerException e) {
188
e.printStackTrace();
189
out.println("\nERROR: RASagent: verification of class file "
190
+ fullPath + " failed: caught " + e);
191
System.exit(Consts.JCK_STATUS_BASE + Consts.TEST_FAILED);
192
}
193
194
if (classFile.exists()) {
195
clfBasePath = pathToCheck;
196
display("<RASagent>\tthe class file exists:\n<RASagent>\t\t"
197
+ fullPath + "\n<RASagent>\tclass file base directory found:\n"
198
+ "<RASagent>\t\t" + clfBasePath
199
+ "\n#### RASagent: ... class path verification done\n");
200
return true;
201
}
202
else {
203
display("<RASagent>\tno class file at location :\n\t\t"
204
+ fullPath
205
+ "\n#### RASagent: ... class path verification done\n");
206
return false;
207
}
208
}
209
210
/**
211
* Get short name of an invoked test (i.e. without package name) and
212
* store path to the directory with the test's class files.
213
*/
214
private String getTestNameAndPath(String testName) {
215
String shortTestName = testName;
216
String packageName = "";
217
218
// if '.' occurs, it means that current test is inside a package
219
if (testName.lastIndexOf(".") != -1) {
220
shortTestName = testName.substring(testName.lastIndexOf(".")+1);
221
packageName = testName.substring(0, testName.lastIndexOf("."));
222
}
223
224
StringTokenizer clPathes = new StringTokenizer(
225
System.getProperty("java.class.path"), File.pathSeparator);
226
227
while(clPathes.hasMoreTokens()) {
228
String clPath = clPathes.nextToken();
229
230
// trying to load a class file defining the current test from
231
// this entry of "java.class.path": the class file may locate
232
// at the test's work directory or if it's already compiled,
233
// at any directory in classpath
234
if (pathValid(clPath, testName))
235
return shortTestName;
236
}
237
238
// directory with the test's class files was not found.
239
// Actually, it means that the invoked test has own Java
240
// options such as, for example, "-verify"
241
out.println("\nWARNING: the test was not really run due to the following reason:"
242
+ "\n\tthe invoked test has the own Java option: "
243
+ testName);
244
System.exit(Consts.JCK_STATUS_BASE + Consts.TEST_PASSED);
245
246
return null; // fake return for too smart javac
247
}
248
249
/**
250
* Invoke the method <i>main(String[])</i> of the test.
251
*/
252
private int invokeMainMethod(Class testCls, String args[]) {
253
Class[] methType = { String[].class };
254
Object[] methArgs = { args };
255
256
return invokeMethod(testCls, "main", methType, methArgs);
257
}
258
259
/**
260
* Invoke the method <i>run(String[], PrintStream)</i> of the test.
261
*/
262
private int invokeRunMethod(Class testCls, String args[]) {
263
Class[] methType = { String[].class, PrintStream.class };
264
Object[] methArgs = { args, out };
265
266
return invokeMethod(testCls, "run", methType, methArgs);
267
}
268
269
/**
270
* Low level invocation of the test.
271
*/
272
private int invokeMethod(Class<?> testCls, String methodName,
273
Class methType[], Object methArgs[]) {
274
275
try {
276
Method testMeth = testCls.getMethod(methodName, methType);
277
display("\n#### RASagent: invoking method \""
278
+ testMeth.toString() + "\" ...");
279
280
Object result = testMeth.invoke(null, methArgs);
281
282
display("\n#### RASagent: ... invocation of \""
283
+ testMeth.toString() + "\" done");
284
if (result instanceof Integer) {
285
Integer retCode = (Integer) result;
286
return retCode.intValue();
287
}
288
} catch(NoSuchMethodException e) {
289
e.printStackTrace();
290
out.println("\nFAILURE: RASagent: unable to get method \""
291
+ methodName + "\" in class "
292
+ testCls + "\n\tcaught " + e);
293
return Consts.TEST_FAILED;
294
} catch(Exception e) {
295
e.printStackTrace();
296
out.println("\nFAILURE: RASagent: caught during invokation of the test class "
297
+ testCls + " " + e);
298
return Consts.TEST_FAILED;
299
}
300
301
return -1;
302
}
303
304
/**
305
* Load class bytes for HotSwap.
306
*/
307
static byte[] loadFromClassFile(String signature) {
308
String testPath = clfBasePath + File.separator + signature.substring(
309
1, signature.length()-1).replace('/', File.separatorChar) + ".class";
310
File classFile = null;
311
312
display("\n#### RASagent: looking for class file\n<RASagent>\t"
313
+ testPath + " ...");
314
315
try {
316
classFile = new File(testPath);
317
} catch (NullPointerException e) {
318
out.println("\nFAILURE: RASagent: path name to the redefining class file is null");
319
}
320
321
display("\n#### RASagent: loading " + classFile.length()
322
+ " bytes from class file "+ testPath + " ...");
323
byte[] buf = new byte[(int) classFile.length()];
324
try {
325
InputStream in = new FileInputStream(classFile);
326
in.read(buf);
327
in.close();
328
} catch(FileNotFoundException e) {
329
e.printStackTrace();
330
out.println("\nFAILURE: RASagent: loadFromClassFile: file " +
331
classFile.getName() + " not found");
332
System.exit(Consts.JCK_STATUS_BASE + Consts.TEST_FAILED);
333
} catch (Exception e) {
334
e.printStackTrace();
335
out.println("\nFAILURE: RASagent: unable to load bytes from the file:\n");
336
out.println("\t" + testPath + ": caught " + e);
337
System.exit(Consts.JCK_STATUS_BASE + Consts.TEST_FAILED);
338
}
339
340
display("\n#### RASagent: ... " + classFile.length() + " bytes loaded");
341
342
return buf;
343
}
344
345
/**
346
* This method is used in verbose mode. It prints paramter string only
347
* in case of verbose mode.
348
*/
349
private static void display(String msg) {
350
if (verbose)
351
out.println(msg);
352
}
353
354
/**
355
* This method prints out RASagent usage message.
356
*/
357
private static void printHelp() {
358
out.println("\nRASagent usage: RASagent [option, ...] test" +
359
"\n\t-ras.help print this message and exit" +
360
"\n\t-ras.verbose verbose mode (off by default)" +
361
"\n\t-ras.hotswap=mode enable HotSwap of the running test classes" +
362
"\n\t\twhere mode is:" +
363
"\n\t\t\t" + HOTSWAP_EVERY_METHOD_ENTRY
364
+ " - hotswap tested class in its every method entry event" +
365
"\n\t\t\t" + HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS
366
+ " - hotswap tested class in every method entry event for every class" +
367
"\n\t\t\t" + HOTSWAP_EVERY_SINGLE_STEP
368
+ " - hotswap tested class in its every single step event" +
369
"\n\t\t\t" + HOTSWAP_EVERY_EXCEPTION
370
+ " - hotswap tested class in its every exception event" +
371
"\n\t\t\t" + HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS
372
+ " - hotswap tested class in every exception event for every class\n" +
373
"\n\t-ras.invoke_run invoke the method run() of the test" +
374
"\n\t\tinstead of main() by default");
375
}
376
}
377
378