Home | History | Annotate | Download | only in Events
      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
     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      */
     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      */
     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      */
     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 
    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