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.CommandPacket;
22 import org.apache.harmony.jpda.tests.framework.jdwp.EventMod;
23 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
24 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
25 import org.apache.harmony.jpda.tests.framework.jdwp.Location;
26 import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent;
27 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
28 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
29 
30 /**
31  * JDWP Unit test for SINGLE_STEP event with LocationOnly modifier.
32  */
33 public class SingleStepWithLocationTest extends JDWPEventTestCase {
34 
35     private String debuggeeSignature = "Lorg/apache/harmony/jpda/tests/jdwp/Events/SingleStepDebuggee;";
36 
37     private static final String BREAKPOINT_METHOD_NAME = "breakpointTest";
38 
getDebuggeeClassName()39     protected String getDebuggeeClassName() {
40         return SingleStepDebuggee.class.getName();
41     }
42 
43     /**
44      * This test case exercises SINGLE_STEP event.<BR>
45      *
46      * Runs SingleStepDebuggee and sets breakpoint to its
47      * breakpointTest method, sends a request for single step event with the
48      * location of the last line so we single-step until there. Then verifies
49      * that requested SINGLE_STEP event occurs.
50      */
testSingleStepToLocation()51     public void testSingleStepToLocation() {
52         logWriter.println("=> testSingleStepToLocation started");
53 
54         synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
55 
56         // Set breakpoint.
57         long refTypeID = getClassIDBySignature(debuggeeSignature);
58 
59         logWriter.println("=> Debuggee class = " + getDebuggeeClassName());
60         logWriter.println("=> referenceTypeID for Debuggee class = " + refTypeID);
61         logWriter.println("=> Send ReferenceType::Methods command and get methodIDs ");
62 
63         int requestID = debuggeeWrapper.vmMirror.setBreakpointAtMethodBegin(
64                 refTypeID, BREAKPOINT_METHOD_NAME);
65         logWriter.println("=> breakpointID = " + requestID);
66         logWriter.println("=> starting thread");
67 
68         // Execute the breakpoint
69         synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
70 
71         // Wait for breakpoint event so the program is suspended.
72         long breakpointThreadID = debuggeeWrapper.vmMirror
73                 .waitForBreakpoint(requestID);
74 
75         logWriter.println("=> breakpointThreadID = " + breakpointThreadID);
76 
77         // Remove breakpoint.
78         debuggeeWrapper.vmMirror.clearBreakpoint((int)requestID);
79 
80         // Get line table and get code index of the last line.
81         long methodID = getMethodID(refTypeID, BREAKPOINT_METHOD_NAME);
82         ReplyPacket lineTableReply = getLineTable(refTypeID, methodID);
83         checkReplyPacket(lineTableReply, "Method.LineTable");
84         lineTableReply.getNextValueAsLong();  // startIndex
85         lineTableReply.getNextValueAsLong();  // endIndex
86         int linesCount = lineTableReply.getNextValueAsInt();
87         long lastLineCodeIndex = -1;
88         int lastLineNumber = -1;
89         for (int i = 0; i < linesCount; ++i) {
90             lastLineCodeIndex = lineTableReply.getNextValueAsLong();
91             lastLineNumber = lineTableReply.getNextValueAsInt();
92         }
93 
94         logWriter.println("Single-step until line " + lastLineNumber);
95 
96         // Location of last line.
97         Location location = new Location(JDWPConstants.TypeTag.CLASS,
98                 refTypeID, methodID, lastLineCodeIndex);
99 
100         // Sending a SINGLE_STEP request
101         CommandPacket setRequestCommand = new CommandPacket(
102                 JDWPCommands.EventRequestCommandSet.CommandSetID,
103                 JDWPCommands.EventRequestCommandSet.SetCommand);
104         setRequestCommand.setNextValueAsByte(
105                 JDWPConstants.EventKind.SINGLE_STEP);
106         setRequestCommand.setNextValueAsByte(JDWPConstants.SuspendPolicy.ALL);
107         setRequestCommand.setNextValueAsInt(2);
108         setRequestCommand.setNextValueAsByte(EventMod.ModKind.Step);
109         setRequestCommand.setNextValueAsThreadID(breakpointThreadID);
110         setRequestCommand.setNextValueAsInt(JDWPConstants.StepSize.LINE);
111         setRequestCommand.setNextValueAsInt(JDWPConstants.StepDepth.OVER);
112         setRequestCommand.setNextValueAsByte(EventMod.ModKind.LocationOnly);
113         setRequestCommand.setNextValueAsLocation(location);
114 
115         ReplyPacket setRequestReply = debuggeeWrapper.vmMirror
116                 .performCommand(setRequestCommand);
117         checkReplyPacket(setRequestReply, "Set SINGLE_STEP event");
118         requestID = setRequestReply.getNextValueAsInt();
119 
120         logWriter.println("=> RequestID = " + requestID);
121         assertAllDataRead(setRequestReply);
122 
123         // Resume debuggee so we can suspend on single-step.
124         resumeDebuggee();
125 
126         // Wait for event.
127         logWriter.println("==> Wait for SINGLE_STEP event");
128         CommandPacket event = debuggeeWrapper.vmMirror.receiveEvent();
129         ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(event);
130 
131         // Check if received event is expected.
132         logWriter.println("==> Received " + parsedEvents.length + " events");
133 
134         // Trace events
135         for (int i = 0; i < parsedEvents.length; i++) {
136             logWriter.println("");
137             logWriter.println("==> Event #" + i + ";");
138             logWriter.println("==> EventKind: " + parsedEvents[i].getEventKind() + "("
139                     + JDWPConstants.EventKind.getName(parsedEvents[i].getEventKind()) + ")");
140             logWriter.println("==> RequestID: " + parsedEvents[i].getRequestID());
141         }
142 
143         // Check all
144         assertEquals("Received wrong number of events,", 1, parsedEvents.length);
145         assertEquals("Received wrong event request ID,", requestID, parsedEvents[0].getRequestID());
146         assertEquals("Invalid event kind,", JDWPConstants.EventKind.SINGLE_STEP,
147                 parsedEvents[0].getEventKind(),
148                 JDWPConstants.EventKind.getName(JDWPConstants.EventKind.SINGLE_STEP),
149                 JDWPConstants.EventKind.getName(parsedEvents[0].getEventKind()));
150 
151         // Clear SINGLE_STEP event
152         logWriter.println("==> Clearing SINGLE_STEP event..");
153         ReplyPacket clearRequestReply =
154             debuggeeWrapper.vmMirror.clearEvent(JDWPConstants.EventKind.SINGLE_STEP, (int) requestID);
155         checkReplyPacket(clearRequestReply, "Clear SINGLE_STEP event");
156         logWriter.println("==> SINGLE_STEP event has been cleared");
157 
158         // Resuming debuggee before leaving.
159         resumeDebuggee();
160         logWriter.println("==> Test PASSED!");
161     }
162 }
163