blob: 5991a941910c95989a5cec5f970cfd819a4fd3c9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Anatoly F. Bondarenko
*/
/**
* Created on 26.10.2006
*/
package org.apache.harmony.jpda.tests.jdwp.Events;
import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
import org.apache.harmony.jpda.tests.framework.jdwp.EventMod;
import org.apache.harmony.jpda.tests.framework.jdwp.EventPacket;
import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
import org.apache.harmony.jpda.tests.framework.jdwp.Location;
import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent;
import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
/**
* JDWP Unit test for possible combined (co-located) events:
* METHOD_ENTRY, SINGLE_STEP, BREAKPOINT, METHOD_EXIT.
*/
public class CombinedEvents003Test extends CombinedEventsTestCase {
private final String debuggeeSignature = getDebuggeeClassSignature();
private final String methodForEvents = "emptyMethod";
private final String methodEntryClassNameRegexp = getDebuggeeClassName();
private boolean eventVmDeathReceived = false;
@Override
protected String getDebuggeeClassName() {
return CombinedEvents003Debuggee.class.getName();
}
/**
* This test case checks events:
* METHOD_ENTRY, SINGLE_STEP, BREAKPOINT, METHOD_EXIT
* for empty method.
*/
public void testCombinedEvents003_01() {
logWriter.println("==> testCombinedEvents003_01 started");
byte[] EXPECTED_EVENTS_ARRAY = { JDWPConstants.EventKind.METHOD_ENTRY,
JDWPConstants.EventKind.BREAKPOINT,
JDWPConstants.EventKind.SINGLE_STEP,
JDWPConstants.EventKind.METHOD_EXIT};
String debuggeeMainThreadName = synchronizer.receiveMessage();
long debuggeeClassID = debuggeeWrapper.vmMirror
.getClassID(debuggeeSignature);
logWriter.println("=> debuggeeClassID = " + debuggeeClassID);
long threadID = debuggeeWrapper.vmMirror.getThreadID(debuggeeMainThreadName);
logWriter.println("=> threadID = " + threadID);
long runMethodID = debuggeeWrapper.vmMirror.getMethodID(debuggeeClassID, "run");
logWriter.println("=> runMethodID = " + runMethodID);
long fakeMethodID = debuggeeWrapper.vmMirror.getMethodID(debuggeeClassID, "fakeMethod");
logWriter.println("=> fakeMethodID = " + fakeMethodID);
logWriter.println("");
logWriter.println("=> Info for tested method '" + methodForEvents + "':");
long testedMethodID = debuggeeWrapper.vmMirror.getMethodID(debuggeeClassID, methodForEvents);
if (testedMethodID == -1 ) {
String failureMessage = "## FAILURE: Can NOT get MethodID for class '"
+ getDebuggeeClassName() + "'; Method name = " + methodForEvents;
printErrorAndFail(failureMessage);
}
logWriter.println("=> testedMethodID = " + testedMethodID);
printMethodLineTable(debuggeeClassID, null, methodForEvents);
// set requests for events that will be checked
logWriter.println("");
logWriter.println("=> Set request for BREAKPOINT event in debuggee: "
+ getDebuggeeClassName() + ", beginning of method: "
+ methodForEvents);
Location combinedEventsLocation = getMethodEntryLocation(debuggeeClassID, methodForEvents);
if ( combinedEventsLocation == null ) {
String failureMessage = "## FAILURE: Can NOT get MethodEntryLocation for method '"
+ methodForEvents + "'";
printErrorAndFail(failureMessage);
}
ReplyPacket reply = debuggeeWrapper.vmMirror.setBreakpoint(combinedEventsLocation);
int breakpointRequestID = reply.getNextValueAsInt();
logWriter.println("=> Breakpoint requestID = " + breakpointRequestID);
logWriter.println("=> Set request for METHOD_ENTRY event in debuggee: "
+ getDebuggeeClassName());
reply = debuggeeWrapper.vmMirror
.setMethodEntry(methodEntryClassNameRegexp);
checkReplyPacket(reply, "Set METHOD_ENTRY event");
int methodEntryRequestID = reply.getNextValueAsInt();
logWriter.println("=> METHOD_ENTRY requestID = " + methodEntryRequestID);
logWriter.println("=> Set request for METHOD_EXIT event in debuggee: "
+ getDebuggeeClassName());
reply = debuggeeWrapper.vmMirror
.setMethodExit(methodEntryClassNameRegexp);
checkReplyPacket(reply, "Set METHOD_EXIT event");
int methodExitRequestID = reply.getNextValueAsInt();
logWriter.println("=> METHOD_EXIT requestID = " + methodExitRequestID);
logWriter.println("=> Set request for SINGLE_STEP event in class "
+ debuggeeSignature);
CommandPacket setRequestCommand = new CommandPacket(
JDWPCommands.EventRequestCommandSet.CommandSetID,
JDWPCommands.EventRequestCommandSet.SetCommand);
setRequestCommand
.setNextValueAsByte(JDWPConstants.EventKind.SINGLE_STEP);
setRequestCommand.setNextValueAsByte(JDWPConstants.SuspendPolicy.ALL);
setRequestCommand.setNextValueAsInt(2);
setRequestCommand.setNextValueAsByte(EventMod.ModKind.Step);
setRequestCommand.setNextValueAsThreadID(threadID);
setRequestCommand.setNextValueAsInt(JDWPConstants.StepSize.MIN);
setRequestCommand.setNextValueAsInt(JDWPConstants.StepDepth.INTO);
setRequestCommand.setNextValueAsByte(EventMod.ModKind.ClassOnly);
setRequestCommand.setNextValueAsReferenceTypeID(debuggeeClassID);
ReplyPacket setRequestReply = debuggeeWrapper.vmMirror
.performCommand(setRequestCommand);
checkReplyPacket(setRequestReply, "EventRequest::Set command");
int stepRequestID = setRequestReply.getNextValueAsInt();
logWriter.println("=> SINGLE_STEP requestID = " + stepRequestID);
logWriter.println("");
logWriter.println("=> Send SGNL_CONTINUE signal to debuggee...");
synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
logWriter.println("=> Try to receive and check combined events: "
+ " METHOD_ENTRY, SINGLE_STEP, BREAKPOINT, METHOD_EXIT events; ignore single SINGLE_STEP event");
receiveAndCheckEvents(EXPECTED_EVENTS_ARRAY, combinedEventsLocation);
if ( eventVmDeathReceived ) {
logWriter.println("==> testCombinedEvents001 is FINISHing as VM_DEATH is received!");
return;
}
logWriter.println("");
logWriter.println("=> Clean request for METHOD_ENTRY event...");
ReplyPacket clearReply = debuggeeWrapper.vmMirror.clearEvent(
JDWPConstants.EventKind.METHOD_ENTRY, methodEntryRequestID);
checkReplyPacket(clearReply, "EventRequest::Clear");
logWriter.println("");
logWriter.println("=> Clean request for SINGLE_STEP event...");
clearReply = debuggeeWrapper.vmMirror.clearEvent(
JDWPConstants.EventKind.SINGLE_STEP, stepRequestID);
checkReplyPacket(clearReply, "EventRequest::Clear");
logWriter.println("=> Resume debuggee");
debuggeeWrapper.vmMirror.resume();
// check that no other events, except VM_DEATH, will be received
checkVMDeathEvent();
logWriter.println("");
logWriter.println("==> testCombinedEvents003_01 PASSED");
}
void receiveAndCheckEvents(byte[] EXPECTED_EVENTS_ARRAY, Location expectedLocation) {
int EXPECTED_EVENTS_COUNT = EXPECTED_EVENTS_ARRAY.length;
for (;;) {
logWriter.println("=>");
logWriter.println("=> Receiving events...");
EventPacket event = debuggeeWrapper.vmMirror.receiveEvent();
ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(event);
// print all received events
logWriter.println("=> Received event packet with events number = " + parsedEvents.length + " :");
for (int i = 0; i < parsedEvents.length; i++) {
logWriter.println("");
logWriter.println("=> Event #" + (i+1) + " in packet -");
logWriter.println("=> EventKind: "
+ parsedEvents[i].getEventKind()
+ "["
+ JDWPConstants.EventKind.getName(parsedEvents[i]
.getEventKind()) + "]");
logWriter.println("=> RequestID: "
+ parsedEvents[i].getRequestID());
if ( parsedEvents[i].getEventKind() == JDWPConstants.EventKind.VM_DEATH ) {
eventVmDeathReceived = true;
}
}
if ( eventVmDeathReceived ) {
return;
}
checkEventsLocation(parsedEvents, null); // DBG__
// the following code checks received events
if (parsedEvents.length == 1) {
debuggeeWrapper.vmMirror.resume();
continue;
/* DBG__
if (parsedEvents[0].getEventKind() == JDWPConstants.EventKind.SINGLE_STEP) {
logWriter.println("");
logWriter.println("=> Resume debuggee");
logWriter.println("");
debuggeeWrapper.vmMirror.resume();
continue;
} else {
logWriter.println("##FAILURE: received unexpected event: "
+ parsedEvents[0].getEventKind()
+ "["
+ JDWPConstants.EventKind.getName(parsedEvents[0]
.getEventKind())
+ "] instead of SINGLE_STEP");
fail("received event is not SINGLE_STEP event: "
+ parsedEvents[0].getEventKind()
+ "["
+ JDWPConstants.EventKind.getName(parsedEvents[0]
.getEventKind()) + "]");
}
// DBG__ */
//DBG__} else if (parsedEvents.length == EXPECTED_EVENTS_COUNT) {
} else if (parsedEvents.length > 1) {
logWriter.println("");
logWriter
.println("=> Combined events are received. Check events..");
boolean success = true;
for (int i = 0; i < parsedEvents.length; i++) {
boolean isFound = false;
for (int j = 0; j < EXPECTED_EVENTS_COUNT; j++) {
if (parsedEvents[i].getEventKind() == EXPECTED_EVENTS_ARRAY[j]) {
EXPECTED_EVENTS_ARRAY[j] = 0;
isFound = true;
break;
}
}
if (!isFound) {
logWriter.println("##FAILURE: received unexpected event: "
+ parsedEvents[i].getEventKind()
+ "["
+ JDWPConstants.EventKind
.getName(parsedEvents[0]
.getEventKind()) + "]");
success = false;
}
}
if (!success) {
logWriter.println("");
logWriter.println("##FAILURE: the following expected events were not received: ");
for (int k = 0; k < EXPECTED_EVENTS_COUNT; k++) {
if (EXPECTED_EVENTS_ARRAY[k] != 0)
logWriter.println(" #"
+ k
+ ": "
+ EXPECTED_EVENTS_ARRAY[k]
+ "["
+ JDWPConstants.EventKind
.getName(EXPECTED_EVENTS_ARRAY[k])
+ "]");
}
fail("not all expected events were received");
}
for (int i = 0; i < parsedEvents.length; i++) {
byte eventKind = parsedEvents[i].getEventKind();
long eventThreadID = ((ParsedEvent.EventThread)parsedEvents[i]).getThreadID();
logWriter.println("");
logWriter.println("=> Chcek location for combined event N " + (i+1)
+ ": Event kind = " + eventKind + "("
+ JDWPConstants.EventKind.getName(eventKind) +"); eventThreadID = "
+ eventThreadID);
Location eventLocation = null;
switch ( eventKind ) {
case JDWPConstants.EventKind.METHOD_ENTRY:
eventLocation = ((ParsedEvent.Event_METHOD_ENTRY)parsedEvents[i]).getLocation();
break;
case JDWPConstants.EventKind.SINGLE_STEP:
eventLocation = ((ParsedEvent.Event_SINGLE_STEP)parsedEvents[i]).getLocation();
break;
case JDWPConstants.EventKind.BREAKPOINT:
eventLocation = ((ParsedEvent.Event_BREAKPOINT)parsedEvents[i]).getLocation();
break;
case JDWPConstants.EventKind.METHOD_EXIT:
eventLocation = ((ParsedEvent.Event_METHOD_EXIT)parsedEvents[i]).getLocation();
break;
}
long eventClassID = eventLocation.classID;
logWriter.println("=> ClassID in event = " + eventClassID);
if ( expectedLocation.classID != eventClassID ) {
logWriter.println("## FAILURE: Unexpected ClassID in event!");
logWriter.println("## Expected ClassID = " + expectedLocation.classID );
success = false;
} else {
logWriter.println("=> OK - it is expected ClassID");
}
long eventMethodID = eventLocation.methodID;
logWriter.println("=> MethodID in event = " + eventMethodID);
if ( expectedLocation.methodID != eventMethodID ) {
logWriter.println("## FAILURE: Unexpected MethodID in event!");
logWriter.println("## Expected MethodID = " + expectedLocation.methodID);
success = false;
} else {
logWriter.println("=> OK - it is expected MethodID");
}
long eventCodeIndex = eventLocation.index;
logWriter.println("=> CodeIndex in event = " + eventCodeIndex);
if ( expectedLocation.index != eventCodeIndex ) {
logWriter.println("## FAILURE: Unexpected CodeIndex in event!");
logWriter.println("## Expected CodeIndex = "
+ expectedLocation.index);
success = false;
} else {
logWriter.println("=> OK - it is expected CodeIndex)");
}
}
logWriter.println("");
if ( ! success ) {
String failureMessage = "## FAILURE: Unexpected events' locations are found out!";
logWriter.println(failureMessage);
//DBG__printErrorAndFail(failureMessage);
} else {
logWriter.println("=> OK - all combined events have expected location!");
}
break;
} else {
logWriter.println("##FAILURE: received unexpected number of events: "
+ parsedEvents.length
+ " instead of 1 or "
+ EXPECTED_EVENTS_COUNT);
fail("received unexpected number of events: "
+ parsedEvents.length);
}
}
}
void checkVMDeathEvent() {
if ( eventVmDeathReceived ) {
return;
}
logWriter.println("=> Wait for VM_DEATH event...");
while ( true ) { //DBG_
logWriter.println("=> Receiving events...");
EventPacket event = debuggeeWrapper.vmMirror.receiveEvent();
ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(event);
if (parsedEvents.length != 1
|| parsedEvents[0].getEventKind() != JDWPConstants.EventKind.VM_DEATH) {
// print all received events
logWriter.println("##FAILURE: Received unexpected events");
logWriter.println("=> Events received: " + parsedEvents.length);
for (int i = 0; i < parsedEvents.length; i++) {
logWriter.println("");
logWriter.println("=> Event #" + i + ";");
logWriter.println("=> EventKind: "
+ parsedEvents[i].getEventKind()
+ "["
+ JDWPConstants.EventKind.getName(parsedEvents[i]
.getEventKind()) + "]");
logWriter.println("=> RequestID: "
+ parsedEvents[i].getRequestID());
}
checkEventsLocation(parsedEvents, null); // DBG__
logWriter.println("=> Resume debuggee"); //DBG__
debuggeeWrapper.vmMirror.resume(); //DBG__
continue; //DBG__
//DBG__fail("unexpected events received");
}
logWriter.println("=> OK - VM_DEATH event was received. ");
break; //DBG__
} // DBG__
}
}