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.TestErrorException;
22 import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
23 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
24 import org.apache.harmony.jpda.tests.framework.jdwp.Location;
25 import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent;
26 import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent.EventThread;
27 import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent.Event_EXCEPTION;
28 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
29 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
30 
31 /**
32  * JDWP Unit test for BREAKPOINT event on "catch (...)" line.
33  */
34 public class BreakpointOnCatchTest extends JDWPEventTestCase {
35     @Override
getDebuggeeClassName()36     protected String getDebuggeeClassName() {
37         return BreakpointOnCatchDebuggee.class.getName();
38     }
39 
40     /**
41      * This testcase is for BREAKPOINT event.
42      * <BR>It runs BreakpointOnCatchDebuggee and set breakpoint to its breakpointOnCatch
43      * method, then verifies that the requested BREAKPOINT event occurs on a catch statement
44      * (with a pending exception).
45      */
testBreakpointOnCatch()46     public void testBreakpointOnCatch() {
47         logWriter.println("testBreakpointOnCatch started");
48 
49         // Wait for debuggee to start.
50         synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
51 
52         long classID = getClassIDBySignature(getDebuggeeClassSignature());
53         long methodID = getMethodID(classID, BreakpointOnCatchDebuggee.BREAKPOINT_METHOD_NAME);
54 
55         // First, we set an EXCEPTION caught event to know the location of the catch.
56         int exceptionRequestID = requestExceptionCaughtEvent();
57 
58         // Execute the EXCEPTION.
59         synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
60 
61         // Wait for EXCEPTION event.
62         CommandPacket event =
63             debuggeeWrapper.vmMirror.receiveCertainEvent(JDWPConstants.EventKind.EXCEPTION);
64         ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(event);
65         assertEquals("Invalid number of events:", 1, parsedEvents.length);
66         assertEquals("Invalid request ID:", exceptionRequestID, parsedEvents[0].getRequestID());
67 
68         // Extract catch location and check it is in the tested method.
69         Location catchLocation = ((Event_EXCEPTION) parsedEvents[0]).getCatchLocation();
70         assertEquals("Invalid class ID:", classID, catchLocation.classID);
71         assertEquals("Invalid method ID:", methodID, catchLocation.methodID);
72 
73         // Clear the EXCEPTION event.
74         debuggeeWrapper.vmMirror.clearEvent(JDWPConstants.EventKind.EXCEPTION, exceptionRequestID);
75 
76         // Now we can set the BREAKPOINT on the catch location.
77         int requestID = requestBreakpointEvent(catchLocation);
78 
79         // The debuggee is suspended on the EXCEPTION event: resume it to hit the BREAKPOINT event.
80         resumeDebuggee();
81 
82         // Wait for BREAKPOINT event.
83         event =
84             debuggeeWrapper.vmMirror.receiveCertainEvent(JDWPConstants.EventKind.BREAKPOINT);
85         parsedEvents = ParsedEvent.parseEventPacket(event);
86         assertEquals("Invalid number of events:", 1, parsedEvents.length);
87         assertEquals("Invalid request ID:", requestID, parsedEvents[0].getRequestID());
88 
89         // Check the thread is in an expected state.
90         long eventThreadID = ((EventThread) parsedEvents[0]).getThreadID();
91         checkThreadState(eventThreadID, JDWPConstants.ThreadStatus.RUNNING,
92                 JDWPConstants.SuspendStatus.SUSPEND_STATUS_SUSPENDED);
93 
94         logWriter.println("Successfully suspended on a catch statement");
95         logWriter.println("testBreakpointOnCatch done");
96     }
97 
requestExceptionCaughtEvent()98     private int requestExceptionCaughtEvent() {
99       String exceptionSig =
100           getClassSignature(BreakpointOnCatchDebuggee.BreakpointOnCatchDebuggeeException.class);
101       ReplyPacket replyPacket = debuggeeWrapper.vmMirror.setException(exceptionSig, true, false);
102       return replyPacket.getNextValueAsInt();
103 
104     }
105 
requestBreakpointEvent(Location location)106     private int requestBreakpointEvent(Location location) {
107       logWriter.println("Install breakpoint at " + location);
108       ReplyPacket replyPacket = debuggeeWrapper.vmMirror.setBreakpoint(location);
109       return replyPacket.getNextValueAsInt();
110 
111     }
112 }
113