blob: bb2451cc721be525d70db6bc8882af7267fd46ae [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.
*/
package org.apache.harmony.jpda.tests.jdwp.Events;
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.framework.jdwp.TaggedObject;
import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
/**
* JDWP Unit test for uncaught EXCEPTION event.
*/
public class ExceptionUncaughtTest extends ExceptionBaseTest {
private static final String EXCEPTION_SIGNATURE = getClassSignature(DebuggeeException.class);
private static final String THROW_EXCEPTION_METHOD = "throwDebuggeeException";
@Override
protected String getDebuggeeClassName() {
return ExceptionUncaughtDebuggee.class.getName();
}
/**
* This testcase is for uncaught EXCEPTION event and reported exception object.
* <BR>It runs ExceptionUncaughtDebuggee that throws an uncaught DebuggeeException.
* It verifies the following:
* <ul>
* <li>the requested EXCEPTION event occurs</li>
* <li>the reported exception object is not null</li>
* <li>the reported exception object is instance of expected class with expected tag</li>
* </ul>
*/
public void testExceptionUncaughtEvent_ExceptionObject() {
printTestLog("STARTED...");
ParsedEvent.Event_EXCEPTION exceptionEvent = requestAndReceiveExceptionEvent();
TaggedObject returnedException = exceptionEvent.getException();
// assert that exception ObjectID is not null
printTestLog("returnedException.objectID = " + returnedException.objectID);
assertTrue("Returned exception object is null.", returnedException.objectID != 0);
// assert that exception tag is OBJECT
printTestLog("returnedException.tag = " + returnedException.objectID);
assertEquals("Returned exception tag is not OBJECT.",
JDWPConstants.Tag.OBJECT_TAG, returnedException.tag);
// assert that exception class is the expected one
long typeID = getObjectReferenceType(returnedException.objectID);
String returnedExceptionSignature = getClassSignature(typeID);
printTestLog("returnedExceptionSignature = |" + returnedExceptionSignature+"|");
assertString("Invalid signature of returned exception,",
EXCEPTION_SIGNATURE, returnedExceptionSignature);
// resume debuggee
printTestLog("resume debuggee...");
debuggeeWrapper.vmMirror.resume();
}
/**
* This testcase is for uncaught EXCEPTION event and reported throw location.
* <BR>It runs ExceptionUncaughtDebuggee that throws an uncaught DebuggeeException.
* It verifies the following:
* <ul>
* <li>the requested EXCEPTION event occurs</li>
* <li>the reported thread is not null</li>
* <li>the reported throw location is not null</li>
* <li>the reported throw location is equal to location of the top stack frame</li>
* </ul>
*/
public void testExceptionUncaughtEvent_ThrowLocation() {
printTestLog("STARTED...");
ParsedEvent.Event_EXCEPTION exceptionEvent = requestAndReceiveExceptionEvent();
long returnedThread = exceptionEvent.getThreadID();
Location throwLocation = exceptionEvent.getLocation();
// assert that exception thread is not null
printTestLog("returnedThread = " + returnedThread);
assertTrue("Returned exception ThreadID is null,", returnedThread != 0);
// assert that exception location is not null
printTestLog("returnedExceptionLoc = " + throwLocation);
assertNotNull("Returned exception location is null,", throwLocation);
// assert that top stack frame location is not null
Location topFrameLoc = getTopFrameLocation(returnedThread);
printTestLog("topFrameLoc = " + topFrameLoc);
assertNotNull("Returned top stack frame location is null,", topFrameLoc);
// assert that locations of exception and top frame are equal
assertTrue("Different exception and top frame location tag,",
throwLocation.equals(topFrameLoc));
// check throw location's method
long debuggeeClassID = getClassIDBySignature(getDebuggeeClassSignature());
long debuggeeThrowMethodID = getMethodID(debuggeeClassID, THROW_EXCEPTION_METHOD);
if (debuggeeClassID != throwLocation.classID ||
debuggeeThrowMethodID != throwLocation.methodID) {
StringBuilder builder = new StringBuilder("Invalid method for throw location:");
builder.append(" expected ");
builder.append(getDebuggeeClassSignature());
builder.append('.');
builder.append(THROW_EXCEPTION_METHOD);
builder.append(" but got ");
builder.append(dumpLocation(throwLocation));
fail(builder.toString());
}
// resume debuggee
printTestLog("resume debuggee...");
debuggeeWrapper.vmMirror.resume();
}
/**
* This testcase is for uncaught EXCEPTION event and reported catch location.
* <BR>It runs ExceptionUncaughtDebuggee that throws an uncaught DebuggeeException.
* It verifies the following:
* <ul>
* <li>the requested EXCEPTION event occurs</li>
* <li>the reported thread is not null</li>
* <li>the reported catch location is null</li>
* </ul>
*/
public void testExceptionUncaughtEvent_CatchLocation() {
printTestLog("STARTED...");
ParsedEvent.Event_EXCEPTION exceptionEvent = requestAndReceiveExceptionEvent();
long returnedThread = exceptionEvent.getThreadID();
// assert that exception thread is not null
printTestLog("returnedThread = " + returnedThread);
assertTrue("Returned exception ThreadID is null,", returnedThread != 0);
// assert that exception catch location is not null
Location catchLocation = exceptionEvent.getCatchLocation();
printTestLog("returnedExceptionLoc = " + catchLocation);
assertNotNull("Returned exception catch location is null,", catchLocation);
// check catch location's method
if (!isNullLocation(catchLocation)) {
fail("Invalid catch location: expected null but got " + dumpLocation(catchLocation));
}
// resume debuggee
printTestLog("resume debuggee...");
debuggeeWrapper.vmMirror.resume();
}
/**
* Indicates whether the location is "null" or "0". Note: we don't test the type tag as it
* can only be CLASS.
*
* @param location the location to test
* @return true if the location is "null", false otherwise
*/
private static boolean isNullLocation(Location location) {
return location.classID == 0 && location.methodID == 0
&& location.index == 0;
}
/**
* Requests and receives EXCEPTION event then checks the received event kind,
* the received event request ID and the thread state.
* @return the exception event
*/
private ParsedEvent.Event_EXCEPTION requestAndReceiveExceptionEvent() {
synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
boolean isCatch = true;
boolean isUncatch = true;
printTestLog("=> setException(...)...");
ReplyPacket replyPacket = debuggeeWrapper.vmMirror.setException(EXCEPTION_SIGNATURE,
isCatch, isUncatch);
int requestID = replyPacket.getNextValueAsInt();
assertAllDataRead(replyPacket);
printTestLog("setException(...) DONE");
printTestLog("send to Debuggee SGNL_CONTINUE...");
synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
return receiveAndCheckExceptionEvent(requestID);
}
}