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.EventPacket; 22 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants; 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.jdwp.Events.CombinedExceptionEventsDebuggee.SubDebuggeeException; 26 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; 27 28 import java.util.Arrays; 29 30 /** 31 * JDWP Unit test for combined EXCEPTION events. 32 */ 33 public class CombinedExceptionEventsTest extends CombinedEventsTestCase { 34 @Override getDebuggeeClassName()35 protected String getDebuggeeClassName() { 36 return CombinedExceptionEventsDebuggee.class.getName(); 37 } 38 39 /** 40 * Tests combined EXCEPTION events for caught exception. It runs the 41 * CombinedExceptionEventsDebuggee and verifies we only received 42 * EXCEPTION events for caught exception. 43 */ testCombinedExceptionEvents_CaughtExceptionOnly()44 public void testCombinedExceptionEvents_CaughtExceptionOnly() { 45 runCombinedExceptionEventsTest(false); 46 } 47 48 /** 49 * Tests combined EXCEPTION events for uncaught exception. It runs the 50 * CombinedExceptionEventsDebuggee and verifies we only received 51 * EXCEPTION events for uncaught exception. 52 */ testCombinedExceptionEvents_UncaughtExceptionOnly()53 public void testCombinedExceptionEvents_UncaughtExceptionOnly() { 54 runCombinedExceptionEventsTest(true); 55 } 56 57 /** 58 * Tests combined EXCEPTION events. It runs the CombinedExceptionEventsDebuggee 59 * and requests the following EXCEPTION events: 60 * <ol> 61 * <li>only caught DebuggeeException (and subclasses)</li> 62 * <li>only caught SubDebuggeeException (and subclasses)</li> 63 * <li>only uncaught DebuggeeException (and subclasses)</li> 64 * <li>only uncaught SubDebuggeeException (and subclasses)</li> 65 * <li>caught and uncaught DebuggeeException (and subclasses)</li> 66 * <li>caught and uncaught SubDebuggeeException (and subclasses)</li> 67 * </ol> 68 * 69 * Finally it verifies we received only the expected events. 70 * 71 * @param testUncaughtException 72 * true to test uncaught exception, false to test caught exception. 73 */ runCombinedExceptionEventsTest(boolean testUncaughtException)74 private void runCombinedExceptionEventsTest(boolean testUncaughtException) { 75 // Wait for debuggee. 76 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 77 78 String superExceptionClassSignature = getClassSignature( 79 DebuggeeException.class); 80 String subExceptionClassSignature = getClassSignature( 81 SubDebuggeeException.class); 82 83 long superExceptionClassID = debuggeeWrapper.vmMirror.getClassID( 84 superExceptionClassSignature); 85 long subExceptionClassID = debuggeeWrapper.vmMirror.getClassID( 86 subExceptionClassSignature); 87 88 // Request "caught only" exceptions with super and sub classes. 89 int request1 = requestException(superExceptionClassID, true, false); 90 int request2 = requestException(subExceptionClassID, true, false); 91 92 // Request "uncaught only" exceptions with super and sub classes. 93 int request3 = requestException(superExceptionClassID, false, true); 94 int request4 = requestException(subExceptionClassID, false, true); 95 96 // Request "caught & uncaught" exceptions with super and sub classes. 97 int request5 = requestException(superExceptionClassID, true, true); 98 int request6 = requestException(subExceptionClassID, true, true); 99 100 int[] expectedRequests = null; 101 String signalMessage = null; 102 if (testUncaughtException) { 103 // We expect requests 3, 4, 5 and 6. 104 expectedRequests = new int[] { request3, request4, request5, request6 }; 105 signalMessage = CombinedExceptionEventsDebuggee.TEST_UNCAUGHT_EXCEPTION_SIGNAL; 106 } else { 107 // We expect requests 1, 2, 5 and 6. 108 expectedRequests = new int[] { request1, request2, request5, request6 }; 109 signalMessage = CombinedExceptionEventsDebuggee.TEST_CAUGHT_EXCEPTION_SIGNAL; 110 } 111 112 // Signal debuggee. 113 synchronizer.sendMessage(signalMessage); 114 115 printTestLog("=> receiveEvent()..."); 116 EventPacket event = debuggeeWrapper.vmMirror.receiveEvent(); 117 ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(event); 118 printTestLog("Received " + parsedEvents.length + " + event(s)."); 119 120 int[] receivedRequests = new int[parsedEvents.length]; 121 long eventThreadID = -1; 122 long exceptionObjectID = -1; 123 for (int i = 0; i < parsedEvents.length; ++i) { 124 ParsedEvent parsedEvent = parsedEvents[i]; 125 byte eventKind = parsedEvent.getEventKind(); 126 int requestID = parsedEvent.getRequestID(); 127 printTestLog("Event #" + i + ": kind=" 128 + JDWPConstants.EventKind.getName(eventKind) 129 + ", requestID=" + requestID); 130 assertEquals("Invalid event kind,", 131 JDWPConstants.EventKind.EXCEPTION, eventKind, 132 JDWPConstants.EventKind.getName( 133 JDWPConstants.EventKind.EXCEPTION), 134 JDWPConstants.EventKind.getName(eventKind)); 135 136 ParsedEvent.Event_EXCEPTION exceptionEvent = (ParsedEvent.Event_EXCEPTION) parsedEvent; 137 138 long currentEventThreadID = exceptionEvent.getThreadID(); 139 long currentExceptionObjectID = exceptionEvent 140 .getException().objectID; 141 // Checks all events are for the same thread. 142 if (eventThreadID != -1) { 143 assertEquals("Invalid event thread ID", eventThreadID, 144 currentEventThreadID); 145 } else { 146 eventThreadID = currentEventThreadID; 147 } 148 // Checks all events are for the same exception. 149 if (exceptionObjectID != -1) { 150 assertEquals("Invalid exception object ID", exceptionObjectID, 151 currentExceptionObjectID); 152 } else { 153 exceptionObjectID = currentExceptionObjectID; 154 } 155 // Check thread is properly suspended. 156 checkThreadState(eventThreadID, JDWPConstants.ThreadStatus.RUNNING, 157 JDWPConstants.SuspendStatus.SUSPEND_STATUS_SUSPENDED); 158 159 receivedRequests[i] = requestID; 160 } 161 162 // Check we receive all expected events. 163 Arrays.sort(expectedRequests); 164 Arrays.sort(receivedRequests); 165 if (!Arrays.equals(expectedRequests, receivedRequests)) { 166 String expectedArrayString = Arrays.toString(expectedRequests); 167 String receivedArrayString = Arrays.toString(receivedRequests); 168 fail("Unexpected event: expected " + expectedArrayString 169 + " but got " + receivedArrayString); 170 } 171 } 172 requestException(long exceptionClassID, boolean caught, boolean uncaught)173 private int requestException(long exceptionClassID, boolean caught, 174 boolean uncaught) { 175 printTestLog("Request EXCEPTION event: class=" + exceptionClassID + ", caught=" 176 + caught + ", uncaught=" + uncaught); 177 ReplyPacket replyPacket = debuggeeWrapper.vmMirror.setException( 178 exceptionClassID, caught, uncaught); 179 int requestID = replyPacket.getNextValueAsInt(); 180 assertAllDataRead(replyPacket); 181 printTestLog("Created request " + requestID); 182 return requestID; 183 } 184 } 185