Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIEventsDebugger.java
41161 views
1
/*
2
* Copyright (c) 2006, 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.jdi;
24
25
import java.io.PrintStream;
26
import java.lang.reflect.*;
27
import java.util.*;
28
29
import com.sun.jdi.*;
30
import com.sun.jdi.event.*;
31
import com.sun.jdi.request.*;
32
import nsk.share.TestBug;
33
34
/*
35
* Class is used as base debugger in tests for following events and event requests:
36
* - MonitorContendedEnterRequest / MonitorContendedEnterEvent
37
* - MonitorContendedEnteredRequest / MonitorContendedEnteredEvent
38
* - MonitorWaitRequest / MonitorWaitEvent
39
* - MonitorWaitedRequest / MonitorWaitedEvent
40
*
41
* In all these tests similar scenario is used:
42
* - debugger VM forces debuggee VM to create number of objects which should generate events during test
43
* - if any event filters are used each generating event object is checked is this object accepted by all filters,
44
* if object was accepted it should save information about all generated events and this information is available for debugger
45
* - debuggee performs event generation and stop at breakpoint
46
* - debugger reads data saved by event generators and checks is only expected events was generated
47
*/
48
public class JDIEventsDebugger extends TestDebuggerType2 {
49
// types of tested events
50
static public enum EventType {
51
MONITOR_CONTENTED_ENTER,
52
MONITOR_CONTENTED_ENTERED,
53
MONITOR_WAIT,
54
MONITOR_WAITED
55
}
56
57
/*
58
* Class contains information required for event testing
59
*/
60
static class TestedEventData {
61
// event class
62
public Class<?> eventClass;
63
64
// class representing event data on debuggee's side
65
public Class<?> eventDataMirrorClass;
66
67
// class representing event data on debugger's side
68
public Class<?> eventDataClass;
69
70
public TestedEventData(Class<?> eventClass, Class<?> eventDataMirrorClass, Class<?> eventDataClass) {
71
this.eventClass = eventClass;
72
this.eventDataMirrorClass = eventDataMirrorClass;
73
this.eventDataClass = eventDataClass;
74
}
75
}
76
77
static public Map<EventType, TestedEventData> testedEventData = new HashMap<EventType, TestedEventData>();
78
79
static {
80
testedEventData.put(EventType.MONITOR_CONTENTED_ENTER, new TestedEventData(MonitorContendedEnterEvent.class,
81
DebuggeeEventData.DebugMonitorEnterEventData.class, DebuggerEventData.DebugMonitorEnterEventData.class));
82
83
testedEventData.put(EventType.MONITOR_CONTENTED_ENTERED, new TestedEventData(MonitorContendedEnteredEvent.class,
84
DebuggeeEventData.DebugMonitorEnteredEventData.class, DebuggerEventData.DebugMonitorEnteredEventData.class));
85
86
testedEventData.put(EventType.MONITOR_WAIT, new TestedEventData(MonitorWaitEvent.class, DebuggeeEventData.DebugMonitorWaitEventData.class,
87
DebuggerEventData.DebugMonitorWaitEventData.class));
88
89
testedEventData.put(EventType.MONITOR_WAITED, new TestedEventData(MonitorWaitedEvent.class,
90
DebuggeeEventData.DebugMonitorWaitedEventData.class, DebuggerEventData.DebugMonitorWaitedEventData.class));
91
}
92
93
static public TestedEventData[] eventDataByEventTypes(EventType[] eventTypes) {
94
TestedEventData[] result = new TestedEventData[eventTypes.length];
95
96
int i = 0;
97
for (EventType eventType : eventTypes) {
98
TestedEventData eventData = testedEventData.get(eventType);
99
100
if (eventData == null)
101
throw new TestBug("Unsupported event type: " + eventType);
102
103
result[i++] = eventData;
104
}
105
106
return result;
107
}
108
109
/*
110
* Dummy event listener, just accepts all events
111
*/
112
public class DummyEventListener extends EventHandler.EventListener {
113
private volatile boolean breakpointEventReceived;
114
115
public boolean eventReceived(Event event) {
116
if (event instanceof BreakpointEvent) {
117
breakpointEventReceived = true;
118
vm.resume();
119
}
120
121
return true;
122
}
123
124
public void waitBreakpoint() {
125
while (!breakpointEventReceived)
126
Thread.yield();
127
}
128
}
129
130
/*
131
* Parse common for event tests parameters
132
*/
133
protected String[] doInit(String[] args, PrintStream out) {
134
args = super.doInit(args, out);
135
136
ArrayList<String> standardArgs = new ArrayList<String>();
137
138
for (int i = 0; i < args.length; i++) {
139
if (args[i].equals("-allowExtraEvents")) {
140
extraEventClasses = createEventClassArray(args[i + 1]);
141
142
i++;
143
} else if (args[i].equals("-allowMissedEvents")) {
144
missedEventClasses = createEventClassArray(args[i + 1]);
145
146
i++;
147
} else
148
standardArgs.add(args[i]);
149
}
150
151
return standardArgs.toArray(new String[standardArgs.size()]);
152
}
153
154
// can't control some kinds of events (events from system libraries) and
155
// not all events should be saved for analysis
156
// (should be implemented in subclasses)
157
protected boolean shouldSaveEvent(Event event) {
158
return true;
159
}
160
161
public Class<?> findEventDataClass(TestedEventData[] testedEventData, Event event) {
162
for (TestedEventData eventData : testedEventData) {
163
if (eventData.eventClass.isAssignableFrom(event.getClass()))
164
return eventData.eventClass;
165
}
166
167
return null;
168
}
169
170
/*
171
* This event listener stores received monitor events until BreakpointEvent
172
* is not received, after getting of BreakpointEvent checks only expected
173
* events were received
174
*/
175
public class EventListener extends EventHandler.EventListener {
176
177
private TestedEventData[] testedEventData;
178
179
public EventListener(TestedEventData[] testedEventData) {
180
this.testedEventData = testedEventData;
181
}
182
183
private boolean shouldHandleEvent(Event event) {
184
return findEventDataClass(testedEventData, event) == null ? false : true;
185
}
186
187
volatile boolean breakpointWasReceived;
188
189
// execution was interrupted because of timeout
190
volatile boolean executionWasInterrupted;
191
192
public boolean eventReceived(Event event) {
193
if (shouldHandleEvent(event)) {
194
if (shouldSaveEvent(event)) {
195
196
Class<?> eventClass;
197
198
eventClass = findEventDataClass(testedEventData, event);
199
List<Event> events = allReceivedEvents.get(eventClass);
200
201
if (events == null) {
202
events = new LinkedList<Event>();
203
allReceivedEvents.put(eventClass, events);
204
}
205
206
events.add(event);
207
}
208
209
return true;
210
}
211
// debuggee should stop at the end of test
212
else if (event instanceof BreakpointEvent) {
213
breakpointWasReceived = true;
214
215
try {
216
// if execution was interrupted because of timeout don't check received
217
// events because it can consume too much time
218
if (!executionWasInterrupted) {
219
// get data from debuggee about all generated events
220
initExpectedEvents(testedEventData);
221
222
checkEvents();
223
} else
224
log.complain("WARNING: execution was interrupted because of timeout, test doesn't check received events");
225
} catch (Throwable t) {
226
unexpectedException(t);
227
}
228
229
vm.resume();
230
231
return true;
232
}
233
234
return false;
235
}
236
}
237
238
protected Class<?> extraEventClasses[];
239
240
protected Class<?> missedEventClasses[];
241
242
/*
243
* If test can't strictly control event generation it may allow generation
244
* of extra events and unexpected events aren't treated as error
245
* (subclasses should specify what kinds of extra events are allowed)
246
*/
247
private Class<?>[] allowedExtraEvents() {
248
return extraEventClasses;
249
}
250
251
/*
252
* If test can't strictly control event generation case when debugger doesn't
253
* receive expected event may be not treated as failure
254
* (subclasses should specify what kinds of expected events can be not received)
255
*/
256
private Class<?>[] allowedMissedEvents() {
257
return missedEventClasses;
258
}
259
260
private boolean isExtraEventAllowed(Class<?> eventClass) {
261
return checkEvent(eventClass, allowedExtraEvents());
262
}
263
264
private boolean isMissedEventAllowed(Class<?> eventClass) {
265
return checkEvent(eventClass, allowedMissedEvents());
266
}
267
268
private boolean checkEvent(Class<?> eventClass, Class<?> classes[]) {
269
if (classes == null)
270
return false;
271
272
for (Class<?> klass : classes) {
273
if (klass.isAssignableFrom(eventClass))
274
return true;
275
}
276
277
return false;
278
}
279
280
// flag is modified from the event listener thread
281
private volatile boolean eventsNotGenerated;
282
283
/*
284
* Method returns true if test expects event generation, but events weren't
285
* generated. If test can't strictly control event generation such case isn't
286
* necessarily treated as test failure (sublasses of JDIEventsDebugger can
287
* for example try to rerun test several times).
288
*/
289
protected boolean eventsNotGenerated() {
290
return eventsNotGenerated;
291
}
292
293
/*
294
* Print debug information about expected and received events(this data
295
* should be stored in lists 'allExpectedEvents' and 'allReceivedEvents')
296
* and check that only expected events were received
297
*/
298
private void checkEvents() {
299
if (getAllExpectedEvents().size() > 0 && getAllReceivedEvents().size() == 0 && allowedMissedEvents() != null) {
300
log.display("WARNING: didn't receive any event");
301
eventsNotGenerated = true;
302
}
303
304
log.display("ALL RECEIVED EVENTS: ");
305
for (Event event : getAllReceivedEvents())
306
log.display("received event: " + eventToString(event));
307
308
log.display("ALL EXPECTED EVENTS: ");
309
for (DebuggerEventData.DebugEventData eventData : getAllExpectedEvents())
310
log.display("expected event: " + eventData);
311
312
// try to find received event in the list of expected events, if this event
313
// was found remove data about events from both lists
314
for (Class<?> eventClass : allReceivedEvents.keySet()) {
315
List<Event> receivedEvents = allReceivedEvents.get(eventClass);
316
List<DebuggerEventData.DebugEventData> expectedEvents = allExpectedEvents.get(eventClass);
317
318
for (Iterator<Event> allReceivedEventsIterator = receivedEvents.iterator();
319
allReceivedEventsIterator.hasNext();) {
320
321
Event event = allReceivedEventsIterator.next();
322
323
for (Iterator<DebuggerEventData.DebugEventData> allExpectedEventsIterator = expectedEvents.iterator();
324
allExpectedEventsIterator.hasNext();) {
325
326
DebuggerEventData.DebugEventData debugEventData = allExpectedEventsIterator.next();
327
328
if (debugEventData.shouldCheckEvent(event)) {
329
if (debugEventData.checkEvent(event)) {
330
allExpectedEventsIterator.remove();
331
allReceivedEventsIterator.remove();
332
break;
333
}
334
}
335
}
336
}
337
}
338
339
List<Event> receivedEventsLeft = getAllReceivedEvents();
340
341
// check is all received events were found in expected
342
if (receivedEventsLeft.size() > 0) {
343
// if allowExtraEvents = true extra events are not treated as error
344
for (Event event : receivedEventsLeft) {
345
if (!isExtraEventAllowed(event.getClass())) {
346
setSuccess(false);
347
log.complain("Unexpected event " + eventToString(event));
348
}
349
}
350
}
351
352
List<DebuggerEventData.DebugEventData> expectedEventsLeft = getAllExpectedEvents();
353
354
// check is all expected events were received
355
if (expectedEventsLeft.size() > 0) {
356
for (DebuggerEventData.DebugEventData eventData : expectedEventsLeft) {
357
if (!isMissedEventAllowed(eventData.eventClass)) {
358
setSuccess(false);
359
log.complain("Expected event was not generated: " + eventData);
360
}
361
}
362
}
363
}
364
365
private String eventToString(Event event) {
366
try {
367
if (event instanceof MonitorContendedEnterEvent)
368
return event + ". Details(MonitorContendedEnterEvent):" + " Monitor: " + ((MonitorContendedEnterEvent) event).monitor() + " Thread: "
369
+ ((MonitorContendedEnterEvent) event).thread();
370
else if (event instanceof MonitorContendedEnteredEvent)
371
return event + ". Details(MonitorContendedEnteredEvent):" + " Monitor: " + ((MonitorContendedEnteredEvent) event).monitor()
372
+ " Thread: " + ((MonitorContendedEnteredEvent) event).thread();
373
else if (event instanceof MonitorWaitEvent)
374
return event + ". Details(MonitorWaitEvent):" + " Monitor: " + ((MonitorWaitEvent) event).monitor() + " Thread: "
375
+ ((MonitorWaitEvent) event).thread() + " Timeout: " + ((MonitorWaitEvent) event).timeout();
376
else if (event instanceof MonitorWaitedEvent)
377
return event + ". Details(MonitorWaitedEvent):" + " Monitor: " + ((MonitorWaitedEvent) event).monitor() + " Thread: "
378
+ ((MonitorWaitedEvent) event).thread() + " Timedout: " + ((MonitorWaitedEvent) event).timedout();
379
380
return event.toString();
381
}
382
// this exception can occur when unexpected event was received
383
catch (ObjectCollectedException e) {
384
// allowExtraEvents=true extra events are not treated as error
385
if (!isExtraEventAllowed(event.getClass())) {
386
setSuccess(false);
387
e.printStackTrace(log.getOutStream());
388
log.complain("Unexpected ObjectCollectedException was caught, possible unexpected event was received");
389
}
390
391
return event.getClass().getName() + " [ Can't get full description, ObjectCollectedException was thrown ]";
392
}
393
}
394
395
// events received during test execution are stored here
396
private Map<Class<?>, List<Event>> allReceivedEvents = new HashMap<Class<?>, List<Event>>();
397
398
private List<Event> getAllReceivedEvents() {
399
List<Event> result = new LinkedList<Event>();
400
401
for (Class<?> eventClass : allReceivedEvents.keySet()) {
402
result.addAll(allReceivedEvents.get(eventClass));
403
}
404
405
return result;
406
}
407
408
protected Map<Class<?>, List<DebuggerEventData.DebugEventData>> allExpectedEvents = new HashMap<Class<?>, List<DebuggerEventData.DebugEventData>>();
409
410
private List<DebuggerEventData.DebugEventData> getAllExpectedEvents() {
411
List<DebuggerEventData.DebugEventData> result = new LinkedList<DebuggerEventData.DebugEventData>();
412
413
for (Class<?> eventClass : allExpectedEvents.keySet()) {
414
result.addAll(allExpectedEvents.get(eventClass));
415
}
416
417
return result;
418
}
419
420
// find in debuggee VM and add to the list 'allExpectedEvents' instances
421
// of classes representing generated events
422
protected void initExpectedEvents(TestedEventData testedEventData[]) {
423
List<DebuggerEventData.DebugEventData> events;
424
425
ReferenceType referenceType = debuggee.classByName(debuggeeClassNameWithoutArgs());
426
427
ArrayReference generatedEvents = (ArrayReference) referenceType.getValue(referenceType.fieldByName("generatedEvents"));
428
429
for (TestedEventData eventData : testedEventData) {
430
events = new LinkedList<DebuggerEventData.DebugEventData>();
431
allExpectedEvents.put(eventData.eventClass, events);
432
}
433
434
for (int i = 0; i < generatedEvents.length(); i++) {
435
ObjectReference debuggeeMirror = (ObjectReference) generatedEvents.getValue(i);
436
437
for (TestedEventData eventData : testedEventData) {
438
439
if (debuggeeMirror.referenceType().name().equals(eventData.eventDataMirrorClass.getName())) {
440
events = allExpectedEvents.get(eventData.eventClass);
441
442
/*
443
* Use reflection to create object representing generated
444
* event Event data class should has constructor with single
445
* parameter of type com.sun.jdi.ObjectReference
446
*/
447
Constructor<?> constructor;
448
449
try {
450
constructor = eventData.eventDataClass.getConstructor(new Class[] { ObjectReference.class });
451
} catch (NoSuchMethodException e) {
452
TestBug testBug = new TestBug(
453
"Class representing debug event data should implement constructor with single parameter of type com.sun.jdi.ObjectReference");
454
testBug.initCause(e);
455
throw testBug;
456
}
457
458
DebuggerEventData.DebugEventData expectedEvent;
459
460
try {
461
expectedEvent = (DebuggerEventData.DebugEventData) constructor.newInstance(new Object[] { debuggeeMirror });
462
} catch (Exception e) {
463
TestBug testBug = new TestBug("Error when create debug event data: " + e);
464
testBug.initCause(e);
465
throw testBug;
466
}
467
events.add(expectedEvent);
468
}
469
}
470
}
471
}
472
473
private void printFiltersInfo() {
474
if (eventFilters.size() > 0) {
475
log.display("Use following filters: ");
476
477
for (EventFilters.DebugEventFilter filter : eventFilters)
478
log.display("" + filter);
479
} else {
480
log.display("Don't use event filters");
481
}
482
}
483
484
// filters used in test
485
protected List<EventFilters.DebugEventFilter> eventFilters = new LinkedList<EventFilters.DebugEventFilter>();
486
487
// Check is object generating events matches all filters,
488
// if object was accepted by all filters set this object's field
489
// 'saveEventData' to 'true', otherwise to 'false',
490
private void checkEventGenerator(ThreadReference eventThread, ObjectReference executor) {
491
boolean acceptedByFilters = true;
492
493
for (EventFilters.DebugEventFilter eventFilter : eventFilters) {
494
if (!eventFilter.isObjectMatch(executor, eventThread)) {
495
acceptedByFilters = false;
496
break;
497
}
498
}
499
500
try {
501
executor.setValue(executor.referenceType().fieldByName("saveEventData"), vm.mirrorOf(acceptedByFilters));
502
} catch (Exception e) {
503
throw new TestBug("Unexpected exception when change object field in debugee VM: " + e, e);
504
}
505
}
506
507
/*
508
* Find all event generating threads in debuggee VM (instances of
509
* nsk.share.jdi.MonitorEventsDebuggee$MonitorActionsThread) all these
510
* threads have special field - 'executor', this is object which generates
511
* events. If event generating thread and event generating object was
512
* accepted by all filters generating object should store information about
513
* all generated events and this information will be available for debugger
514
*/
515
protected void initializeEventGenerators() {
516
printFiltersInfo();
517
518
List<ThreadReference> eventThreads = getEventThreads();
519
520
for (ThreadReference eventThread : eventThreads) {
521
ObjectReference executor = (ObjectReference) eventThread.getValue(eventThread.referenceType().fieldByName("executor"));
522
checkEventGenerator(eventThread, executor);
523
}
524
525
// debuggee's main thread also can generate events, need to filter it in
526
// the same way as other threads
527
checkEventGenerator(debuggee.threadByName(JDIEventsDebuggee.MAIN_THREAD_NAME), findSingleObjectReference(debuggeeClassNameWithoutArgs()));
528
}
529
530
// find instances of nsk.share.jdi.MonitorEventsDebuggee$MonitorActionsThread
531
protected List<ThreadReference> getEventThreads() {
532
ReferenceType referenceType = debuggee.classByName(JDIEventsDebuggee.EventActionsThread.class.getName());
533
List<ObjectReference> debuggeeEventThreads = referenceType.instances(0);
534
535
List<ThreadReference> result = new LinkedList<ThreadReference>();
536
for (ObjectReference threadReference : debuggeeEventThreads)
537
result.add((ThreadReference) threadReference);
538
539
return result;
540
}
541
542
// find instances of nsk.share.jdi.MonitorEventsDebuggee$MonitorActionsThread,
543
// and get value of this object's field with name 'executor'
544
protected List<ObjectReference> getEventObjects() {
545
List<ObjectReference> eventObjects = new LinkedList<ObjectReference>();
546
547
List<ThreadReference> eventThreads = getEventThreads();
548
549
for (ThreadReference eventThread : eventThreads) {
550
eventObjects.add((ObjectReference) eventThread.getValue(eventThread.referenceType().fieldByName("executor")));
551
}
552
553
return eventObjects;
554
}
555
556
// remove all filters, received and expected events
557
private void clearTestData() {
558
allExpectedEvents.clear();
559
allReceivedEvents.clear();
560
eventFilters.clear();
561
eventsNotGenerated = false;
562
}
563
564
private boolean isEventSupported(EventType eventType) {
565
switch (eventType) {
566
case MONITOR_CONTENTED_ENTER:
567
case MONITOR_CONTENTED_ENTERED:
568
case MONITOR_WAIT:
569
case MONITOR_WAITED:
570
return vm.canRequestMonitorEvents();
571
572
default:
573
throw new TestBug("Invalid tested event type: " + eventType);
574
}
575
}
576
577
// create instance of EventRequest depending on given eventType
578
private EventRequest createTestRequest(EventType eventType) {
579
switch (eventType) {
580
case MONITOR_CONTENTED_ENTER:
581
return debuggee.getEventRequestManager().createMonitorContendedEnterRequest();
582
case MONITOR_CONTENTED_ENTERED:
583
return debuggee.getEventRequestManager().createMonitorContendedEnteredRequest();
584
case MONITOR_WAIT:
585
return debuggee.getEventRequestManager().createMonitorWaitRequest();
586
case MONITOR_WAITED:
587
return debuggee.getEventRequestManager().createMonitorWaitedRequest();
588
589
default:
590
throw new TestBug("Invalid tested event type: " + eventType);
591
}
592
}
593
594
// create command depending on given eventType
595
private String createCommand(EventType eventTypes[], int eventsNumber) {
596
String command = JDIEventsDebuggee.COMMAND_CREATE_ACTIONS_EXECUTORS + ":" + eventsNumber + ":";
597
598
for (EventType eventType : eventTypes) {
599
switch (eventType) {
600
case MONITOR_CONTENTED_ENTER:
601
case MONITOR_CONTENTED_ENTERED:
602
case MONITOR_WAIT:
603
case MONITOR_WAITED:
604
command += " " + eventType.name();
605
break;
606
607
default:
608
throw new TestBug("Invalid tested event type: " + eventType);
609
}
610
}
611
612
return command;
613
}
614
615
// get list of event requests from EventRequestManager depending on the given eventType
616
private List<?> getEventRequestsFromManager(EventType eventType) {
617
switch (eventType) {
618
case MONITOR_CONTENTED_ENTER:
619
return debuggee.getEventRequestManager().monitorContendedEnterRequests();
620
case MONITOR_CONTENTED_ENTERED:
621
return debuggee.getEventRequestManager().monitorContendedEnteredRequests();
622
case MONITOR_WAIT:
623
return debuggee.getEventRequestManager().monitorWaitRequests();
624
case MONITOR_WAITED:
625
return debuggee.getEventRequestManager().monitorWaitedRequests();
626
627
default:
628
throw new TestBug("Invalid tested event type: " + eventType);
629
}
630
}
631
632
protected EventHandler eventHandler;
633
634
private EventListener eventListener;
635
636
// perform event generation before test begins to load all using classes
637
// and avoid unexpected events related to classloading
638
protected void prepareDebuggee(EventType[] eventTypes) {
639
initDefaultBreakpoint();
640
641
eventHandler = new EventHandler(debuggee, log);
642
eventHandler.startListening();
643
644
// use event listener which just skip all received events
645
DummyEventListener dummyEventListener = new DummyEventListener();
646
eventHandler.addListener(dummyEventListener);
647
648
EventRequest eventRequests[] = new EventRequest[eventTypes.length];
649
650
for (int i = 0; i < eventRequests.length; i++) {
651
eventRequests[i] = createTestRequest(eventTypes[i]);
652
eventRequests[i].setSuspendPolicy(EventRequest.SUSPEND_NONE);
653
eventRequests[i].enable();
654
}
655
656
// debuggee should create event generators
657
pipe.println(createCommand(eventTypes, 1));
658
659
if (!isDebuggeeReady())
660
return;
661
662
// start event generation
663
pipe.println(JDIEventsDebuggee.COMMAND_START_EXECUTION);
664
665
if (!isDebuggeeReady())
666
return;
667
668
for (int i = 0; i < eventRequests.length; i++)
669
eventRequests[i].disable();
670
671
dummyEventListener.waitBreakpoint();
672
673
eventHandler.removeListener(dummyEventListener);
674
675
pipe.println(JDIEventsDebuggee.COMMAND_WAIT_EXECUTION_COMPLETION);
676
677
if (!isDebuggeeReady())
678
return;
679
680
eventListener = new EventListener(eventDataByEventTypes(eventTypes));
681
eventHandler.addListener(eventListener);
682
}
683
684
/*
685
* Method for stress testing, allows specify requests for several event
686
* types, number of events which should be generated during test and number
687
* of threads which simultaneously generate events
688
*/
689
protected void stressTestTemplate(EventType[] eventTypes, int eventsNumber, int threadsNumber) {
690
for (EventType eventType : eventTypes) {
691
if (!isEventSupported(eventType)) {
692
log.complain("Can't test event because of it isn't supported: " + eventType);
693
return;
694
}
695
}
696
697
// Used framework is intended for testing event filters and debuggee
698
// creates 3 threads performing event generation and there is possibility
699
// to filter events from some threads
700
for (int i = 0; i < threadsNumber; i++) {
701
pipe.println(createCommand(eventTypes, eventsNumber));
702
703
if (!isDebuggeeReady())
704
return;
705
}
706
707
// clear data(if this method is executed several times)
708
clearTestData();
709
710
initializeEventGenerators();
711
712
EventRequest eventRequests[] = new EventRequest[eventTypes.length];
713
714
// create event requests
715
for (int i = 0; i < eventTypes.length; i++) {
716
eventRequests[i] = createTestRequest(eventTypes[i]);
717
eventRequests[i].setSuspendPolicy(EventRequest.SUSPEND_NONE);
718
eventRequests[i].enable();
719
720
log.display("Use following event request: " + eventRequests[i]);
721
}
722
723
// stressTestTemplate can control only execution time, so ignore iteration count
724
stresser.start(0);
725
try {
726
// start event generation
727
pipe.println(JDIEventsDebuggee.COMMAND_START_EXECUTION);
728
729
if (!isDebuggeeReady())
730
return;
731
732
// check is stressTime exceeded
733
while (stresser.continueExecution()) {
734
try {
735
Thread.sleep(100);
736
} catch (InterruptedException e) {
737
unexpectedException(e);
738
}
739
740
// periodically check is test completed
741
if (eventListener.breakpointWasReceived)
742
break;
743
}
744
} finally {
745
stresser.finish();
746
}
747
748
// debugger should interrupt test because of timeout
749
if (!eventListener.breakpointWasReceived) {
750
751
eventListener.executionWasInterrupted = true;
752
753
log.complain("WARNING: time is exceeded, interrupt test");
754
755
pipe.println(JDIEventsDebuggee.COMMAND_STOP_EXECUTION);
756
757
if (!isDebuggeeReady())
758
return;
759
}
760
761
pipe.println(JDIEventsDebuggee.COMMAND_WAIT_EXECUTION_COMPLETION);
762
763
if (!isDebuggeeReady())
764
return;
765
766
for (int i = 0; i < eventRequests.length; i++)
767
eventRequests[i].disable();
768
}
769
770
/*
771
* Hook method for subclasses implementing tests against event filters (it is called from eventFilterTestTemplate)
772
*/
773
protected EventFilters.DebugEventFilter[] createTestFilters(int testedFilterIndex) {
774
throw new TestBug("Not implemented");
775
}
776
777
/*
778
* Test event request with filter
779
*
780
* Also this method check following:
781
* - InvalidRequestStateException is thrown if add filter for deleted or enabled request
782
* - EventRequestManager.xxxRequests() returns created event request
783
*/
784
protected void eventFilterTestTemplate(EventType eventType, int testedFilterIndex) {
785
if (!isEventSupported(eventType)) {
786
log.complain("Can't test event because of it isn't supported: " + eventType);
787
return;
788
}
789
790
// debuggee create event generators
791
pipe.println(createCommand(new EventType[] { eventType }, 1));
792
793
if (!isDebuggeeReady())
794
return;
795
796
clearTestData();
797
798
EventFilters.DebugEventFilter[] filters = createTestFilters(testedFilterIndex);
799
800
for (EventFilters.DebugEventFilter filter : filters) {
801
if (filter.isSupported(vm))
802
eventFilters.add(filter);
803
else {
804
log.complain("Can't test filter because of it isn't supported: " + filter);
805
return;
806
}
807
}
808
809
initializeEventGenerators();
810
811
// create event request
812
EventRequest request = createTestRequest(eventType);
813
request.setSuspendPolicy(EventRequest.SUSPEND_NONE);
814
815
// try add filter to enabled request, expect
816
// 'InvalidRequestStateException'
817
request.enable();
818
try {
819
for (EventFilters.DebugEventFilter filter : filters)
820
filter.addFilter(request);
821
822
setSuccess(false);
823
log.complain("Expected 'InvalidRequestStateException' was not thrown");
824
} catch (InvalidRequestStateException e) {
825
// expected exception
826
} catch (Throwable e) {
827
setSuccess(false);
828
log.complain("Unexpected exception: " + e);
829
e.printStackTrace(log.getOutStream());
830
}
831
832
// add event filter
833
request.disable();
834
835
for (EventFilters.DebugEventFilter filter : filters)
836
addFilter(filter, request);
837
838
request.enable();
839
840
log.display("Use following event request: " + request);
841
842
// start event generation
843
pipe.println(JDIEventsDebuggee.COMMAND_START_EXECUTION);
844
845
if (!isDebuggeeReady())
846
return;
847
848
// wait execution completion
849
pipe.println(JDIEventsDebuggee.COMMAND_WAIT_EXECUTION_COMPLETION);
850
851
if (!isDebuggeeReady())
852
return;
853
854
// check that method EventRequestManager.xxxRequests() return created
855
// request
856
if (!getEventRequestsFromManager(eventType).contains(request)) {
857
setSuccess(false);
858
log.complain("EventRequestManager doesn't return request: " + request);
859
}
860
861
// delete event request
862
debuggee.getEventRequestManager().deleteEventRequest(request);
863
864
// try add filter to removed request, expect
865
// 'InvalidRequestStateException'
866
try {
867
for (EventFilters.DebugEventFilter filter : filters)
868
filter.addFilter(request);
869
setSuccess(false);
870
log.complain("Expected 'InvalidRequestStateException' was not thrown");
871
} catch (InvalidRequestStateException e) {
872
// expected exception
873
} catch (Throwable t) {
874
unexpectedException(t);
875
}
876
}
877
878
private void addFilter(EventFilters.DebugEventFilter filter, EventRequest request) {
879
try {
880
filter.addFilter(request);
881
} catch (Throwable t) {
882
unexpectedException(t);
883
}
884
}
885
886
// used to parse parameters -allowExtraEvents and -allowMissedEvents
887
private Class<?>[] createEventClassArray(String string) {
888
String eventTypesNames[] = string.split(":");
889
EventType eventTypes[] = new EventType[eventTypesNames.length];
890
try {
891
for (int i = 0; i < eventTypesNames.length; i++) {
892
eventTypes[i] = EventType.valueOf(eventTypesNames[i]);
893
}
894
} catch (IllegalArgumentException e) {
895
throw new TestBug("Invalid event type", e);
896
}
897
898
if (eventTypesNames.length == 0)
899
throw new TestBug("Event types weren't specified");
900
901
Class<?>[] result = new Class[eventTypesNames.length];
902
903
for (int i = 0; i < result.length; i++)
904
result[i] = testedEventData.get(eventTypes[i]).eventClass;
905
906
return result;
907
}
908
909
}
910
911