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 Vitaly A. Provodin 21 */ 22 23 /** 24 * Created on 15.02.2005 25 */ 26 package org.apache.harmony.jpda.tests.jdwp.ThreadReference; 27 28 import java.util.Vector; 29 import java.util.Enumeration; 30 31 import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket; 32 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands; 33 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants; 34 import org.apache.harmony.jpda.tests.framework.jdwp.Location; 35 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket; 36 import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase; 37 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; 38 39 /** 40 * JDWP Unit test for ThreadReference.Frames command. 41 */ 42 public class FramesTest extends JDWPSyncTestCase { 43 44 short err; 45 long threadID; 46 47 class FrameStruct { 48 long frameID; 49 Location loc; FrameStruct(long frameID, Location loc)50 FrameStruct(long frameID, Location loc) { 51 this.frameID = frameID; 52 this.loc = loc; 53 } 54 } 55 getDebuggeeClassName()56 protected String getDebuggeeClassName() { 57 return "org.apache.harmony.jpda.tests.jdwp.ThreadReference.FramesDebuggee"; 58 } 59 60 /** 61 * This testcase exercises ThreadReference.Frames command. 62 * <BR>At first the test starts FramesDebuggee which recursively invokes 63 * the method 'FramesDebuggee.recursiveMethod' thereby the specified depth 64 * 'FramesDebuggee.DEPTH' of recursion is reached. 65 * <BR> Then the tests performs the ThreadReference.Frames command 66 * for the main thread with parameters: 67 * <BR>startFrame=0, length=(amount_of_all_frames + 1) 68 * <BR>It is expected the error INVALID_LENGTH is returned. 69 */ testFrames005()70 public void testFrames005() { 71 logWriter.println("==> testFrames005 START "); 72 String testedThreadName = synchronizer.receiveMessage(); 73 74 logWriter.println 75 ("==> testedThreadName = |" + testedThreadName +"|"); 76 threadID = debuggeeWrapper.vmMirror.getThreadID(testedThreadName); 77 logWriter.println("==> threadID = " + threadID); 78 debuggeeWrapper.vmMirror.suspendThread(threadID); 79 80 Vector allFrames = getFrames(0, -1); 81 if (err != JDWPConstants.Error.NONE) { 82 printErrorAndFail("Unexpected ERROR = " + err 83 + "(" + JDWPConstants.Error.getName(err) + ")"); 84 } 85 String methodName, classSignature; 86 int i = 0; 87 for (Enumeration e = allFrames.elements(); e.hasMoreElements(); i++) { 88 FrameStruct frame = (FrameStruct )e.nextElement(); 89 methodName = getMethodName(frame.loc.classID, frame.loc.methodID); 90 classSignature = getClassSignature(frame.loc.classID); 91 logWriter.println("\t" + i + ". frameID=" + frame.frameID 92 + " - " + classSignature 93 + methodName 94 + "(" + frame.loc.index + ")"); 95 } 96 97 allFrames = getFrames(0, allFrames.size() + 1); 98 if (err == JDWPConstants.Error.INVALID_LENGTH) { 99 logWriter.println("Caught expected error - " + JDWPConstants.Error.getName(err) 100 + "(" + err + ")"); 101 } else { 102 printErrorAndFail("unexpected behaviour: error is " 103 + JDWPConstants.Error.getName(err) + "(" + err + ")" 104 + " but must be " 105 + JDWPConstants.Error.getName(JDWPConstants.Error.INVALID_LENGTH) 106 + "(" + JDWPConstants.Error.INVALID_LENGTH + ")"); 107 } 108 logWriter.println("==> testFrames005 OK. "); 109 debuggeeWrapper.vmMirror.resumeThread(threadID); 110 111 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 112 } 113 114 /** 115 * This testcase exercises ThreadReference.Frames command. 116 * <BR>At first the test starts FramesDebuggee which recursively invokes 117 * the method 'FramesDebuggee.recursiveMethod' thereby the specified depth 118 * 'FramesDebuggee.DEPTH' of recursion is reached. 119 * <BR> Then the tests performs the ThreadReference.Frames command 120 * for the main thread with parameters: 121 * <BR>startFrame=(amount_of_all_frames + 1), length=-1 122 * <BR>It is expected the error INVALID_INDEX is returned. 123 */ testFrames004()124 public void testFrames004() { 125 logWriter.println("==> testFrames004 START "); 126 String testedThreadName = synchronizer.receiveMessage(); 127 128 logWriter.println 129 ("==> testedThreadName = |" + testedThreadName +"|"); 130 threadID = debuggeeWrapper.vmMirror.getThreadID(testedThreadName); 131 logWriter.println("==> threadID = " + threadID); 132 debuggeeWrapper.vmMirror.suspendThread(threadID); 133 134 Vector allFrames = getFrames(0, -1); 135 if (err != JDWPConstants.Error.NONE) { 136 printErrorAndFail("Unexpected ERROR = " + err 137 + "(" + JDWPConstants.Error.getName(err) + ")"); 138 } 139 String methodName, classSignature; 140 int i = 0; 141 for (Enumeration e = allFrames.elements(); e.hasMoreElements(); i++) { 142 FrameStruct frame = (FrameStruct )e.nextElement(); 143 methodName = getMethodName(frame.loc.classID, frame.loc.methodID); 144 classSignature = getClassSignature(frame.loc.classID); 145 logWriter.println("\t" + i + ". frameID=" + frame.frameID 146 + " - " + classSignature 147 + methodName 148 + "(" + frame.loc.index + ")"); 149 } 150 151 allFrames = getFrames(allFrames.size() + 1, -1); 152 if (err == JDWPConstants.Error.INVALID_INDEX) { 153 logWriter.println("Caught expected error - " + JDWPConstants.Error.getName(err) 154 + "(" + err + ")"); 155 } else { 156 printErrorAndFail("unexpected behaviour: error is " 157 + JDWPConstants.Error.getName(err) + "(" + err + ")" 158 + " but must be " 159 + JDWPConstants.Error.getName(JDWPConstants.Error.INVALID_INDEX) 160 + "(" + JDWPConstants.Error.INVALID_INDEX + ")"); 161 } 162 163 logWriter.println("==> testFrames004 OK. "); 164 debuggeeWrapper.vmMirror.resumeThread(threadID); 165 166 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 167 } 168 169 /** 170 * This testcase exercises ThreadReference.Frames command. 171 * <BR>At first the test starts FramesDebuggee which recursively invokes 172 * the method 'FramesDebuggee.recursiveMethod' thereby the specified depth 173 * 'FramesDebuggee.DEPTH' of recursion is reached. 174 * <BR> Then the tests performs the ThreadReference.Frames command 175 * for the main thread with parameters: 176 * <BR>startFrame=amount_of_all_frames, length=-1 177 * <BR>It is expected an empty set of frames is returned. 178 */ testFrames003()179 public void testFrames003() { 180 logWriter.println("==> testFrames003 START "); 181 String testedThreadName = synchronizer.receiveMessage(); 182 183 logWriter.println 184 ("==> testedThreadName = |" + testedThreadName +"|"); 185 threadID = debuggeeWrapper.vmMirror.getThreadID(testedThreadName); 186 logWriter.println("==> threadID = " + threadID); 187 debuggeeWrapper.vmMirror.suspendThread(threadID); 188 189 Vector allFrames = getFrames(0, -1); 190 if (err != JDWPConstants.Error.NONE) { 191 printErrorAndFail("Unexpected ERROR = " + err 192 + "(" + JDWPConstants.Error.getName(err) + ")"); 193 } 194 String methodName, classSignature; 195 int i = 0; 196 for (Enumeration e = allFrames.elements(); e.hasMoreElements(); i++) { 197 FrameStruct frame = (FrameStruct )e.nextElement(); 198 methodName = getMethodName(frame.loc.classID, frame.loc.methodID); 199 classSignature = getClassSignature(frame.loc.classID); 200 logWriter.println("\t" + i + ". frameID=" + frame.frameID 201 + " - " + classSignature 202 + methodName 203 + "(" + frame.loc.index + ")"); 204 } 205 206 allFrames = getFrames(allFrames.size(), -1); 207 if (err != JDWPConstants.Error.NONE) { 208 printErrorAndFail("Unexpected ERROR = " + err 209 + "(" + JDWPConstants.Error.getName(err) + ")"); 210 } 211 if (allFrames.size() == 0) { 212 logWriter.println("empty set of frames is returned"); 213 } else { 214 printErrorAndFail("it is expected an empty set of frames, but frameCount = " 215 + allFrames.size()); 216 } 217 218 logWriter.println("==> testFrames003 OK. "); 219 debuggeeWrapper.vmMirror.resumeThread(threadID); 220 221 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 222 } 223 224 /** 225 * This testcase exercises ThreadReference.Frames command. 226 * <BR>At first the test starts FramesDebuggee which recursively invokes 227 * the method 'FramesDebuggee.recursiveMethod' thereby the specified depth 228 * 'FramesDebuggee.DEPTH' of recursion is reached. 229 * <BR>Then the test by ThreadReference.Frames command 230 * requests all frames and looks for the first frame 231 * which has location in the 'recursiveMethod'. 232 * <BR>The index of such frame is passed as startFrame parameter for 233 * the second invocation of ThreadReference.Frames command. 234 * <BR>The length (the second parameter) is set to 'FramesDebuggee.DEPTH'. 235 * <BR>It is expected that the amount of returned frames is equal to 236 * 'FramesDebuggee.DEPTH' and all returned frames have locations in 237 * 'recursiveMethod'. 238 */ testFrames002()239 public void testFrames002() { 240 logWriter.println("==> testFrames002 START "); 241 String testedThreadName = synchronizer.receiveMessage(); 242 243 logWriter.println 244 ("==> testedThreadName = |" + testedThreadName +"|"); 245 threadID = debuggeeWrapper.vmMirror.getThreadID(testedThreadName); 246 logWriter.println("==> threadID = " + threadID); 247 debuggeeWrapper.vmMirror.suspendThread(threadID); 248 249 Vector allFrames = getFrames(0, -1); 250 if (err != JDWPConstants.Error.NONE) { 251 printErrorAndFail("Unexpected ERROR = " + err 252 + "(" + JDWPConstants.Error.getName(err) + ")"); 253 } 254 String methodName, classSignature; 255 int frameNumber = -1; 256 int i = 0; 257 for (Enumeration e = allFrames.elements(); e.hasMoreElements(); i++) { 258 FrameStruct frame = (FrameStruct )e.nextElement(); 259 methodName = getMethodName(frame.loc.classID, frame.loc.methodID); 260 classSignature = getClassSignature(frame.loc.classID); 261 if (frameNumber < 0 && FramesDebuggee.METHOD_NAME.equals(methodName)) { 262 frameNumber = i; 263 } 264 logWriter.println("\t" + i + ". frameID=" + frame.frameID 265 + " - " + classSignature 266 + methodName 267 + "(" + frame.loc.index + ")"); 268 } 269 270 if (frameNumber < 0) { 271 printErrorAndFail("frameNumber is unexpectedly equal to " + frameNumber); 272 } 273 274 allFrames = getFrames(frameNumber, FramesDebuggee.DEPTH); 275 if (err != JDWPConstants.Error.NONE) { 276 printErrorAndFail("Unexpected ERROR = " + err 277 + "(" + JDWPConstants.Error.getName(err) + ")"); 278 } 279 i = frameNumber; 280 int methodCount = 0; 281 String unexpectedMethods = null; 282 String depthError = null; 283 for (Enumeration e = allFrames.elements(); e.hasMoreElements(); i++) { 284 FrameStruct frame = (FrameStruct )e.nextElement(); 285 methodName = getMethodName(frame.loc.classID, frame.loc.methodID); 286 classSignature = getClassSignature(frame.loc.classID); 287 logWriter.println("\t" + i + ". frameID=" + frame.frameID 288 + " - " + classSignature 289 + methodName 290 + "(" + frame.loc.index + ")"); 291 292 if (methodName.equals(FramesDebuggee.METHOD_NAME)) { 293 methodCount++; 294 } else { 295 logWriter.printError("unexpected method - " + methodName); 296 unexpectedMethods = null == unexpectedMethods ? methodName : unexpectedMethods + "," + methodName; 297 } 298 } 299 300 if (methodCount != FramesDebuggee.DEPTH) { 301 logWriter.printError(depthError = ("Number of " + FramesDebuggee.METHOD_NAME + " in frames " 302 + methodCount + " but expected " + FramesDebuggee.DEPTH)); 303 } 304 305 debuggeeWrapper.vmMirror.resumeThread(threadID); 306 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 307 308 if (null != unexpectedMethods) { 309 logWriter.println("==> testFrames002 FAILED "); 310 fail("unexpected method(s): " + unexpectedMethods); 311 } 312 else if (null != depthError) { 313 logWriter.println("==> testFrames002 FAILED "); 314 fail(depthError); 315 } else { 316 logWriter.println("==> testFrames002 OK. "); 317 } 318 } 319 320 /** 321 * This testcase exercises ThreadReference.Frames command. 322 * <BR>At first the test starts FramesDebuggee which recursively invokes 323 * the method 'FramesDebuggee.recursiveMethod' thereby the specified depth 324 * 'FramesDebuggee.DEPTH' of recursion is reached. 325 * <BR>Then the test by ThreadReference.Frames command 326 * requests all frames and looks for the first frame 327 * which has location in the 'recursiveMethod'. 328 * <BR>The index of such frame is passed as startFrame parameter for 329 * the second invocation of ThreadReference.Frames command. 330 * <BR>The length (the second parameter) is set to '-1'. 331 * <BR>It is expected that the amount of returned frames which are located in 332 * 'recursiveMethod' is equal to 'FramesDebuggee.DEPTH'. 333 */ testFrames001()334 public void testFrames001() { 335 logWriter.println("==> testFrames001 START "); 336 String testedThreadName = synchronizer.receiveMessage(); 337 338 logWriter.println 339 ("==> testedThreadName = |" + testedThreadName +"|"); 340 threadID = debuggeeWrapper.vmMirror.getThreadID(testedThreadName); 341 logWriter.println("==> threadID = " + threadID); 342 debuggeeWrapper.vmMirror.suspendThread(threadID); 343 344 Vector allFrames = getFrames(0, -1); 345 if (err != JDWPConstants.Error.NONE) { 346 printErrorAndFail("Unexpected ERROR = " + err 347 + "(" + JDWPConstants.Error.getName(err) + ")"); 348 } 349 String methodName, classSignature; 350 int frameNumber = -1; 351 int i = 0; 352 for (Enumeration e = allFrames.elements(); e.hasMoreElements(); i++) { 353 FrameStruct frame = (FrameStruct )e.nextElement(); 354 methodName = getMethodName(frame.loc.classID, frame.loc.methodID); 355 classSignature = getClassSignature(frame.loc.classID); 356 if (frameNumber < 0 && FramesDebuggee.METHOD_NAME.equals(methodName)) { 357 frameNumber = i; 358 } 359 logWriter.println("\t" + i + ". frameID=" + frame.frameID 360 + " - " + classSignature 361 + methodName 362 + "(" + frame.loc.index + ")"); 363 } 364 365 if (frameNumber < 0) { 366 logWriter.printError("frameNumber is unexpectedly equal to " + frameNumber); 367 assertTrue("Invalid frameNumber", frameNumber > 0); 368 } 369 370 allFrames = getFrames(frameNumber, -1); 371 if (err != JDWPConstants.Error.NONE) { 372 printErrorAndFail("Unexpected ERROR = " + err 373 + "(" + JDWPConstants.Error.getName(err) + ")"); 374 } 375 i = frameNumber; 376 int methodCount = 0; 377 boolean testCondition; 378 String unexpectedMethods = null; 379 String depthError = null; 380 for (Enumeration e = allFrames.elements(); e.hasMoreElements(); i++) { 381 FrameStruct frame = (FrameStruct )e.nextElement(); 382 methodName = getMethodName(frame.loc.classID, frame.loc.methodID); 383 classSignature = getClassSignature(frame.loc.classID); 384 logWriter.println("\t" + i + ". frameID=" + frame.frameID 385 + " - " + classSignature 386 + methodName 387 + "(" + frame.loc.index + ")"); 388 testCondition = (i == frameNumber 389 && !methodName.equals(FramesDebuggee.METHOD_NAME)); 390 if (testCondition) { 391 logWriter.printError("unexpected method name of the first frame - " 392 + methodName); 393 unexpectedMethods = null == unexpectedMethods ? methodName : unexpectedMethods + "," + methodName; 394 } 395 396 if (methodName.equals(FramesDebuggee.METHOD_NAME)) { 397 methodCount++; 398 } 399 } 400 401 if (methodCount != FramesDebuggee.DEPTH) { 402 logWriter.printError(depthError = ("Number of " + FramesDebuggee.METHOD_NAME + " in frames " 403 + methodCount + " but expected " + FramesDebuggee.DEPTH)); 404 } 405 406 debuggeeWrapper.vmMirror.resumeThread(threadID); 407 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 408 409 if (null != unexpectedMethods) { 410 logWriter.println("==> testFrames001 FAILED "); 411 fail("unexpected method(s): " + unexpectedMethods); 412 } 413 else if (null != depthError) { 414 logWriter.println("==> testFrames001 FAILED "); 415 fail(depthError); 416 } else { 417 logWriter.println("==> testFrames001 OK. "); 418 } 419 } 420 getFrames(int startFrame, int length)421 private Vector getFrames(int startFrame, int length) { 422 423 Vector<FrameStruct> frames = new Vector<FrameStruct>(); 424 425 logWriter.println("startFrame=" + startFrame 426 + "; length=" + length); 427 428 // getting frames of the thread 429 CommandPacket packet = new CommandPacket( 430 JDWPCommands.ThreadReferenceCommandSet.CommandSetID, 431 JDWPCommands.ThreadReferenceCommandSet.FramesCommand); 432 packet.setNextValueAsThreadID(threadID); 433 packet.setNextValueAsInt(startFrame); 434 packet.setNextValueAsInt(length); 435 ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet); 436 err = reply.getErrorCode(); 437 if ( err != JDWPConstants.Error.NONE) { 438 logWriter.println("\tthreadID=" + threadID 439 + " - " + JDWPConstants.Error.getName(err)); 440 return null; 441 } 442 int framesCount = reply.getNextValueAsInt(); 443 long frameID; 444 Location loc; 445 logWriter.println("framesCount=" + framesCount); 446 for (int j = 0; j < framesCount; j++) { 447 frameID = reply.getNextValueAsFrameID(); 448 loc = reply.getNextValueAsLocation(); 449 frames.add(new FrameStruct(frameID, loc)); 450 } 451 return frames; 452 } 453 } 454