Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/aod/TargetApplicationWaitingAgents.java
41161 views
1
/*
2
* Copyright (c) 2008, 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
package nsk.share.aod;
24
25
import nsk.share.*;
26
import nsk.share.jpda.SocketIOPipe;
27
28
import java.util.*;
29
30
/*
31
Class TargetApplicationWaitingAgents is part of the framework used in the AttachOnDemand tests
32
(tests against Attach API, API from package com.sun.tools.attach).
33
34
Attach API allows to load so called 'agents' in the running VM. In terms of this framework
35
application running in the VM where agent is loaded to is called 'target application'.
36
37
TargetApplicationWaitingAgents is base class for target applications used in the AttachOnDemand tests
38
(also TargetApplicationWaitingAgents can be used without modifications in tests where target
39
application shouldn't execute some test-specific actions).
40
41
AttachOnDemand tests requires synchronization between test agents and target application:
42
- before target application can start to execute test-specific actions it
43
should wait when all tests agents will be loaded
44
45
- target application shouldn't finish until all agents finish their work
46
47
TargetApplicationWaitingAgents incapsulates actions common for all target applications. TargetApplicationWaitingAgents
48
provides 2 methods: 'agentLoaded' and 'agentFinished', test agents use these methods to notify
49
target application about its status. When target application based on the TargetApplicationWaitingAgents
50
starts it first waits when all test agents will be loaded (number of expected test agents is
51
passed via parameter -agentsNumber). After this target application executes test-specific actions,
52
waits when all test agents will finish, checks agent's status (passed of failed) and
53
finishes.
54
55
In most cases test target applications should override only method 'targetApplicationActions' and
56
its 'main' method should contain only call of the method 'TargetApplicationWaitingAgents.runTargetApplication'.
57
58
Typical target application class looks like this:
59
60
public class targetExample extends TargetApplicationWaitingAgents {
61
62
protected void targetApplicationActions() {
63
// do test-specific actions
64
}
65
66
public static void main(String[] args) {
67
new targetExample().runTargetApplication(args);
68
}
69
}
70
*/
71
public class TargetApplicationWaitingAgents {
72
73
private volatile static boolean testFailed = false;
74
75
private static long AGENTS_CONNECTION_TIMEOUT = 5 * 60 * 1000; // 5 min
76
77
private static long AGENTS_FINISHING_TIMEOUT = 5 * 60 * 1000; // 5 min
78
79
private static boolean allAgentsAttached;
80
81
private static List<String> attachedAgents = new ArrayList<String>();
82
83
private static boolean allAgentsFinished;
84
85
private static List<String> finishedAgents = new ArrayList<String>();
86
87
private static boolean targetApplicationInitialized;
88
89
static protected AODTargetArgParser argParser;
90
91
protected static Log log;
92
93
static private Object monitor = new Object();
94
95
/*
96
* Methods
97
* - agentLoaded(String agentName) and
98
* - agentFinished(String agentName, boolean finishedSuccessfully)
99
* are called from test agents to notify target application about its status
100
*/
101
102
public static void agentLoaded(String agentName) {
103
synchronized (monitor) {
104
if (!targetApplicationInitialized)
105
waitForTargetApplicationInitialization();
106
107
// check test logic
108
if (attachedAgents.contains(agentName)) {
109
setStatusFailed("Agent '" + agentName + "' already attached");
110
111
// let TargetApplication complete execution in case of error
112
allAgentsAttached = true;
113
monitor.notifyAll();
114
115
throw new TestBug("Agent '" + agentName + "' calls method 'agentLoaded' more than 1 time");
116
} else {
117
attachedAgents.add(agentName);
118
119
log.display("Agent '" + agentName + "' was loaded");
120
121
allAgentsAttached = (attachedAgents.size() == argParser.getExpectedAgentsNumber());
122
123
if (allAgentsAttached)
124
monitor.notifyAll();
125
126
// check test logic
127
if (attachedAgents.size() > argParser.getExpectedAgentsNumber()) {
128
setStatusFailed("Unexpected agent attached (expected agents number: " +
129
argParser.getExpectedAgentsNumber() +
130
", but " + attachedAgents.size() + " agents were loaded)");
131
132
throw new TestBug("More agents attached than it was expected" +
133
" (expected: " + argParser.getExpectedAgentsNumber() +
134
", attached: " + attachedAgents.size() + ")");
135
}
136
}
137
}
138
}
139
140
public static void agentFinished(String agentName, boolean finishedSuccessfully) {
141
synchronized (monitor) {
142
// check test logic
143
if (!targetApplicationInitialized)
144
throw new TestBug("Method 'agentFinished' was called before TargetApplication was initialized");
145
146
boolean algorithmError = false;
147
String errorMessage = "Test algorithm error:";
148
149
if (!attachedAgents.contains(agentName)) {
150
algorithmError = true;
151
errorMessage += " agent '" + agentName + "' didn't call method 'agentLoaded';";
152
log.complain(errorMessage);
153
}
154
155
if (finishedAgents.contains(agentName)) {
156
algorithmError = true;
157
errorMessage += " agent '" + agentName + "' already called method 'agentFinished';";
158
log.complain(errorMessage);
159
}
160
161
if (algorithmError) {
162
// let TargetApplication complete execution in case of error
163
allAgentsFinished = true;
164
monitor.notifyAll();
165
166
throw new TestBug(errorMessage);
167
} else {
168
finishedAgents.add(agentName);
169
170
log.display("Agent '" + agentName + "' finished execution (finishedSuccessfully: " + finishedSuccessfully + ")");
171
172
if (!finishedSuccessfully)
173
setStatusFailed("Agent '" + agentName + " finished with error status");
174
175
allAgentsFinished = (finishedAgents.size() == argParser.getExpectedAgentsNumber());
176
177
if (allAgentsAttached)
178
monitor.notifyAll();
179
}
180
}
181
}
182
183
/*
184
* This method is called from the method 'agentLoaded' in case
185
* when target application isn't initialized yet at the moment
186
* when agent is connecting
187
*/
188
static private void waitForTargetApplicationInitialization() {
189
synchronized (monitor) {
190
while (!targetApplicationInitialized) {
191
try {
192
monitor.wait();
193
} catch (InterruptedException e) {
194
// should never happen
195
exitAsFailed(e);
196
}
197
}
198
}
199
}
200
201
/*
202
* This method is introduced to let subclasses to create its own parsers
203
*/
204
protected AODTargetArgParser createArgParser(String[] args) {
205
return new AODTargetArgParser(args);
206
}
207
208
/*
209
* Target application initialization
210
*/
211
private void initTargetApplication(String[] args) {
212
synchronized (monitor) {
213
if (targetApplicationInitialized)
214
throw new TestBug("TargetApplication already initialized");
215
216
log = new Log(System.out, true);
217
218
argParser = createArgParser(args);
219
220
// test-specific initialization
221
init(args);
222
223
targetApplicationInitialized = true;
224
monitor.notifyAll();
225
}
226
}
227
228
static private void waitAgentsConnection() {
229
synchronized (monitor) {
230
long waitFinishTime = System.currentTimeMillis() + AGENTS_CONNECTION_TIMEOUT;
231
232
while (!allAgentsAttached && (System.currentTimeMillis() < waitFinishTime)) {
233
try {
234
monitor.wait(AGENTS_CONNECTION_TIMEOUT);
235
} catch (InterruptedException e) {
236
// should never happen
237
exitAsFailed(e);
238
}
239
}
240
}
241
242
if (!allAgentsAttached) {
243
exitAsFailed("Agents didn't attach in " + AGENTS_CONNECTION_TIMEOUT + "ms, stop execution " +
244
"(expected agents number: " + argParser.getExpectedAgentsNumber() +
245
", attached agents number: " + attachedAgents.size() + ")");
246
}
247
}
248
249
static private void waitAgentsFinishing() {
250
synchronized (monitor) {
251
long waitFinishTime = System.currentTimeMillis() + AGENTS_FINISHING_TIMEOUT;
252
253
while (!allAgentsFinished && (System.currentTimeMillis() < waitFinishTime)) {
254
try {
255
monitor.wait(AGENTS_FINISHING_TIMEOUT);
256
} catch (InterruptedException e) {
257
// should never happen
258
exitAsFailed(e);
259
}
260
}
261
}
262
263
if (!allAgentsFinished)
264
exitAsFailed("Agents didn't finish in " + AGENTS_FINISHING_TIMEOUT + "ms, stop execution " +
265
"(attached agents number: " + attachedAgents.size() +
266
", finished agents number: " + finishedAgents.size() + ")");
267
}
268
269
/*
270
* Print error message and set failed status, but don't exit
271
*/
272
273
static public void setStatusFailed(String message) {
274
testFailed = true;
275
log.complain(message);
276
}
277
278
static public void setStatusFailed(Throwable t) {
279
testFailed = true;
280
log.complain("Unexpected exception: " + t);
281
t.printStackTrace(log.getOutStream());
282
}
283
284
/*
285
* Print error message and exit with fail status
286
*/
287
static protected void exitAsFailed(String errorMessage) {
288
try {
289
log.complain(errorMessage);
290
log.complain("Stop execution");
291
} finally {
292
System.exit(Consts.JCK_STATUS_BASE + Consts.TEST_FAILED);
293
}
294
}
295
296
/*
297
* Print error message and exit with fail status
298
*/
299
static protected void exitAsFailed(Throwable t) {
300
try {
301
log.complain("Unexpected exception was thrown during TargetApplication execution: " + t);
302
t.printStackTrace(log.getOutStream());
303
log.display("Stop execution");
304
} finally {
305
System.exit(Consts.JCK_STATUS_BASE + Consts.TEST_FAILED);
306
}
307
}
308
309
/*
310
* Following 3 methods can be overridden in subclasses:
311
*
312
* - init(String[] args)
313
*
314
* - targetApplicationActions()
315
*
316
* - afterAgentsFinished()
317
*/
318
319
/*
320
* Test-specific initialization
321
*/
322
protected void init(String[] args) {
323
324
}
325
326
protected void targetApplicationActions() throws Throwable {
327
// do nothing by default
328
}
329
330
protected void afterAgentsFinished() {
331
// do nothing by default
332
}
333
334
public final void runTargetApplication(String[] args) {
335
initTargetApplication(args);
336
337
SocketIOPipe pipe = null;
338
339
try {
340
if (argParser.getPort() > 0) {
341
/*
342
* When target application initialized send signal to AODTestRunner
343
*/
344
pipe = SocketIOPipe.createClientIOPipe(log, "localhost", argParser.getPort(), 0);
345
log.display("Sending signal '" + AODTestRunner.SIGNAL_READY_FOR_ATTACH + "'");
346
pipe.println(AODTestRunner.SIGNAL_READY_FOR_ATTACH);
347
}
348
349
log.display("Waiting for agents connection");
350
waitAgentsConnection();
351
log.display("All expected agents connected");
352
353
try {
354
targetApplicationActions();
355
} catch (Throwable e) {
356
/*
357
* If something goes wrong during test execution it is better
358
* to exit without waiting for agents
359
*/
360
361
if (pipe != null)
362
pipe.close();
363
364
exitAsFailed(e);
365
}
366
367
log.display("Waiting for agents finishing");
368
waitAgentsFinishing();
369
log.display("All agents finished execution");
370
371
afterAgentsFinished();
372
373
if (pipe != null) {
374
/*
375
* Don't finish execution until AODTestRunner attached agents
376
*/
377
String signal = pipe.readln();
378
log.display("Signal received: '" + signal + "'");
379
if ((signal == null) || !signal.equals(AODTestRunner.SIGNAL_FINISH))
380
throw new TestBug("Unexpected AODTestRunner signal: '" + signal + "'");
381
382
if (testFailed) {
383
if (pipe != null)
384
pipe.close();
385
386
exitAsFailed("Error happened during TargetApplication execution (see error messages for details)");
387
} else {
388
log.display("Test passed");
389
}
390
}
391
} finally {
392
if (pipe != null)
393
pipe.close();
394
}
395
}
396
397
public static void main(String[] args) {
398
new TargetApplicationWaitingAgents().runTargetApplication(args);
399
}
400
}
401
402