1 /* 2 * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package nsk.jdwp.Event.CLASS_PREPARE; 25 26 import java.io.*; 27 28 import nsk.share.*; 29 import nsk.share.jpda.*; 30 import nsk.share.jdwp.*; 31 32 /** 33 * Test for JDWP event: CLASS_PREPARE. 34 * 35 * See clsprepare001.README for description of test execution. 36 * 37 * This class represents debugger part of the test. 38 * Test is executed by invoking method runIt(). 39 * JDWP event is tested in the method waitForTestedEvent(). 40 * 41 * @see #runIt() 42 * @see #waitForTestedEvent() 43 */ 44 public class clsprepare001 { 45 46 // exit status constants 47 static final int JCK_STATUS_BASE = 95; 48 static final int PASSED = 0; 49 static final int FAILED = 2; 50 51 // package and classes names constants 52 static final String PACKAGE_NAME = "nsk.jdwp.Event.CLASS_PREPARE"; 53 static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "clsprepare001"; 54 static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a"; 55 56 // tested JDWP event constants 57 static final byte TESTED_EVENT_KIND = JDWP.EventKind.CLASS_PREPARE; 58 static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL; 59 60 // name and signature of the tested class 61 static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass"; 62 static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";"; 63 64 // usual scaffold objects 65 ArgumentHandler argumentHandler = null; 66 Log log = null; 67 Binder binder = null; 68 Debugee debugee = null; 69 Transport transport = null; 70 int waitTime = 0; // minutes 71 long timeout = 0; // milliseconds 72 boolean dead = false; 73 boolean success = true; 74 75 // obtained data 76 int eventRequestID = 0; 77 78 // ------------------------------------------------------------------- 79 80 /** 81 * Start test from command line. 82 */ main(String argv[])83 public static void main(String argv[]) { 84 System.exit(run(argv,System.out) + JCK_STATUS_BASE); 85 } 86 87 /** 88 * Start test from JCK-compilant environment. 89 */ run(String argv[], PrintStream out)90 public static int run(String argv[], PrintStream out) { 91 return new clsprepare001().runIt(argv, out); 92 } 93 94 // ------------------------------------------------------------------- 95 96 /** 97 * Perform test execution. 98 */ runIt(String argv[], PrintStream out)99 public int runIt(String argv[], PrintStream out) { 100 101 // make log for debugger messages 102 argumentHandler = new ArgumentHandler(argv); 103 log = new Log(out, argumentHandler); 104 waitTime = argumentHandler.getWaitTime(); 105 timeout = waitTime * 60 * 1000; 106 107 // execute test and display results 108 try { 109 log.display("\n>>> Starting debugee \n"); 110 111 // launch debuggee 112 binder = new Binder(argumentHandler, log); 113 log.display("Launching debugee"); 114 debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME); 115 transport = debugee.getTransport(); 116 log.display(" ... debugee launched"); 117 log.display(""); 118 119 // set timeout for debuggee responces 120 log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)"); 121 transport.setReadTimeout(timeout); 122 log.display(" ... timeout set"); 123 124 // wait for debuggee started 125 log.display("Waiting for VM_INIT event"); 126 debugee.waitForVMInit(); 127 log.display(" ... VM_INIT event received"); 128 129 // query debugee for VM-dependent ID sizes 130 log.display("Querying for IDSizes"); 131 debugee.queryForIDSizes(); 132 log.display(" ... size of VM-dependent types adjusted"); 133 134 // make request for CLASS_PREPARE event 135 log.display("\n>>> Making request for tested event \n"); 136 137 log.display("Making request for CLASS_PREPARE event for class:\n\t" 138 + TESTED_CLASS_NAME); 139 requestTestedEvent(); 140 log.display(" ... got requestID: " + eventRequestID); 141 142 // resume debuggee 143 log.display("Resumindg debuggee"); 144 debugee.resume(); 145 log.display(" ... debuggee resumed"); 146 147 // wait for tested CLASS_PREPARE event 148 log.display("\n>>> Testing JDWP event \n"); 149 waitForTestedEvent(); 150 151 // clear tested request for CLASS_PREPARE event 152 log.display("\n>>> Clearing request for tested event \n"); 153 clearTestedRequest(); 154 155 // finish debuggee after testing 156 log.display("\n>>> Finishing debuggee \n"); 157 158 // resume debuggee 159 log.display("Resuming debuggee"); 160 debugee.resume(); 161 log.display(" ... debuggee resumed"); 162 163 // wait for debuggee exited 164 log.display("Waiting for VM_DEATH event"); 165 debugee.waitForVMDeath(); 166 dead = true; 167 log.display(" ... VM_DEATH event received"); 168 169 } catch (Failure e) { 170 log.complain("TEST FAILED: " + e.getMessage()); 171 success = false; 172 } catch (Exception e) { 173 e.printStackTrace(out); 174 log.complain("Caught unexpected exception while running the test:\n\t" + e); 175 success = false; 176 } finally { 177 // quit debugee 178 log.display("\n>>> Finishing test \n"); 179 quitDebugee(); 180 } 181 182 // check test results 183 if (!success) { 184 log.complain("TEST FAILED"); 185 return FAILED; 186 } 187 188 out.println("TEST PASSED"); 189 return PASSED; 190 191 } 192 193 /** 194 * Make request for tested CLASS_PREPARE event. 195 */ requestTestedEvent()196 void requestTestedEvent() { 197 Failure failure = new Failure("Error occured while makind request for tested event"); 198 199 // create command packet and fill requred out data 200 log.display("Create command packet: " + "EventRequest.Set"); 201 CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set); 202 log.display(" eventKind: " + TESTED_EVENT_KIND); 203 command.addByte(TESTED_EVENT_KIND); 204 log.display(" eventPolicy: " + TESTED_EVENT_SUSPEND_POLICY); 205 command.addByte(TESTED_EVENT_SUSPEND_POLICY); 206 log.display(" modifiers: " + 1); 207 command.addInt(1); 208 log.display(" modKind: " + JDWP.EventModifierKind.CLASS_MATCH); 209 command.addByte(JDWP.EventModifierKind.CLASS_MATCH); 210 log.display(" classPattern: " + TESTED_CLASS_NAME); 211 command.addString(TESTED_CLASS_NAME); 212 command.setLength(); 213 log.display(" ... command packet composed"); 214 215 // send command packet to debugee 216 try { 217 log.display("Sending command packet:\n" + command); 218 transport.write(command); 219 log.display(" ... command packet sent"); 220 } catch (IOException e) { 221 log.complain("Unable to send command packet:\n\t" + e); 222 success = false; 223 throw failure; 224 } 225 226 ReplyPacket reply = new ReplyPacket(); 227 228 // receive reply packet from debugee 229 try { 230 log.display("Waiting for reply packet"); 231 transport.read(reply); 232 log.display(" ... packet received:\n" + reply); 233 } catch (IOException e) { 234 log.complain("Unable to read reply packet:\n\t" + e); 235 success = false; 236 throw failure; 237 } 238 239 // check reply packet header 240 try{ 241 log.display("Checking header of reply packet"); 242 reply.checkHeader(command.getPacketID()); 243 log.display(" .. packet header is correct"); 244 } catch (BoundException e) { 245 log.complain("Bad header of reply packet:\n\t" + e.getMessage()); 246 success = false; 247 throw failure; 248 } 249 250 // start parsing reply packet data 251 log.display("Parsing reply packet:"); 252 reply.resetPosition(); 253 254 // extract requestID 255 int requestID = 0; 256 try { 257 requestID = reply.getInt(); 258 log.display(" requestID: " + requestID); 259 } catch (BoundException e) { 260 log.complain("Unable to extract requestID from request reply packet:\n\t" 261 + e.getMessage()); 262 success = false; 263 throw failure; 264 } 265 266 // check requestID 267 if (requestID == 0) { 268 log.complain("Unexpected null requestID returned: " + requestID); 269 success = false; 270 throw failure; 271 } 272 273 eventRequestID = requestID; 274 275 // check for extra data in reply packet 276 if (!reply.isParsed()) { 277 log.complain("Extra trailing bytes found in request reply packet at: " 278 + reply.offsetString()); 279 success = false; 280 } 281 282 log.display(" ... reply packet parsed"); 283 } 284 285 /** 286 * Clear request for tested CLASS_PREPARE event. 287 */ clearTestedRequest()288 void clearTestedRequest() { 289 Failure failure = new Failure("Error occured while clearing request for tested event"); 290 291 // create command packet and fill requred out data 292 log.display("Create command packet: " + "EventRequest.Clear"); 293 CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear); 294 log.display(" event: " + TESTED_EVENT_KIND); 295 command.addByte(TESTED_EVENT_KIND); 296 log.display(" requestID: " + eventRequestID); 297 command.addInt(eventRequestID); 298 log.display(" ... command packet composed"); 299 300 // send command packet to debugee 301 try { 302 log.display("Sending command packet:\n" + command); 303 transport.write(command); 304 log.display(" ... command packet sent"); 305 } catch (IOException e) { 306 log.complain("Unable to send command packet:\n\t" + e); 307 success = false; 308 throw failure; 309 } 310 311 ReplyPacket reply = new ReplyPacket(); 312 313 // receive reply packet from debugee 314 try { 315 log.display("Waiting for reply packet"); 316 transport.read(reply); 317 log.display(" ... packet received:\n" + reply); 318 } catch (IOException e) { 319 log.complain("Unable to read reply packet:\n\t" + e); 320 success = false; 321 throw failure; 322 } 323 324 // check reply packet header 325 try{ 326 log.display("Checking header of reply packet"); 327 reply.checkHeader(command.getPacketID()); 328 log.display(" .. packet header is correct"); 329 } catch (BoundException e) { 330 log.complain("Bad header of reply packet:\n\t" + e.getMessage()); 331 success = false; 332 throw failure; 333 } 334 335 // start parsing reply packet data 336 log.display("Parsing reply packet:"); 337 reply.resetPosition(); 338 339 log.display(" no data"); 340 341 // check for extra data in reply packet 342 if (!reply.isParsed()) { 343 log.complain("Extra trailing bytes found in request reply packet at: " 344 + reply.offsetString()); 345 success = false; 346 } 347 348 log.display(" ... reply packet parsed"); 349 } 350 351 /** 352 * Wait for tested CLASS_PREPARE event. 353 */ waitForTestedEvent()354 void waitForTestedEvent() { 355 356 EventPacket eventPacket = null; 357 358 // receive reply packet from debugee 359 try { 360 log.display("Waiting for event packet (for " + timeout + "ms timeout)"); 361 eventPacket = debugee.getEventPacket(timeout); 362 log.display(" ... event packet received:\n" + eventPacket); 363 } catch (IOException e) { 364 log.complain("Unable to read tested event packet:\n\t" + e); 365 success = false; 366 return; 367 } 368 369 // check reply packet header 370 try{ 371 log.display("Checking header of event packet"); 372 eventPacket.checkHeader(); 373 log.display(" ... packet header is correct"); 374 } catch (BoundException e) { 375 log.complain("Bad header of tested event packet:\n\t" 376 + e.getMessage()); 377 success = false; 378 return; 379 } 380 381 // start parsing reply packet data 382 log.display("Parsing event packet:"); 383 eventPacket.resetPosition(); 384 385 // get suspendPolicy value 386 byte suspendPolicy = 0; 387 try { 388 suspendPolicy = eventPacket.getByte(); 389 log.display(" suspendPolicy: " + suspendPolicy); 390 } catch (BoundException e) { 391 log.complain("Unable to get suspendPolicy value from tested event packet:\n\t" 392 + e.getMessage()); 393 success = false; 394 return; 395 } 396 397 // check suspendPolicy value 398 if (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY) { 399 log.complain("Unexpected SuspendPolicy in tested event packet: " + 400 suspendPolicy + " (expected: " + TESTED_EVENT_SUSPEND_POLICY + ")"); 401 success = false; 402 } 403 404 // get events count 405 int events = 0; 406 try { 407 events = eventPacket.getInt(); 408 log.display(" events: " + events); 409 } catch (BoundException e) { 410 log.complain("Unable to get events count from tested event packet:\n\t" 411 + e.getMessage()); 412 success = false; 413 return; 414 } 415 416 // check events count 417 if (events < 0) { 418 log.complain("Negative value of events number in tested event packet: " + 419 events + " (expected: " + 1 + ")"); 420 success = false; 421 } else if (events != 1) { 422 log.complain("Invalid number of events in tested event packet: " + 423 events + " (expected: " + 1 + ")"); 424 success = false; 425 } 426 427 // extract each event 428 for (int i = 0; i < events; i++) { 429 log.display(" event #" + i + ":"); 430 431 // get eventKind 432 byte eventKind = 0; 433 try { 434 eventKind = eventPacket.getByte(); 435 log.display(" eventKind: " + eventKind); 436 } catch (BoundException e) { 437 log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t" 438 + e.getMessage()); 439 success = false; 440 return; 441 } 442 443 // check eventKind 444 if (eventKind != JDWP.EventKind.CLASS_PREPARE) { 445 log.complain("Unexpected eventKind of event " + i + " in tested event packet: " + 446 eventKind + " (expected: " + JDWP.EventKind.CLASS_PREPARE + ")"); 447 success = false; 448 return; 449 } 450 451 // get requestID 452 int requestID = 0; 453 try { 454 requestID = eventPacket.getInt(); 455 log.display(" requestID: " + requestID); 456 } catch (BoundException e) { 457 log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t" 458 + e.getMessage()); 459 success = false; 460 return; 461 } 462 463 // check requestID 464 if (requestID != eventRequestID) { 465 log.complain("Unexpected requestID of event " + i + " in tested event packet: " + 466 requestID + " (expected: " + eventRequestID + ")"); 467 success = false; 468 } 469 470 // get threadID 471 long threadID = 0; 472 try { 473 threadID = eventPacket.getObjectID(); 474 log.display(" threadID: " + threadID); 475 } catch (BoundException e) { 476 log.complain("Unable to get threadID of event #" + i + " from tested event packet:\n\t" 477 + e.getMessage()); 478 success = false; 479 return; 480 } 481 482 // check threadID 483 if (threadID == 0) { 484 log.complain("Unexpected null threadID of event " + i + " in tested event packet: " + 485 threadID); 486 success = false; 487 } 488 489 // get refTypeTag 490 byte refTypeTag = 0; 491 try { 492 refTypeTag = eventPacket.getByte(); 493 log.display(" refTypeTag: " + refTypeTag); 494 } catch (BoundException e) { 495 log.complain("Unable to get refTypeTag of event #" + i + " from tested event packet:\n\t" 496 + e.getMessage()); 497 success = false; 498 return; 499 } 500 501 // check refTypeGag 502 if (refTypeTag != JDWP.TypeTag.CLASS) { 503 log.complain("Unexpected refTypeTag of event " + i + " in tested event packet: " + 504 refTypeTag + " (expected: " + JDWP.TypeTag.CLASS + ")"); 505 success = false; 506 } 507 508 // get referenceTypeID 509 long referenceTypeID = 0; 510 try { 511 referenceTypeID = eventPacket.getReferenceTypeID(); 512 log.display(" referenceTypeID: " + referenceTypeID); 513 } catch (BoundException e) { 514 log.complain("Unable to get referenceTypeID of event #" + i + " from tested event packet:\n\t" 515 + e.getMessage()); 516 success = false; 517 return; 518 } 519 520 // check referenceTypeID 521 if (referenceTypeID == 0) { 522 log.complain("Unexpected null referenceTypeID of event " + i + " in tested event packet: " + 523 referenceTypeID); 524 success = false; 525 } 526 527 // get signature 528 String signature = null; 529 try { 530 signature = eventPacket.getString(); 531 log.display(" signature: " + signature); 532 } catch (BoundException e) { 533 log.complain("Unable to get class signature of event #" + i + " from tested event packet:\n\t" 534 + e.getMessage()); 535 success = false; 536 return; 537 } 538 539 // check signature 540 if (!signature.equals(TESTED_CLASS_SIGNATURE)) { 541 log.complain("Unexpected class signature of event " + i + " in tested event packet: " + 542 signature + " (expected: " + TESTED_CLASS_SIGNATURE + ")"); 543 success = false; 544 } 545 546 // get status 547 int status = 0; 548 try { 549 status = eventPacket.getInt(); 550 log.display(" status: " + status); 551 } catch (BoundException e) { 552 log.complain("Unable to get class status of event #" + i + " from tested event packet:\n\t" 553 + e.getMessage()); 554 success = false; 555 return; 556 } 557 558 // check status 559 if ((status & JDWP.ClassStatus.ERROR) != 0) { 560 log.complain("Unexpected class status of event " + i + " in tested event packet: " + 561 status + " (expected: w/o bit " + JDWP.ClassStatus.ERROR + ")"); 562 success = false; 563 } 564 } 565 566 // check for extra data in event packet 567 if (!eventPacket.isParsed()) { 568 log.complain("Extra trailing bytes found in event packet at: " 569 + eventPacket.offsetString()); 570 success = false; 571 } 572 573 log.display(" ... event packet parsed"); 574 } 575 576 /** 577 * Disconnect debuggee and wait for it exited. 578 */ quitDebugee()579 void quitDebugee() { 580 if (debugee == null) 581 return; 582 583 // disconnect debugee 584 if (!dead) { 585 try { 586 log.display("Disconnecting debuggee"); 587 debugee.dispose(); 588 log.display(" ... debuggee disconnected"); 589 } catch (Failure e) { 590 log.display("Failed to finally disconnect debuggee:\n\t" 591 + e.getMessage()); 592 } 593 } 594 595 // wait for debugee exited 596 log.display("Waiting for debuggee exit"); 597 int code = debugee.waitFor(); 598 log.display(" ... debuggee exited with exit code: " + code); 599 600 // analize debugee exit status code 601 if (code != JCK_STATUS_BASE + PASSED) { 602 log.complain("Debuggee FAILED with exit code: " + code); 603 success = false; 604 } 605 } 606 607 } 608