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 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 /** 19 * @author Anatoly F. Bondarenko 20 */ 21 22 /** 23 * Created on 26.10.2006 24 */ 25 package org.apache.harmony.jpda.tests.jdwp.Events; 26 27 import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket; 28 import org.apache.harmony.jpda.tests.framework.jdwp.EventMod; 29 import org.apache.harmony.jpda.tests.framework.jdwp.EventPacket; 30 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands; 31 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants; 32 import org.apache.harmony.jpda.tests.framework.jdwp.Location; 33 import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent; 34 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket; 35 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; 36 37 /** 38 * JDWP Unit test for possible combined (co-located) events: 39 * METHOD_ENTRY, SINGLE_STEP, BREAKPOINT, METHOD_EXIT. 40 */ 41 public class CombinedEvents003Test extends CombinedEventsTestCase { 42 43 private String debuggeeSignature = 44 "Lorg/apache/harmony/jpda/tests/jdwp/Events/CombinedEvents003Debuggee;"; 45 46 private String methodForEvents = "emptyMethod"; 47 48 private String methodEntryClassNameRegexp = 49 "org.apache.harmony.jpda.tests.jdwp.Events.CombinedEvents003Debuggee"; 50 51 private boolean eventVmDeathReceived = false; 52 getDebuggeeClassName()53 protected String getDebuggeeClassName() { 54 return CombinedEvents003Debuggee.class.getName(); 55 } 56 57 /** 58 * This test case checks events: 59 * METHOD_ENTRY, SINGLE_STEP, BREAKPOINT, METHOD_EXIT 60 * for empty method. 61 */ 62 testCombinedEvents003_01()63 public void testCombinedEvents003_01() { 64 logWriter.println("==> testCombinedEvents003_01 started"); 65 66 byte[] EXPECTED_EVENTS_ARRAY = { JDWPConstants.EventKind.METHOD_ENTRY, 67 JDWPConstants.EventKind.BREAKPOINT, 68 JDWPConstants.EventKind.SINGLE_STEP, 69 JDWPConstants.EventKind.METHOD_EXIT}; 70 71 String debuggeeMainThreadName = synchronizer.receiveMessage(); 72 73 long debuggeeClassID = debuggeeWrapper.vmMirror 74 .getClassID(debuggeeSignature); 75 logWriter.println("=> debuggeeClassID = " + debuggeeClassID); 76 77 long threadID = debuggeeWrapper.vmMirror.getThreadID(debuggeeMainThreadName); 78 logWriter.println("=> threadID = " + threadID); 79 80 long runMethodID = debuggeeWrapper.vmMirror.getMethodID(debuggeeClassID, "run"); 81 logWriter.println("=> runMethodID = " + runMethodID); 82 83 long dummyMethodID = debuggeeWrapper.vmMirror.getMethodID(debuggeeClassID, "dummyMethod"); 84 logWriter.println("=> dummyMethodID = " + dummyMethodID); 85 86 logWriter.println(""); 87 logWriter.println("=> Info for tested method '" + methodForEvents + "':"); 88 long testedMethodID = debuggeeWrapper.vmMirror.getMethodID(debuggeeClassID, methodForEvents); 89 if (testedMethodID == -1 ) { 90 String failureMessage = "## FAILURE: Can NOT get MethodID for class '" 91 + getDebuggeeClassName() + "'; Method name = " + methodForEvents; 92 printErrorAndFail(failureMessage); 93 } 94 logWriter.println("=> testedMethodID = " + testedMethodID); 95 printMethodLineTable(debuggeeClassID, null, methodForEvents); 96 97 // set requests for events that will be checked 98 logWriter.println(""); 99 logWriter.println("=> Set request for BREAKPOINT event in debuggee: " 100 + getDebuggeeClassName() + ", beginning of method: " 101 + methodForEvents); 102 Location combinedEventsLocation = getMethodEntryLocation(debuggeeClassID, methodForEvents); 103 if ( combinedEventsLocation == null ) { 104 String failureMessage = "## FAILURE: Can NOT get MethodEntryLocation for method '" 105 + methodForEvents + "'"; 106 printErrorAndFail(failureMessage); 107 } 108 ReplyPacket reply = debuggeeWrapper.vmMirror.setBreakpoint(combinedEventsLocation); 109 int breakpointRequestID = reply.getNextValueAsInt(); 110 logWriter.println("=> Breakpoint requestID = " + breakpointRequestID); 111 112 logWriter.println("=> Set request for METHOD_ENTRY event in debuggee: " 113 + getDebuggeeClassName()); 114 reply = debuggeeWrapper.vmMirror 115 .setMethodEntry(methodEntryClassNameRegexp); 116 checkReplyPacket(reply, "Set METHOD_ENTRY event"); 117 int methodEntryRequestID = reply.getNextValueAsInt(); 118 logWriter.println("=> METHOD_ENTRY requestID = " + methodEntryRequestID); 119 logWriter.println("=> Set request for METHOD_EXIT event in debuggee: " 120 + getDebuggeeClassName()); 121 reply = debuggeeWrapper.vmMirror 122 .setMethodExit(methodEntryClassNameRegexp); 123 checkReplyPacket(reply, "Set METHOD_EXIT event"); 124 int methodExitRequestID = reply.getNextValueAsInt(); 125 logWriter.println("=> METHOD_EXIT requestID = " + methodExitRequestID); 126 127 logWriter.println("=> Set request for SINGLE_STEP event in class " 128 + debuggeeSignature); 129 CommandPacket setRequestCommand = new CommandPacket( 130 JDWPCommands.EventRequestCommandSet.CommandSetID, 131 JDWPCommands.EventRequestCommandSet.SetCommand); 132 setRequestCommand 133 .setNextValueAsByte(JDWPConstants.EventKind.SINGLE_STEP); 134 setRequestCommand.setNextValueAsByte(JDWPConstants.SuspendPolicy.ALL); 135 setRequestCommand.setNextValueAsInt(2); 136 setRequestCommand.setNextValueAsByte(EventMod.ModKind.Step); 137 setRequestCommand.setNextValueAsThreadID(threadID); 138 setRequestCommand.setNextValueAsInt(JDWPConstants.StepSize.MIN); 139 setRequestCommand.setNextValueAsInt(JDWPConstants.StepDepth.INTO); 140 setRequestCommand.setNextValueAsByte(EventMod.ModKind.ClassOnly); 141 setRequestCommand.setNextValueAsReferenceTypeID(debuggeeClassID); 142 143 ReplyPacket setRequestReply = debuggeeWrapper.vmMirror 144 .performCommand(setRequestCommand); 145 checkReplyPacket(setRequestReply, "EventRequest::Set command"); 146 int stepRequestID = setRequestReply.getNextValueAsInt(); 147 logWriter.println("=> SINGLE_STEP requestID = " + stepRequestID); 148 149 logWriter.println(""); 150 logWriter.println("=> Send SGNL_CONTINUE signal to debuggee..."); 151 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 152 153 logWriter.println("=> Try to receive and check combined events: " 154 + " METHOD_ENTRY, SINGLE_STEP, BREAKPOINT, METHOD_EXIT events; ignore single SINGLE_STEP event"); 155 receiveAndCheckEvents(EXPECTED_EVENTS_ARRAY, combinedEventsLocation); 156 if ( eventVmDeathReceived ) { 157 logWriter.println("==> testCombinedEvents001 is FINISHing as VM_DEATH is received!"); 158 return; 159 } 160 161 logWriter.println(""); 162 logWriter.println("=> Clean request for METHOD_ENTRY event..."); 163 ReplyPacket clearReply = debuggeeWrapper.vmMirror.clearEvent( 164 JDWPConstants.EventKind.METHOD_ENTRY, methodEntryRequestID); 165 checkReplyPacket(clearReply, "EventRequest::Clear"); 166 167 logWriter.println(""); 168 logWriter.println("=> Clean request for SINGLE_STEP event..."); 169 clearReply = debuggeeWrapper.vmMirror.clearEvent( 170 JDWPConstants.EventKind.SINGLE_STEP, stepRequestID); 171 checkReplyPacket(clearReply, "EventRequest::Clear"); 172 173 logWriter.println("=> Resume debuggee"); 174 debuggeeWrapper.vmMirror.resume(); 175 176 // check that no other events, except VM_DEATH, will be received 177 checkVMDeathEvent(); 178 179 logWriter.println(""); 180 logWriter.println("==> testCombinedEvents003_01 PASSED"); 181 } 182 receiveAndCheckEvents(byte[] EXPECTED_EVENTS_ARRAY, Location expectedLocation)183 void receiveAndCheckEvents(byte[] EXPECTED_EVENTS_ARRAY, Location expectedLocation) { 184 int EXPECTED_EVENTS_COUNT = EXPECTED_EVENTS_ARRAY.length; 185 for (;;) { 186 logWriter.println("=>"); 187 logWriter.println("=> Receiving events..."); 188 EventPacket event = debuggeeWrapper.vmMirror.receiveEvent(); 189 ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(event); 190 191 // print all received events 192 logWriter.println("=> Received event packet with events number = " + parsedEvents.length + " :"); 193 194 for (int i = 0; i < parsedEvents.length; i++) { 195 logWriter.println(""); 196 logWriter.println("=> Event #" + (i+1) + " in packet -"); 197 logWriter.println("=> EventKind: " 198 + parsedEvents[i].getEventKind() 199 + "[" 200 + JDWPConstants.EventKind.getName(parsedEvents[i] 201 .getEventKind()) + "]"); 202 logWriter.println("=> RequestID: " 203 + parsedEvents[i].getRequestID()); 204 if ( parsedEvents[i].getEventKind() == JDWPConstants.EventKind.VM_DEATH ) { 205 eventVmDeathReceived = true; 206 } 207 } 208 if ( eventVmDeathReceived ) { 209 return; 210 } 211 checkEventsLocation(parsedEvents, null); // DBG__ 212 213 // the following code checks received events 214 if (parsedEvents.length == 1) { 215 debuggeeWrapper.vmMirror.resume(); 216 continue; 217 /* DBG__ 218 if (parsedEvents[0].getEventKind() == JDWPConstants.EventKind.SINGLE_STEP) { 219 logWriter.println(""); 220 logWriter.println("=> Resume debuggee"); 221 logWriter.println(""); 222 debuggeeWrapper.vmMirror.resume(); 223 continue; 224 } else { 225 logWriter.println("##FAILURE: received unexpected event: " 226 + parsedEvents[0].getEventKind() 227 + "[" 228 + JDWPConstants.EventKind.getName(parsedEvents[0] 229 .getEventKind()) 230 + "] instead of SINGLE_STEP"); 231 fail("received event is not SINGLE_STEP event: " 232 + parsedEvents[0].getEventKind() 233 + "[" 234 + JDWPConstants.EventKind.getName(parsedEvents[0] 235 .getEventKind()) + "]"); 236 } 237 // DBG__ */ 238 //DBG__} else if (parsedEvents.length == EXPECTED_EVENTS_COUNT) { 239 } else if (parsedEvents.length > 1) { 240 logWriter.println(""); 241 logWriter 242 .println("=> Combined events are received. Check events.."); 243 boolean success = true; 244 for (int i = 0; i < parsedEvents.length; i++) { 245 boolean isFound = false; 246 for (int j = 0; j < EXPECTED_EVENTS_COUNT; j++) { 247 if (parsedEvents[i].getEventKind() == EXPECTED_EVENTS_ARRAY[j]) { 248 EXPECTED_EVENTS_ARRAY[j] = 0; 249 isFound = true; 250 break; 251 } 252 } 253 if (!isFound) { 254 logWriter.println("##FAILURE: received unexpected event: " 255 + parsedEvents[i].getEventKind() 256 + "[" 257 + JDWPConstants.EventKind 258 .getName(parsedEvents[0] 259 .getEventKind()) + "]"); 260 success = false; 261 } 262 } 263 if (!success) { 264 logWriter.println(""); 265 logWriter.println("##FAILURE: the following expected events were not received: "); 266 for (int k = 0; k < EXPECTED_EVENTS_COUNT; k++) { 267 if (EXPECTED_EVENTS_ARRAY[k] != 0) 268 logWriter.println(" #" 269 + k 270 + ": " 271 + EXPECTED_EVENTS_ARRAY[k] 272 + "[" 273 + JDWPConstants.EventKind 274 .getName(EXPECTED_EVENTS_ARRAY[k]) 275 + "]"); 276 } 277 fail("not all expected events were received"); 278 } 279 for (int i = 0; i < parsedEvents.length; i++) { 280 byte eventKind = parsedEvents[i].getEventKind(); 281 long eventThreadID = ((ParsedEvent.EventThread)parsedEvents[i]).getThreadID(); 282 logWriter.println(""); 283 logWriter.println("=> Chcek location for combined event N " + (i+1) 284 + ": Event kind = " + eventKind + "(" 285 + JDWPConstants.EventKind.getName(eventKind) +"); eventThreadID = " 286 + eventThreadID); 287 Location eventLocation = null; 288 switch ( eventKind ) { 289 case JDWPConstants.EventKind.METHOD_ENTRY: 290 eventLocation = ((ParsedEvent.Event_METHOD_ENTRY)parsedEvents[i]).getLocation(); 291 break; 292 case JDWPConstants.EventKind.SINGLE_STEP: 293 eventLocation = ((ParsedEvent.Event_SINGLE_STEP)parsedEvents[i]).getLocation(); 294 break; 295 case JDWPConstants.EventKind.BREAKPOINT: 296 eventLocation = ((ParsedEvent.Event_BREAKPOINT)parsedEvents[i]).getLocation(); 297 break; 298 case JDWPConstants.EventKind.METHOD_EXIT: 299 eventLocation = ((ParsedEvent.Event_METHOD_EXIT)parsedEvents[i]).getLocation(); 300 break; 301 } 302 long eventClassID = eventLocation.classID; 303 logWriter.println("=> ClassID in event = " + eventClassID); 304 if ( expectedLocation.classID != eventClassID ) { 305 logWriter.println("## FAILURE: Unexpected ClassID in event!"); 306 logWriter.println("## Expected ClassID = " + expectedLocation.classID ); 307 success = false; 308 } else { 309 logWriter.println("=> OK - it is expected ClassID"); 310 } 311 long eventMethodID = eventLocation.methodID; 312 logWriter.println("=> MethodID in event = " + eventMethodID); 313 if ( expectedLocation.methodID != eventMethodID ) { 314 logWriter.println("## FAILURE: Unexpected MethodID in event!"); 315 logWriter.println("## Expected MethodID = " + expectedLocation.methodID); 316 success = false; 317 } else { 318 logWriter.println("=> OK - it is expected MethodID"); 319 } 320 long eventCodeIndex = eventLocation.index; 321 logWriter.println("=> CodeIndex in event = " + eventCodeIndex); 322 if ( expectedLocation.index != eventCodeIndex ) { 323 logWriter.println("## FAILURE: Unexpected CodeIndex in event!"); 324 logWriter.println("## Expected CodeIndex = " 325 + expectedLocation.index); 326 success = false; 327 } else { 328 logWriter.println("=> OK - it is expected CodeIndex)"); 329 } 330 } 331 logWriter.println(""); 332 if ( ! success ) { 333 String failureMessage = "## FAILURE: Unexpected events' locations are found out!"; 334 logWriter.println(failureMessage); 335 //DBG__printErrorAndFail(failureMessage); 336 } else { 337 logWriter.println("=> OK - all combined events have expected location!"); 338 } 339 break; 340 } else { 341 logWriter.println("##FAILURE: received unexpected number of events: " 342 + parsedEvents.length 343 + " instead of 1 or " 344 + EXPECTED_EVENTS_COUNT); 345 fail("received unexpected number of events: " 346 + parsedEvents.length); 347 } 348 } 349 } 350 checkVMDeathEvent()351 void checkVMDeathEvent() { 352 if ( eventVmDeathReceived ) { 353 return; 354 } 355 logWriter.println("=> Wait for VM_DEATH event..."); 356 while ( true ) { //DBG_ 357 logWriter.println("=> Receiving events..."); 358 EventPacket event = debuggeeWrapper.vmMirror.receiveEvent(); 359 ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(event); 360 if (parsedEvents.length != 1 361 || parsedEvents[0].getEventKind() != JDWPConstants.EventKind.VM_DEATH) { 362 // print all received events 363 logWriter.println("##FAILURE: Received unexpected events"); 364 logWriter.println("=> Events received: " + parsedEvents.length); 365 for (int i = 0; i < parsedEvents.length; i++) { 366 logWriter.println(""); 367 logWriter.println("=> Event #" + i + ";"); 368 logWriter.println("=> EventKind: " 369 + parsedEvents[i].getEventKind() 370 + "[" 371 + JDWPConstants.EventKind.getName(parsedEvents[i] 372 .getEventKind()) + "]"); 373 logWriter.println("=> RequestID: " 374 + parsedEvents[i].getRequestID()); 375 } 376 checkEventsLocation(parsedEvents, null); // DBG__ 377 logWriter.println("=> Resume debuggee"); //DBG__ 378 debuggeeWrapper.vmMirror.resume(); //DBG__ 379 continue; //DBG__ 380 //DBG__fail("unexpected events received"); 381 } 382 logWriter.println("=> OK - VM_DEATH event was received. "); 383 break; //DBG__ 384 } // DBG__ 385 } 386 } 387