Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/JDIEventsDebugger.java
41161 views
/*1* Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22package nsk.share.jdi;2324import java.io.PrintStream;25import java.lang.reflect.*;26import java.util.*;2728import com.sun.jdi.*;29import com.sun.jdi.event.*;30import com.sun.jdi.request.*;31import nsk.share.TestBug;3233/*34* Class is used as base debugger in tests for following events and event requests:35* - MonitorContendedEnterRequest / MonitorContendedEnterEvent36* - MonitorContendedEnteredRequest / MonitorContendedEnteredEvent37* - MonitorWaitRequest / MonitorWaitEvent38* - MonitorWaitedRequest / MonitorWaitedEvent39*40* In all these tests similar scenario is used:41* - debugger VM forces debuggee VM to create number of objects which should generate events during test42* - if any event filters are used each generating event object is checked is this object accepted by all filters,43* if object was accepted it should save information about all generated events and this information is available for debugger44* - debuggee performs event generation and stop at breakpoint45* - debugger reads data saved by event generators and checks is only expected events was generated46*/47public class JDIEventsDebugger extends TestDebuggerType2 {48// types of tested events49static public enum EventType {50MONITOR_CONTENTED_ENTER,51MONITOR_CONTENTED_ENTERED,52MONITOR_WAIT,53MONITOR_WAITED54}5556/*57* Class contains information required for event testing58*/59static class TestedEventData {60// event class61public Class<?> eventClass;6263// class representing event data on debuggee's side64public Class<?> eventDataMirrorClass;6566// class representing event data on debugger's side67public Class<?> eventDataClass;6869public TestedEventData(Class<?> eventClass, Class<?> eventDataMirrorClass, Class<?> eventDataClass) {70this.eventClass = eventClass;71this.eventDataMirrorClass = eventDataMirrorClass;72this.eventDataClass = eventDataClass;73}74}7576static public Map<EventType, TestedEventData> testedEventData = new HashMap<EventType, TestedEventData>();7778static {79testedEventData.put(EventType.MONITOR_CONTENTED_ENTER, new TestedEventData(MonitorContendedEnterEvent.class,80DebuggeeEventData.DebugMonitorEnterEventData.class, DebuggerEventData.DebugMonitorEnterEventData.class));8182testedEventData.put(EventType.MONITOR_CONTENTED_ENTERED, new TestedEventData(MonitorContendedEnteredEvent.class,83DebuggeeEventData.DebugMonitorEnteredEventData.class, DebuggerEventData.DebugMonitorEnteredEventData.class));8485testedEventData.put(EventType.MONITOR_WAIT, new TestedEventData(MonitorWaitEvent.class, DebuggeeEventData.DebugMonitorWaitEventData.class,86DebuggerEventData.DebugMonitorWaitEventData.class));8788testedEventData.put(EventType.MONITOR_WAITED, new TestedEventData(MonitorWaitedEvent.class,89DebuggeeEventData.DebugMonitorWaitedEventData.class, DebuggerEventData.DebugMonitorWaitedEventData.class));90}9192static public TestedEventData[] eventDataByEventTypes(EventType[] eventTypes) {93TestedEventData[] result = new TestedEventData[eventTypes.length];9495int i = 0;96for (EventType eventType : eventTypes) {97TestedEventData eventData = testedEventData.get(eventType);9899if (eventData == null)100throw new TestBug("Unsupported event type: " + eventType);101102result[i++] = eventData;103}104105return result;106}107108/*109* Dummy event listener, just accepts all events110*/111public class DummyEventListener extends EventHandler.EventListener {112private volatile boolean breakpointEventReceived;113114public boolean eventReceived(Event event) {115if (event instanceof BreakpointEvent) {116breakpointEventReceived = true;117vm.resume();118}119120return true;121}122123public void waitBreakpoint() {124while (!breakpointEventReceived)125Thread.yield();126}127}128129/*130* Parse common for event tests parameters131*/132protected String[] doInit(String[] args, PrintStream out) {133args = super.doInit(args, out);134135ArrayList<String> standardArgs = new ArrayList<String>();136137for (int i = 0; i < args.length; i++) {138if (args[i].equals("-allowExtraEvents")) {139extraEventClasses = createEventClassArray(args[i + 1]);140141i++;142} else if (args[i].equals("-allowMissedEvents")) {143missedEventClasses = createEventClassArray(args[i + 1]);144145i++;146} else147standardArgs.add(args[i]);148}149150return standardArgs.toArray(new String[standardArgs.size()]);151}152153// can't control some kinds of events (events from system libraries) and154// not all events should be saved for analysis155// (should be implemented in subclasses)156protected boolean shouldSaveEvent(Event event) {157return true;158}159160public Class<?> findEventDataClass(TestedEventData[] testedEventData, Event event) {161for (TestedEventData eventData : testedEventData) {162if (eventData.eventClass.isAssignableFrom(event.getClass()))163return eventData.eventClass;164}165166return null;167}168169/*170* This event listener stores received monitor events until BreakpointEvent171* is not received, after getting of BreakpointEvent checks only expected172* events were received173*/174public class EventListener extends EventHandler.EventListener {175176private TestedEventData[] testedEventData;177178public EventListener(TestedEventData[] testedEventData) {179this.testedEventData = testedEventData;180}181182private boolean shouldHandleEvent(Event event) {183return findEventDataClass(testedEventData, event) == null ? false : true;184}185186volatile boolean breakpointWasReceived;187188// execution was interrupted because of timeout189volatile boolean executionWasInterrupted;190191public boolean eventReceived(Event event) {192if (shouldHandleEvent(event)) {193if (shouldSaveEvent(event)) {194195Class<?> eventClass;196197eventClass = findEventDataClass(testedEventData, event);198List<Event> events = allReceivedEvents.get(eventClass);199200if (events == null) {201events = new LinkedList<Event>();202allReceivedEvents.put(eventClass, events);203}204205events.add(event);206}207208return true;209}210// debuggee should stop at the end of test211else if (event instanceof BreakpointEvent) {212breakpointWasReceived = true;213214try {215// if execution was interrupted because of timeout don't check received216// events because it can consume too much time217if (!executionWasInterrupted) {218// get data from debuggee about all generated events219initExpectedEvents(testedEventData);220221checkEvents();222} else223log.complain("WARNING: execution was interrupted because of timeout, test doesn't check received events");224} catch (Throwable t) {225unexpectedException(t);226}227228vm.resume();229230return true;231}232233return false;234}235}236237protected Class<?> extraEventClasses[];238239protected Class<?> missedEventClasses[];240241/*242* If test can't strictly control event generation it may allow generation243* of extra events and unexpected events aren't treated as error244* (subclasses should specify what kinds of extra events are allowed)245*/246private Class<?>[] allowedExtraEvents() {247return extraEventClasses;248}249250/*251* If test can't strictly control event generation case when debugger doesn't252* receive expected event may be not treated as failure253* (subclasses should specify what kinds of expected events can be not received)254*/255private Class<?>[] allowedMissedEvents() {256return missedEventClasses;257}258259private boolean isExtraEventAllowed(Class<?> eventClass) {260return checkEvent(eventClass, allowedExtraEvents());261}262263private boolean isMissedEventAllowed(Class<?> eventClass) {264return checkEvent(eventClass, allowedMissedEvents());265}266267private boolean checkEvent(Class<?> eventClass, Class<?> classes[]) {268if (classes == null)269return false;270271for (Class<?> klass : classes) {272if (klass.isAssignableFrom(eventClass))273return true;274}275276return false;277}278279// flag is modified from the event listener thread280private volatile boolean eventsNotGenerated;281282/*283* Method returns true if test expects event generation, but events weren't284* generated. If test can't strictly control event generation such case isn't285* necessarily treated as test failure (sublasses of JDIEventsDebugger can286* for example try to rerun test several times).287*/288protected boolean eventsNotGenerated() {289return eventsNotGenerated;290}291292/*293* Print debug information about expected and received events(this data294* should be stored in lists 'allExpectedEvents' and 'allReceivedEvents')295* and check that only expected events were received296*/297private void checkEvents() {298if (getAllExpectedEvents().size() > 0 && getAllReceivedEvents().size() == 0 && allowedMissedEvents() != null) {299log.display("WARNING: didn't receive any event");300eventsNotGenerated = true;301}302303log.display("ALL RECEIVED EVENTS: ");304for (Event event : getAllReceivedEvents())305log.display("received event: " + eventToString(event));306307log.display("ALL EXPECTED EVENTS: ");308for (DebuggerEventData.DebugEventData eventData : getAllExpectedEvents())309log.display("expected event: " + eventData);310311// try to find received event in the list of expected events, if this event312// was found remove data about events from both lists313for (Class<?> eventClass : allReceivedEvents.keySet()) {314List<Event> receivedEvents = allReceivedEvents.get(eventClass);315List<DebuggerEventData.DebugEventData> expectedEvents = allExpectedEvents.get(eventClass);316317for (Iterator<Event> allReceivedEventsIterator = receivedEvents.iterator();318allReceivedEventsIterator.hasNext();) {319320Event event = allReceivedEventsIterator.next();321322for (Iterator<DebuggerEventData.DebugEventData> allExpectedEventsIterator = expectedEvents.iterator();323allExpectedEventsIterator.hasNext();) {324325DebuggerEventData.DebugEventData debugEventData = allExpectedEventsIterator.next();326327if (debugEventData.shouldCheckEvent(event)) {328if (debugEventData.checkEvent(event)) {329allExpectedEventsIterator.remove();330allReceivedEventsIterator.remove();331break;332}333}334}335}336}337338List<Event> receivedEventsLeft = getAllReceivedEvents();339340// check is all received events were found in expected341if (receivedEventsLeft.size() > 0) {342// if allowExtraEvents = true extra events are not treated as error343for (Event event : receivedEventsLeft) {344if (!isExtraEventAllowed(event.getClass())) {345setSuccess(false);346log.complain("Unexpected event " + eventToString(event));347}348}349}350351List<DebuggerEventData.DebugEventData> expectedEventsLeft = getAllExpectedEvents();352353// check is all expected events were received354if (expectedEventsLeft.size() > 0) {355for (DebuggerEventData.DebugEventData eventData : expectedEventsLeft) {356if (!isMissedEventAllowed(eventData.eventClass)) {357setSuccess(false);358log.complain("Expected event was not generated: " + eventData);359}360}361}362}363364private String eventToString(Event event) {365try {366if (event instanceof MonitorContendedEnterEvent)367return event + ". Details(MonitorContendedEnterEvent):" + " Monitor: " + ((MonitorContendedEnterEvent) event).monitor() + " Thread: "368+ ((MonitorContendedEnterEvent) event).thread();369else if (event instanceof MonitorContendedEnteredEvent)370return event + ". Details(MonitorContendedEnteredEvent):" + " Monitor: " + ((MonitorContendedEnteredEvent) event).monitor()371+ " Thread: " + ((MonitorContendedEnteredEvent) event).thread();372else if (event instanceof MonitorWaitEvent)373return event + ". Details(MonitorWaitEvent):" + " Monitor: " + ((MonitorWaitEvent) event).monitor() + " Thread: "374+ ((MonitorWaitEvent) event).thread() + " Timeout: " + ((MonitorWaitEvent) event).timeout();375else if (event instanceof MonitorWaitedEvent)376return event + ". Details(MonitorWaitedEvent):" + " Monitor: " + ((MonitorWaitedEvent) event).monitor() + " Thread: "377+ ((MonitorWaitedEvent) event).thread() + " Timedout: " + ((MonitorWaitedEvent) event).timedout();378379return event.toString();380}381// this exception can occur when unexpected event was received382catch (ObjectCollectedException e) {383// allowExtraEvents=true extra events are not treated as error384if (!isExtraEventAllowed(event.getClass())) {385setSuccess(false);386e.printStackTrace(log.getOutStream());387log.complain("Unexpected ObjectCollectedException was caught, possible unexpected event was received");388}389390return event.getClass().getName() + " [ Can't get full description, ObjectCollectedException was thrown ]";391}392}393394// events received during test execution are stored here395private Map<Class<?>, List<Event>> allReceivedEvents = new HashMap<Class<?>, List<Event>>();396397private List<Event> getAllReceivedEvents() {398List<Event> result = new LinkedList<Event>();399400for (Class<?> eventClass : allReceivedEvents.keySet()) {401result.addAll(allReceivedEvents.get(eventClass));402}403404return result;405}406407protected Map<Class<?>, List<DebuggerEventData.DebugEventData>> allExpectedEvents = new HashMap<Class<?>, List<DebuggerEventData.DebugEventData>>();408409private List<DebuggerEventData.DebugEventData> getAllExpectedEvents() {410List<DebuggerEventData.DebugEventData> result = new LinkedList<DebuggerEventData.DebugEventData>();411412for (Class<?> eventClass : allExpectedEvents.keySet()) {413result.addAll(allExpectedEvents.get(eventClass));414}415416return result;417}418419// find in debuggee VM and add to the list 'allExpectedEvents' instances420// of classes representing generated events421protected void initExpectedEvents(TestedEventData testedEventData[]) {422List<DebuggerEventData.DebugEventData> events;423424ReferenceType referenceType = debuggee.classByName(debuggeeClassNameWithoutArgs());425426ArrayReference generatedEvents = (ArrayReference) referenceType.getValue(referenceType.fieldByName("generatedEvents"));427428for (TestedEventData eventData : testedEventData) {429events = new LinkedList<DebuggerEventData.DebugEventData>();430allExpectedEvents.put(eventData.eventClass, events);431}432433for (int i = 0; i < generatedEvents.length(); i++) {434ObjectReference debuggeeMirror = (ObjectReference) generatedEvents.getValue(i);435436for (TestedEventData eventData : testedEventData) {437438if (debuggeeMirror.referenceType().name().equals(eventData.eventDataMirrorClass.getName())) {439events = allExpectedEvents.get(eventData.eventClass);440441/*442* Use reflection to create object representing generated443* event Event data class should has constructor with single444* parameter of type com.sun.jdi.ObjectReference445*/446Constructor<?> constructor;447448try {449constructor = eventData.eventDataClass.getConstructor(new Class[] { ObjectReference.class });450} catch (NoSuchMethodException e) {451TestBug testBug = new TestBug(452"Class representing debug event data should implement constructor with single parameter of type com.sun.jdi.ObjectReference");453testBug.initCause(e);454throw testBug;455}456457DebuggerEventData.DebugEventData expectedEvent;458459try {460expectedEvent = (DebuggerEventData.DebugEventData) constructor.newInstance(new Object[] { debuggeeMirror });461} catch (Exception e) {462TestBug testBug = new TestBug("Error when create debug event data: " + e);463testBug.initCause(e);464throw testBug;465}466events.add(expectedEvent);467}468}469}470}471472private void printFiltersInfo() {473if (eventFilters.size() > 0) {474log.display("Use following filters: ");475476for (EventFilters.DebugEventFilter filter : eventFilters)477log.display("" + filter);478} else {479log.display("Don't use event filters");480}481}482483// filters used in test484protected List<EventFilters.DebugEventFilter> eventFilters = new LinkedList<EventFilters.DebugEventFilter>();485486// Check is object generating events matches all filters,487// if object was accepted by all filters set this object's field488// 'saveEventData' to 'true', otherwise to 'false',489private void checkEventGenerator(ThreadReference eventThread, ObjectReference executor) {490boolean acceptedByFilters = true;491492for (EventFilters.DebugEventFilter eventFilter : eventFilters) {493if (!eventFilter.isObjectMatch(executor, eventThread)) {494acceptedByFilters = false;495break;496}497}498499try {500executor.setValue(executor.referenceType().fieldByName("saveEventData"), vm.mirrorOf(acceptedByFilters));501} catch (Exception e) {502throw new TestBug("Unexpected exception when change object field in debugee VM: " + e, e);503}504}505506/*507* Find all event generating threads in debuggee VM (instances of508* nsk.share.jdi.MonitorEventsDebuggee$MonitorActionsThread) all these509* threads have special field - 'executor', this is object which generates510* events. If event generating thread and event generating object was511* accepted by all filters generating object should store information about512* all generated events and this information will be available for debugger513*/514protected void initializeEventGenerators() {515printFiltersInfo();516517List<ThreadReference> eventThreads = getEventThreads();518519for (ThreadReference eventThread : eventThreads) {520ObjectReference executor = (ObjectReference) eventThread.getValue(eventThread.referenceType().fieldByName("executor"));521checkEventGenerator(eventThread, executor);522}523524// debuggee's main thread also can generate events, need to filter it in525// the same way as other threads526checkEventGenerator(debuggee.threadByName(JDIEventsDebuggee.MAIN_THREAD_NAME), findSingleObjectReference(debuggeeClassNameWithoutArgs()));527}528529// find instances of nsk.share.jdi.MonitorEventsDebuggee$MonitorActionsThread530protected List<ThreadReference> getEventThreads() {531ReferenceType referenceType = debuggee.classByName(JDIEventsDebuggee.EventActionsThread.class.getName());532List<ObjectReference> debuggeeEventThreads = referenceType.instances(0);533534List<ThreadReference> result = new LinkedList<ThreadReference>();535for (ObjectReference threadReference : debuggeeEventThreads)536result.add((ThreadReference) threadReference);537538return result;539}540541// find instances of nsk.share.jdi.MonitorEventsDebuggee$MonitorActionsThread,542// and get value of this object's field with name 'executor'543protected List<ObjectReference> getEventObjects() {544List<ObjectReference> eventObjects = new LinkedList<ObjectReference>();545546List<ThreadReference> eventThreads = getEventThreads();547548for (ThreadReference eventThread : eventThreads) {549eventObjects.add((ObjectReference) eventThread.getValue(eventThread.referenceType().fieldByName("executor")));550}551552return eventObjects;553}554555// remove all filters, received and expected events556private void clearTestData() {557allExpectedEvents.clear();558allReceivedEvents.clear();559eventFilters.clear();560eventsNotGenerated = false;561}562563private boolean isEventSupported(EventType eventType) {564switch (eventType) {565case MONITOR_CONTENTED_ENTER:566case MONITOR_CONTENTED_ENTERED:567case MONITOR_WAIT:568case MONITOR_WAITED:569return vm.canRequestMonitorEvents();570571default:572throw new TestBug("Invalid tested event type: " + eventType);573}574}575576// create instance of EventRequest depending on given eventType577private EventRequest createTestRequest(EventType eventType) {578switch (eventType) {579case MONITOR_CONTENTED_ENTER:580return debuggee.getEventRequestManager().createMonitorContendedEnterRequest();581case MONITOR_CONTENTED_ENTERED:582return debuggee.getEventRequestManager().createMonitorContendedEnteredRequest();583case MONITOR_WAIT:584return debuggee.getEventRequestManager().createMonitorWaitRequest();585case MONITOR_WAITED:586return debuggee.getEventRequestManager().createMonitorWaitedRequest();587588default:589throw new TestBug("Invalid tested event type: " + eventType);590}591}592593// create command depending on given eventType594private String createCommand(EventType eventTypes[], int eventsNumber) {595String command = JDIEventsDebuggee.COMMAND_CREATE_ACTIONS_EXECUTORS + ":" + eventsNumber + ":";596597for (EventType eventType : eventTypes) {598switch (eventType) {599case MONITOR_CONTENTED_ENTER:600case MONITOR_CONTENTED_ENTERED:601case MONITOR_WAIT:602case MONITOR_WAITED:603command += " " + eventType.name();604break;605606default:607throw new TestBug("Invalid tested event type: " + eventType);608}609}610611return command;612}613614// get list of event requests from EventRequestManager depending on the given eventType615private List<?> getEventRequestsFromManager(EventType eventType) {616switch (eventType) {617case MONITOR_CONTENTED_ENTER:618return debuggee.getEventRequestManager().monitorContendedEnterRequests();619case MONITOR_CONTENTED_ENTERED:620return debuggee.getEventRequestManager().monitorContendedEnteredRequests();621case MONITOR_WAIT:622return debuggee.getEventRequestManager().monitorWaitRequests();623case MONITOR_WAITED:624return debuggee.getEventRequestManager().monitorWaitedRequests();625626default:627throw new TestBug("Invalid tested event type: " + eventType);628}629}630631protected EventHandler eventHandler;632633private EventListener eventListener;634635// perform event generation before test begins to load all using classes636// and avoid unexpected events related to classloading637protected void prepareDebuggee(EventType[] eventTypes) {638initDefaultBreakpoint();639640eventHandler = new EventHandler(debuggee, log);641eventHandler.startListening();642643// use event listener which just skip all received events644DummyEventListener dummyEventListener = new DummyEventListener();645eventHandler.addListener(dummyEventListener);646647EventRequest eventRequests[] = new EventRequest[eventTypes.length];648649for (int i = 0; i < eventRequests.length; i++) {650eventRequests[i] = createTestRequest(eventTypes[i]);651eventRequests[i].setSuspendPolicy(EventRequest.SUSPEND_NONE);652eventRequests[i].enable();653}654655// debuggee should create event generators656pipe.println(createCommand(eventTypes, 1));657658if (!isDebuggeeReady())659return;660661// start event generation662pipe.println(JDIEventsDebuggee.COMMAND_START_EXECUTION);663664if (!isDebuggeeReady())665return;666667for (int i = 0; i < eventRequests.length; i++)668eventRequests[i].disable();669670dummyEventListener.waitBreakpoint();671672eventHandler.removeListener(dummyEventListener);673674pipe.println(JDIEventsDebuggee.COMMAND_WAIT_EXECUTION_COMPLETION);675676if (!isDebuggeeReady())677return;678679eventListener = new EventListener(eventDataByEventTypes(eventTypes));680eventHandler.addListener(eventListener);681}682683/*684* Method for stress testing, allows specify requests for several event685* types, number of events which should be generated during test and number686* of threads which simultaneously generate events687*/688protected void stressTestTemplate(EventType[] eventTypes, int eventsNumber, int threadsNumber) {689for (EventType eventType : eventTypes) {690if (!isEventSupported(eventType)) {691log.complain("Can't test event because of it isn't supported: " + eventType);692return;693}694}695696// Used framework is intended for testing event filters and debuggee697// creates 3 threads performing event generation and there is possibility698// to filter events from some threads699for (int i = 0; i < threadsNumber; i++) {700pipe.println(createCommand(eventTypes, eventsNumber));701702if (!isDebuggeeReady())703return;704}705706// clear data(if this method is executed several times)707clearTestData();708709initializeEventGenerators();710711EventRequest eventRequests[] = new EventRequest[eventTypes.length];712713// create event requests714for (int i = 0; i < eventTypes.length; i++) {715eventRequests[i] = createTestRequest(eventTypes[i]);716eventRequests[i].setSuspendPolicy(EventRequest.SUSPEND_NONE);717eventRequests[i].enable();718719log.display("Use following event request: " + eventRequests[i]);720}721722// stressTestTemplate can control only execution time, so ignore iteration count723stresser.start(0);724try {725// start event generation726pipe.println(JDIEventsDebuggee.COMMAND_START_EXECUTION);727728if (!isDebuggeeReady())729return;730731// check is stressTime exceeded732while (stresser.continueExecution()) {733try {734Thread.sleep(100);735} catch (InterruptedException e) {736unexpectedException(e);737}738739// periodically check is test completed740if (eventListener.breakpointWasReceived)741break;742}743} finally {744stresser.finish();745}746747// debugger should interrupt test because of timeout748if (!eventListener.breakpointWasReceived) {749750eventListener.executionWasInterrupted = true;751752log.complain("WARNING: time is exceeded, interrupt test");753754pipe.println(JDIEventsDebuggee.COMMAND_STOP_EXECUTION);755756if (!isDebuggeeReady())757return;758}759760pipe.println(JDIEventsDebuggee.COMMAND_WAIT_EXECUTION_COMPLETION);761762if (!isDebuggeeReady())763return;764765for (int i = 0; i < eventRequests.length; i++)766eventRequests[i].disable();767}768769/*770* Hook method for subclasses implementing tests against event filters (it is called from eventFilterTestTemplate)771*/772protected EventFilters.DebugEventFilter[] createTestFilters(int testedFilterIndex) {773throw new TestBug("Not implemented");774}775776/*777* Test event request with filter778*779* Also this method check following:780* - InvalidRequestStateException is thrown if add filter for deleted or enabled request781* - EventRequestManager.xxxRequests() returns created event request782*/783protected void eventFilterTestTemplate(EventType eventType, int testedFilterIndex) {784if (!isEventSupported(eventType)) {785log.complain("Can't test event because of it isn't supported: " + eventType);786return;787}788789// debuggee create event generators790pipe.println(createCommand(new EventType[] { eventType }, 1));791792if (!isDebuggeeReady())793return;794795clearTestData();796797EventFilters.DebugEventFilter[] filters = createTestFilters(testedFilterIndex);798799for (EventFilters.DebugEventFilter filter : filters) {800if (filter.isSupported(vm))801eventFilters.add(filter);802else {803log.complain("Can't test filter because of it isn't supported: " + filter);804return;805}806}807808initializeEventGenerators();809810// create event request811EventRequest request = createTestRequest(eventType);812request.setSuspendPolicy(EventRequest.SUSPEND_NONE);813814// try add filter to enabled request, expect815// 'InvalidRequestStateException'816request.enable();817try {818for (EventFilters.DebugEventFilter filter : filters)819filter.addFilter(request);820821setSuccess(false);822log.complain("Expected 'InvalidRequestStateException' was not thrown");823} catch (InvalidRequestStateException e) {824// expected exception825} catch (Throwable e) {826setSuccess(false);827log.complain("Unexpected exception: " + e);828e.printStackTrace(log.getOutStream());829}830831// add event filter832request.disable();833834for (EventFilters.DebugEventFilter filter : filters)835addFilter(filter, request);836837request.enable();838839log.display("Use following event request: " + request);840841// start event generation842pipe.println(JDIEventsDebuggee.COMMAND_START_EXECUTION);843844if (!isDebuggeeReady())845return;846847// wait execution completion848pipe.println(JDIEventsDebuggee.COMMAND_WAIT_EXECUTION_COMPLETION);849850if (!isDebuggeeReady())851return;852853// check that method EventRequestManager.xxxRequests() return created854// request855if (!getEventRequestsFromManager(eventType).contains(request)) {856setSuccess(false);857log.complain("EventRequestManager doesn't return request: " + request);858}859860// delete event request861debuggee.getEventRequestManager().deleteEventRequest(request);862863// try add filter to removed request, expect864// 'InvalidRequestStateException'865try {866for (EventFilters.DebugEventFilter filter : filters)867filter.addFilter(request);868setSuccess(false);869log.complain("Expected 'InvalidRequestStateException' was not thrown");870} catch (InvalidRequestStateException e) {871// expected exception872} catch (Throwable t) {873unexpectedException(t);874}875}876877private void addFilter(EventFilters.DebugEventFilter filter, EventRequest request) {878try {879filter.addFilter(request);880} catch (Throwable t) {881unexpectedException(t);882}883}884885// used to parse parameters -allowExtraEvents and -allowMissedEvents886private Class<?>[] createEventClassArray(String string) {887String eventTypesNames[] = string.split(":");888EventType eventTypes[] = new EventType[eventTypesNames.length];889try {890for (int i = 0; i < eventTypesNames.length; i++) {891eventTypes[i] = EventType.valueOf(eventTypesNames[i]);892}893} catch (IllegalArgumentException e) {894throw new TestBug("Invalid event type", e);895}896897if (eventTypesNames.length == 0)898throw new TestBug("Event types weren't specified");899900Class<?>[] result = new Class[eventTypesNames.length];901902for (int i = 0; i < result.length; i++)903result[i] = testedEventData.get(eventTypes[i]).eventClass;904905return result;906}907908}909910911