1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package org.apache.harmony.jpda.tests.jdwp.Events; 20 21 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants; 22 import org.apache.harmony.jpda.tests.framework.jdwp.Location; 23 import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent; 24 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket; 25 import org.apache.harmony.jpda.tests.framework.jdwp.TaggedObject; 26 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; 27 28 /** 29 * JDWP Unit test for uncaught EXCEPTION event. 30 */ 31 public class ExceptionUncaughtTest extends ExceptionBaseTest { 32 private static final String EXCEPTION_SIGNATURE = getClassSignature(DebuggeeException.class); 33 34 private static final String THROW_EXCEPTION_METHOD = "throwDebuggeeException"; 35 getDebuggeeClassName()36 protected String getDebuggeeClassName() { 37 return ExceptionUncaughtDebuggee.class.getName(); 38 } 39 40 /** 41 * This testcase is for uncaught EXCEPTION event and reported exception object. 42 * <BR>It runs ExceptionUncaughtDebuggee that throws an uncaught DebuggeeException. 43 * It verifies the following: 44 * <ul> 45 * <li>the requested EXCEPTION event occurs</li> 46 * <li>the reported exception object is not null</li> 47 * <li>the reported exception object is instance of expected class with expected tag</li> 48 * </ul> 49 */ testExceptionUncaughtEvent_ExceptionObject()50 public void testExceptionUncaughtEvent_ExceptionObject() { 51 printTestLog("STARTED..."); 52 53 ParsedEvent.Event_EXCEPTION exceptionEvent = requestAndReceiveExceptionEvent(); 54 TaggedObject returnedException = exceptionEvent.getException(); 55 56 // assert that exception ObjectID is not null 57 printTestLog("returnedException.objectID = " + returnedException.objectID); 58 assertTrue("Returned exception object is null.", returnedException.objectID != 0); 59 60 // assert that exception tag is OBJECT 61 printTestLog("returnedException.tag = " + returnedException.objectID); 62 assertEquals("Returned exception tag is not OBJECT.", 63 JDWPConstants.Tag.OBJECT_TAG, returnedException.tag); 64 65 // assert that exception class is the expected one 66 long typeID = getObjectReferenceType(returnedException.objectID); 67 String returnedExceptionSignature = getClassSignature(typeID); 68 printTestLog("returnedExceptionSignature = |" + returnedExceptionSignature+"|"); 69 assertString("Invalid signature of returned exception,", 70 EXCEPTION_SIGNATURE, returnedExceptionSignature); 71 72 // resume debuggee 73 printTestLog("resume debuggee..."); 74 debuggeeWrapper.vmMirror.resume(); 75 } 76 77 /** 78 * This testcase is for uncaught EXCEPTION event and reported throw location. 79 * <BR>It runs ExceptionUncaughtDebuggee that throws an uncaught DebuggeeException. 80 * It verifies the following: 81 * <ul> 82 * <li>the requested EXCEPTION event occurs</li> 83 * <li>the reported thread is not null</li> 84 * <li>the reported throw location is not null</li> 85 * <li>the reported throw location is equal to location of the top stack frame</li> 86 * </ul> 87 */ testExceptionUncaughtEvent_ThrowLocation()88 public void testExceptionUncaughtEvent_ThrowLocation() { 89 printTestLog("STARTED..."); 90 91 ParsedEvent.Event_EXCEPTION exceptionEvent = requestAndReceiveExceptionEvent(); 92 long returnedThread = exceptionEvent.getThreadID(); 93 Location throwLocation = exceptionEvent.getLocation(); 94 95 // assert that exception thread is not null 96 printTestLog("returnedThread = " + returnedThread); 97 assertTrue("Returned exception ThreadID is null,", returnedThread != 0); 98 99 // assert that exception location is not null 100 printTestLog("returnedExceptionLoc = " + throwLocation); 101 assertNotNull("Returned exception location is null,", throwLocation); 102 103 // assert that top stack frame location is not null 104 Location topFrameLoc = getTopFrameLocation(returnedThread); 105 printTestLog("topFrameLoc = " + topFrameLoc); 106 assertNotNull("Returned top stack frame location is null,", topFrameLoc); 107 108 // assert that locations of exception and top frame are equal 109 assertTrue("Different exception and top frame location tag,", 110 throwLocation.equals(topFrameLoc)); 111 112 // check throw location's method 113 long debuggeeClassID = getClassIDBySignature(getDebuggeeClassSignature()); 114 long debuggeeThrowMethodID = getMethodID(debuggeeClassID, THROW_EXCEPTION_METHOD); 115 if (debuggeeClassID != throwLocation.classID || 116 debuggeeThrowMethodID != throwLocation.methodID) { 117 StringBuilder builder = new StringBuilder("Invalid method for throw location:"); 118 builder.append(" expected "); 119 builder.append(getDebuggeeClassSignature()); 120 builder.append('.'); 121 builder.append(THROW_EXCEPTION_METHOD); 122 builder.append(" but got "); 123 builder.append(dumpLocation(throwLocation)); 124 fail(builder.toString()); 125 } 126 127 // resume debuggee 128 printTestLog("resume debuggee..."); 129 debuggeeWrapper.vmMirror.resume(); 130 } 131 132 /** 133 * This testcase is for uncaught EXCEPTION event and reported catch location. 134 * <BR>It runs ExceptionUncaughtDebuggee that throws an uncaught DebuggeeException. 135 * It verifies the following: 136 * <ul> 137 * <li>the requested EXCEPTION event occurs</li> 138 * <li>the reported thread is not null</li> 139 * <li>the reported catch location is null</li> 140 * </ul> 141 */ testExceptionUncaughtEvent_CatchLocation()142 public void testExceptionUncaughtEvent_CatchLocation() { 143 printTestLog("STARTED..."); 144 145 ParsedEvent.Event_EXCEPTION exceptionEvent = requestAndReceiveExceptionEvent(); 146 long returnedThread = exceptionEvent.getThreadID(); 147 148 // assert that exception thread is not null 149 printTestLog("returnedThread = " + returnedThread); 150 assertTrue("Returned exception ThreadID is null,", returnedThread != 0); 151 152 // assert that exception catch location is not null 153 Location catchLocation = exceptionEvent.getCatchLocation(); 154 printTestLog("returnedExceptionLoc = " + catchLocation); 155 assertNotNull("Returned exception catch location is null,", catchLocation); 156 157 // check catch location's method 158 if (!isNullLocation(catchLocation)) { 159 fail("Invalid catch location: expected null but got " + dumpLocation(catchLocation)); 160 } 161 162 // resume debuggee 163 printTestLog("resume debuggee..."); 164 debuggeeWrapper.vmMirror.resume(); 165 } 166 167 /** 168 * Indicates whether the location is "null" or "0". Note: we don't test the type tag as it 169 * can only be CLASS. 170 * 171 * @param location the location to test 172 * @return true if the location is "null", false otherwise 173 */ isNullLocation(Location location)174 private static boolean isNullLocation(Location location) { 175 return location.classID == 0 && location.methodID == 0 176 && location.index == 0; 177 } 178 179 /** 180 * Requests and receives EXCEPTION event then checks the received event kind, 181 * the received event request ID and the thread state. 182 * @return the exception event 183 */ requestAndReceiveExceptionEvent()184 private ParsedEvent.Event_EXCEPTION requestAndReceiveExceptionEvent() { 185 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 186 187 boolean isCatch = true; 188 boolean isUncatch = true; 189 printTestLog("=> setException(...)..."); 190 ReplyPacket replyPacket = debuggeeWrapper.vmMirror.setException(EXCEPTION_SIGNATURE, 191 isCatch, isUncatch); 192 int requestID = replyPacket.getNextValueAsInt(); 193 assertAllDataRead(replyPacket); 194 195 printTestLog("setException(...) DONE"); 196 197 printTestLog("send to Debuggee SGNL_CONTINUE..."); 198 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 199 200 return receiveAndCheckExceptionEvent(requestID); 201 } 202 203 } 204