Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/SerialExecutionDebugger.java
41161 views
1
/*
2
* Copyright (c) 2006, 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
package nsk.share.jdi;
24
25
import nsk.share.Consts;
26
import nsk.share.TestBug;
27
import nsk.share.jpda.AbstractDebuggeeTest;
28
import java.io.*;
29
import java.util.*;
30
import jdk.test.lib.Utils;
31
32
/*
33
* This class serial executes several JDI tests based on nsk.share.jdi.TestDebuggerType2 in single VM
34
* SerialExecutionDebugger is used together with SerialExecutionDebuggee, execution process is following:
35
*
36
* - SerialExecutionDebugger reads tests to execute from input file, test description is debugger class name and test's parameters,
37
* if 'shuffle' option is specified in input file debugger executes tests in random order (input file should contain line "OPTIONS:shuffle").
38
* SerialExecutionDebugger can execute tests several times in loop, number of iterations should be specified in input file in following manner:
39
* OPTIONS:iterations <iterations_number>.
40
*
41
* - SerialExecutionDebugger starts debuggee VM with main class SerialExecutionDebuggee,
42
* initializes IOPipe and 'debuggee' object which represents debuggee VM
43
*
44
* - for each test from input file:
45
*
46
* - SerialExecutionDebugger creates object of current debugger and initializes it with already created pipe and debuggee
47
* - SerialExecutionDebugger sends command to SerialExecutionDebuggee: 'COMMAND_EXECUTE_DEBUGGEE <CurrentDebuggeeName>'
48
* (CurrentDebuggeeName name should provide current debugger), and waits READY signal from debuggee
49
* - SerialExecutionDebuggee parses received command, extracts debugee name, creates object of current debuggee, which should be
50
* subclass of nsk.share.jpda.AbstractDebuggeeTestName
51
* - SerialExecutionDebuggee executes current debuggee's method 'doTest()', in this method debuggee sends signal READY
52
* and waits debugger command
53
* - SerialExecutionDebugger receives signal READY and executes current debugger's method 'doTest()', in
54
* this method debugger should perform test
55
* - when debugger method doTest() finishes SerialExecutionDebugger checks is this test passed or failed and
56
* sends command QUIT to the current debuggee, and when current debuggee finishes sends command 'COMMAND_CLEAR_DEBUGGEE' to the SerialExecutionDebuggee,
57
* after this command SerialExecutionDebugger and SerialExecutionDebuggee ready to execute next test
58
*
59
* - when all tests was executed SerialExecutionDebugger sends command QUIT to the SerialExecutionDebuggee and exits
60
*
61
* SerialExecutionDebugger requires "-configFile <ini-file>" parameter, <ini-file> - file with list of tests for execution
62
*/
63
public class SerialExecutionDebugger extends TestDebuggerType2 {
64
static public void main(String[] args) {
65
System.exit(Consts.JCK_STATUS_BASE + new SerialExecutionDebugger().runIt(args, System.out));
66
}
67
68
public String debuggeeClassName() {
69
return SerialExecutionDebuggee.class.getName();
70
}
71
72
// contains test's debugger class name and test parameters
73
static class Test {
74
public Test(String debuggerClassName, String[] arguments) {
75
this.debuggerClassName = debuggerClassName;
76
this.arguments = arguments;
77
}
78
79
public String argumentsToString() {
80
String result = "";
81
82
for (String argument : arguments)
83
result += argument + " ";
84
85
return result;
86
}
87
88
String debuggerClassName;
89
90
String arguments[];
91
}
92
93
private Test tests[];
94
95
// how many times execute tests
96
private int iterations = 1;
97
98
// requires "-configFile <ini-file>" parameter, <ini-file> - file with list
99
// of tests for execution
100
protected String[] doInit(String args[], PrintStream out) {
101
args = super.doInit(args, out);
102
103
String configFileName = null;
104
105
ArrayList<String> standardArgs = new ArrayList<String>();
106
107
for (int i = 0; i < args.length; i++) {
108
if (args[i].equals("-configFile") && (i < args.length - 1)) {
109
configFileName = args[i + 1];
110
i++;
111
} else
112
standardArgs.add(args[i]);
113
}
114
115
if (configFileName == null) {
116
throw new TestBug("Config file wasn't specified (use option -configFile <file name>)");
117
}
118
119
tests = parseConfigFile(configFileName);
120
121
if (tests.length == 0)
122
throw new TestBug("Tests to run were not specified");
123
124
return standardArgs.toArray(new String[] {});
125
}
126
127
// read test names and test parameters from ini-file
128
private Test[] parseConfigFile(String fileName) {
129
List<Test> result = new ArrayList<Test>();
130
131
boolean shuffle = false;
132
133
try {
134
File file = new File(fileName);
135
136
LineNumberReader lineReader = new LineNumberReader(new FileReader(file));
137
138
String line = null;
139
140
while ((line = lineReader.readLine()) != null) {
141
// skip empty lines and comments started with '#"
142
if (line.length() == 0 || line.startsWith("#"))
143
continue;
144
145
if (line.startsWith("OPTIONS:")) {
146
String arguments[] = line.substring(8).split(" ");
147
148
for (int i = 0; i < arguments.length; i++) {
149
if (arguments[i].equalsIgnoreCase("shuffle"))
150
shuffle = true;
151
else if (arguments[i].equalsIgnoreCase("iterations") && (i < (arguments.length - 1))) {
152
iterations = Integer.parseInt(arguments[i + 1]);
153
i++;
154
}
155
}
156
157
continue;
158
}
159
160
StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(line));
161
tokenizer.resetSyntax();
162
tokenizer.wordChars(Integer.MIN_VALUE, Integer.MAX_VALUE);
163
tokenizer.whitespaceChars(' ', ' ');
164
165
if (tokenizer.nextToken() != StreamTokenizer.TT_WORD)
166
throw new TestBug("Invalid ini file format");
167
168
String testClassName = tokenizer.sval;
169
List<String> parameters = new ArrayList<String>();
170
171
int token;
172
while ((token = tokenizer.nextToken()) != StreamTokenizer.TT_EOF) {
173
if (token == StreamTokenizer.TT_WORD) {
174
if (tokenizer.sval.equals("$CLASSPATH"))
175
parameters.add(classpath);
176
else
177
parameters.add(tokenizer.sval);
178
}
179
180
if (token == StreamTokenizer.TT_NUMBER) {
181
parameters.add("" + tokenizer.nval);
182
}
183
}
184
185
result.add(new Test(testClassName, parameters.toArray(new String[] {})));
186
}
187
188
} catch (IOException e) {
189
throw new TestBug("Exception during config file parsing: " + e);
190
}
191
192
if (shuffle) {
193
if (testWorkDir == null)
194
throw new TestBug("Debugger requires -testWorkDir parameter");
195
196
Collections.shuffle(result, Utils.getRandomInstance());
197
198
// save resulted tests sequence in file (to simplify reproducing)
199
try {
200
File file = new File(testWorkDir + File.separator + "run.tests");
201
file.createNewFile();
202
203
PrintWriter writer = new PrintWriter(new FileWriter(file));
204
205
for (Test test : result) {
206
writer.println(test.debuggerClassName + " " + test.argumentsToString());
207
}
208
209
writer.close();
210
} catch (IOException e) {
211
throw new TestBug("Unexpected IOException: " + e);
212
}
213
}
214
215
System.out.println("Tests execution order: ");
216
for (Test test : result) {
217
System.out.println(test.debuggerClassName + " " + test.argumentsToString());
218
}
219
220
return result.toArray(new Test[] {});
221
}
222
223
public void doTest() {
224
225
stresser.start(iterations);
226
227
try {
228
if (iterations == 1) {
229
/*
230
* Since many test couldn't be run in single VM twice and test config specifies only 1 iteration don't
231
* multiple iterations by iterations factor and execute tests once (not depending on iterations factor)
232
*/
233
executeTests();
234
} else {
235
while (stresser.continueExecution()) {
236
if (!executeTests()) {
237
// if error occured stop execution
238
break;
239
}
240
}
241
}
242
} finally {
243
stresser.finish();
244
}
245
}
246
247
boolean executeTests() {
248
// maximum execution time of single test
249
long maxExecutionTime = 0;
250
251
for (Test test : tests) {
252
long testStartTime = System.currentTimeMillis();
253
254
TestDebuggerType2 debugger = null;
255
256
try {
257
// create debugger object
258
Class debuggerClass = Class.forName(test.debuggerClassName);
259
260
if (!TestDebuggerType2.class.isAssignableFrom(debuggerClass)) {
261
setSuccess(false);
262
log.complain("Invalid debugger class: " + debuggerClass);
263
return false;
264
}
265
266
// init test debugger, pass to the debugger already created
267
// objects: argHandler, log, pipe, debuggee, vm
268
debugger = (TestDebuggerType2) debuggerClass.newInstance();
269
debugger.initDebugger(argHandler, log, pipe, debuggee, vm);
270
debugger.doInit(test.arguments, System.out);
271
} catch (Exception e) {
272
setSuccess(false);
273
log.complain("Unexpected exception during debugger initialization: " + e);
274
e.printStackTrace(log.getOutStream());
275
276
return false;
277
}
278
279
log.display("Execute debugger: " + debugger);
280
281
// send command to the SerialExecutionDebuggee (create debuggee
282
// object)
283
pipe.println(SerialExecutionDebuggee.COMMAND_EXECUTE_DEBUGGEE + ":" + debugger.debuggeeClassName());
284
285
// wait first READY from AbstractDebuggeeTest.doTest() (debuggee
286
// sends this command when it was initialized and ready for
287
// test)
288
if (!isDebuggeeReady())
289
return false;
290
291
try {
292
// here debuggee should be ready for test and current
293
// debugger may perform test
294
debugger.doTest();
295
296
if (debugger.getSuccess()) {
297
log.display("Debugger " + debugger + " finished successfully");
298
} else {
299
setSuccess(false);
300
log.complain("Debugger " + debugger + " finished with errors");
301
}
302
} catch (TestBug testBug) {
303
setSuccess(false);
304
log.complain("Test bug in " + debugger + ": " + testBug);
305
testBug.printStackTrace(log.getOutStream());
306
} catch (Throwable t) {
307
setSuccess(false);
308
log.complain("Unexpected exception during test execution(debugger: " + debugger + "): " + t);
309
t.printStackTrace(log.getOutStream());
310
}
311
312
// send QUIT command to the current debuggee
313
pipe.println(AbstractDebuggeeTest.COMMAND_QUIT);
314
315
if (!isDebuggeeReady())
316
return false;
317
318
// send command to the SerialExecutionDebuggee
319
pipe.println(SerialExecutionDebuggee.COMMAND_CLEAR_DEBUGGEE);
320
321
if (!isDebuggeeReady())
322
return false;
323
324
long testExecutionTime = System.currentTimeMillis() - testStartTime;
325
326
if (testExecutionTime > maxExecutionTime)
327
maxExecutionTime = testExecutionTime;
328
329
if (maxExecutionTime > stresser.getTimeLeft()) {
330
log.display("WARNING: stop test execution because of timeout " +
331
"(max execution time for single test: " + maxExecutionTime + ", time left: " + stresser.getTimeLeft() + ")");
332
return false;
333
}
334
}
335
336
return true;
337
}
338
}
339
340