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/**
20 * @author Anatoly F. Bondarenko
21 */
22
23/**
24 * Created on 06.10.2006
25 */
26package org.apache.harmony.jpda.tests.jdwp.Events;
27
28import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
29import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
30import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase;
31import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
32import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
33import org.apache.harmony.jpda.tests.framework.jdwp.Location;
34import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent;
35
36/**
37 * CombinedEventsTestCase class provides auxiliary methods
38 * for JDWP unit tests for Co-located events.
39 */
40public abstract class CombinedEventsTestCase extends JDWPSyncTestCase {
41
42    static Object waitTimeObject = new Object();
43    static protected void waitMlsecsTime(long mlsecsTime) {
44        synchronized(waitTimeObject) {
45            try {
46                waitTimeObject.wait(mlsecsTime);
47            } catch (Throwable throwable) {
48                 // ignore
49            }
50        }
51    }
52
53    void printMethodLineTable(long classID, String className /* may be null */, String methodName) {
54        long methodID = debuggeeWrapper.vmMirror.getMethodID(classID, methodName);
55        if ( methodID == -1 ) {
56            logWriter.println
57            ("## printMethodLineTable(): Can NOT get methodID for classID = "
58                    + classID + "; Method name = " + methodName);
59            return;
60        }
61
62        CommandPacket packet = new CommandPacket(
63                JDWPCommands.MethodCommandSet.CommandSetID,
64                JDWPCommands.MethodCommandSet.LineTableCommand);
65        packet.setNextValueAsClassID(classID);
66        packet.setNextValueAsMethodID(methodID);
67        ReplyPacket lineTableReply = debuggeeWrapper.vmMirror.performCommand(packet);
68        if ( ! checkReplyPacketWithoutFail(lineTableReply,  "printMethodLineTable(): Method.LineTable command") ) {
69            return;
70        }
71        if ( className == null ) {
72            logWriter.println("=== Line Table for method: " + methodName + " ===");
73        } else {
74            logWriter.println("=== Line Table for method: " + methodName + " of class: "
75                    + className + " ===");
76        }
77        long methodStartCodeIndex = lineTableReply.getNextValueAsLong();
78        logWriter.println("==> Method Start Code Index = " + methodStartCodeIndex);
79        long methodEndCodeIndex = lineTableReply.getNextValueAsLong();
80        logWriter.println("==> Method End Code Index = " + methodEndCodeIndex);
81
82        int linesNumber = lineTableReply.getNextValueAsInt();
83        logWriter.println("==> Number of lines = " + linesNumber);
84        for (int i=0; i < linesNumber; i++) {
85            long lineCodeIndex = lineTableReply.getNextValueAsLong();
86            int lineNumber = lineTableReply.getNextValueAsInt();
87            logWriter.println("====> Line Number " + lineNumber + " : Initial code index = " + lineCodeIndex);
88        }
89        logWriter.println("=== End of Line Table " + methodName + " ===");
90    }
91
92    long getMethodStartCodeIndex(long classID, String methodName) {
93        long methodID = debuggeeWrapper.vmMirror.getMethodID(classID, methodName);
94        if ( methodID == -1 ) {
95            logWriter.println
96            ("## getMethodStartCodeIndex(): Can NOT get methodID for classID = "
97                    + classID + "; Method name = " + methodName);
98            return -1;
99        }
100
101        CommandPacket packet = new CommandPacket(
102                JDWPCommands.MethodCommandSet.CommandSetID,
103                JDWPCommands.MethodCommandSet.LineTableCommand);
104        packet.setNextValueAsClassID(classID);
105        packet.setNextValueAsMethodID(methodID);
106        ReplyPacket lineTableReply = debuggeeWrapper.vmMirror.performCommand(packet);
107        if ( ! checkReplyPacketWithoutFail
108                (lineTableReply,  "getMethodStartCodeIndex(): Method.LineTable command") ) {
109            return -1;
110        }
111        long methodStartCodeIndex = lineTableReply.getNextValueAsLong();
112        return methodStartCodeIndex;
113    }
114
115    @SuppressWarnings("unused")
116    long getMethodEndCodeIndex(long classID, String methodName) {
117        long methodID = debuggeeWrapper.vmMirror.getMethodID(classID, methodName);
118        if ( methodID == -1 ) {
119            logWriter.println
120            ("## getMethodEndCodeIndex(): Can NOT get methodID for classID = "
121                    + classID + "; Method name = " + methodName);
122            return -1;
123        }
124
125        CommandPacket packet = new CommandPacket(
126                JDWPCommands.MethodCommandSet.CommandSetID,
127                JDWPCommands.MethodCommandSet.LineTableCommand);
128        packet.setNextValueAsClassID(classID);
129        packet.setNextValueAsMethodID(methodID);
130        ReplyPacket lineTableReply = debuggeeWrapper.vmMirror.performCommand(packet);
131        if ( ! checkReplyPacketWithoutFail
132                (lineTableReply,  "getMethodEndCodeIndex(): Method.LineTable command") ) {
133            return -1;
134        }
135        long methodStartCodeIndex = lineTableReply.getNextValueAsLong();
136        long methodEndCodeIndex = lineTableReply.getNextValueAsLong();
137        return methodEndCodeIndex;
138    }
139
140    protected Location getMethodEntryLocation(long classID, String methodName) {
141        long methodID = debuggeeWrapper.vmMirror.getMethodID(classID, methodName);
142        if ( methodID == -1 ) {
143            logWriter.println
144            ("## getClassMethodEntryLocation(): Can NOT get methodID for classID = "
145                    + classID + "; Method name = " + methodName);
146            return null;
147        }
148
149        CommandPacket packet = new CommandPacket(
150                JDWPCommands.MethodCommandSet.CommandSetID,
151                JDWPCommands.MethodCommandSet.LineTableCommand);
152        packet.setNextValueAsClassID(classID);
153        packet.setNextValueAsMethodID(methodID);
154        ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
155        if ( ! checkReplyPacketWithoutFail
156                (reply,  "getMethodEntryLocation(): Method.LineTable command") ) {
157            return null;
158        }
159        long methodStartCodeIndex = reply.getNextValueAsLong();
160        Location location = new Location();
161        location.tag = JDWPConstants.TypeTag.CLASS;
162        location.classID =  classID;
163        location.methodID = methodID;
164        location.index = methodStartCodeIndex;
165        return location;
166    }
167
168    @SuppressWarnings("unused")
169    protected Location getMethodEndLocation(long classID, String methodName) {
170        long methodID = debuggeeWrapper.vmMirror.getMethodID(classID, methodName);
171        if ( methodID == -1 ) {
172            logWriter.println
173            ("## getClassMethodEndLocation(): Can NOT get methodID for classID = "
174                    + classID + "; Method name = " + methodName);
175            return null;
176        }
177
178        CommandPacket packet = new CommandPacket(
179                JDWPCommands.MethodCommandSet.CommandSetID,
180                JDWPCommands.MethodCommandSet.LineTableCommand);
181        packet.setNextValueAsClassID(classID);
182        packet.setNextValueAsMethodID(methodID);
183        ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
184        if ( ! checkReplyPacketWithoutFail
185                (reply,  "getMethodEndLocation(): Method.LineTable command") ) {
186            return null;
187        }
188        long methodStartCodeIndex = reply.getNextValueAsLong();
189        long methodEndCodeIndex = reply.getNextValueAsLong();
190        Location location = new Location();
191        location.tag = JDWPConstants.TypeTag.CLASS;
192        location.classID =  classID;
193        location.methodID = methodID;
194        location.index = methodEndCodeIndex;
195        return location;
196    }
197
198    protected boolean checkEventsLocation(ParsedEvent[] parsedEvents, Location expectedLocation) {
199        boolean success = true;
200        for (int i = 0; i < parsedEvents.length; i++) {
201            byte eventKind = parsedEvents[i].getEventKind();
202            long eventThreadID = 0;
203            Location eventLocation = null;
204            switch ( eventKind ) {
205            case JDWPConstants.EventKind.METHOD_ENTRY:
206                eventLocation = ((ParsedEvent.Event_METHOD_ENTRY)parsedEvents[i]).getLocation();
207                eventThreadID = ((ParsedEvent.EventThread)parsedEvents[i]).getThreadID();
208                break;
209            case JDWPConstants.EventKind.SINGLE_STEP:
210                eventLocation = ((ParsedEvent.Event_SINGLE_STEP)parsedEvents[i]).getLocation();
211                eventThreadID = ((ParsedEvent.EventThread)parsedEvents[i]).getThreadID();
212                break;
213            case JDWPConstants.EventKind.BREAKPOINT:
214                eventLocation = ((ParsedEvent.Event_BREAKPOINT)parsedEvents[i]).getLocation();
215                eventThreadID = ((ParsedEvent.EventThread)parsedEvents[i]).getThreadID();
216                break;
217            case JDWPConstants.EventKind.METHOD_EXIT:
218                eventLocation = ((ParsedEvent.Event_METHOD_EXIT)parsedEvents[i]).getLocation();
219                eventThreadID = ((ParsedEvent.EventThread)parsedEvents[i]).getThreadID();
220                break;
221            default:
222                logWriter.println("");
223                logWriter.println("=> Chcek location for event "
224                    + ": Event kind = " + eventKind + "("
225                    + JDWPConstants.EventKind.getName(eventKind) +")");
226                logWriter.println("=> WARNING: This event is not suitable to check location!");
227                continue;
228            }
229            logWriter.println("");
230            logWriter.println("=> Chcek location for event "
231                + ": Event kind = " + eventKind + "("
232                + JDWPConstants.EventKind.getName(eventKind) +"); eventThreadID = "
233                + eventThreadID);
234            long eventClassID = eventLocation.classID;
235            logWriter.println("=> ClassID in event = " + eventClassID);
236            if ( expectedLocation != null ) {
237                if ( expectedLocation.classID != eventClassID ) {
238                    logWriter.println("## FAILURE: Unexpected ClassID in event!");
239                    logWriter.println("##          Expected ClassID  = " + expectedLocation.classID );
240                    success = false;
241                } else {
242                    logWriter.println("=> OK - it is expected ClassID");
243                }
244            }
245            long eventMethodID = eventLocation.methodID;
246            logWriter.println("=> MethodID in event = " + eventMethodID);
247            if ( expectedLocation != null ) {
248                if ( expectedLocation.methodID != eventMethodID ) {
249                    logWriter.println("## FAILURE: Unexpected MethodID in event!");
250                    logWriter.println("##          Expected MethodID = " + expectedLocation.methodID);
251                    success = false;
252                } else {
253                    logWriter.println("=> OK - it is expected MethodID");
254                }
255            }
256            long eventCodeIndex = eventLocation.index;
257            logWriter.println("=> CodeIndex in event = " + eventCodeIndex);
258            if ( expectedLocation != null ) {
259                if ( expectedLocation.index != eventCodeIndex ) {
260                    logWriter.println("## FAILURE: Unexpected CodeIndex in event!");
261                    logWriter.println("##          Expected CodeIndex = "
262                        + expectedLocation.index);
263                    success = false;
264                } else {
265                    logWriter.println("=> OK - it is expected CodeIndex)");
266                }
267            }
268        }
269        logWriter.println("");
270        if ( expectedLocation != null ) {
271            if ( ! success ) {
272                String failureMessage = "## FAILURE: Unexpected events' locations are found out!";
273                logWriter.println(failureMessage);
274            } else {
275                logWriter.println("=> OK - all checked events have expected location!");
276            }
277        }
278        return success;
279    }
280
281 }
282