test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassLoaderReference/VisibleClasses/visibclasses001.java
changeset 50317 cf71bff5f533
equal deleted inserted replaced
50316:60ebcc705421 50317:cf71bff5f533
       
     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.ClassLoaderReference.VisibleClasses;
       
    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 command: ClassLoaderReference.VisibleClasses.
       
    34  *
       
    35  * See visibclasses001.README for description of test execution.
       
    36  *
       
    37  * Test is executed by invoking method runIt().
       
    38  * JDWP command is tested in method testCommand().
       
    39  *
       
    40  * @see #runIt()
       
    41  * @see #testCommand()
       
    42  */
       
    43 public class visibclasses001 {
       
    44 
       
    45     // exit status constants
       
    46     static final int JCK_STATUS_BASE = 95;
       
    47     static final int PASSED = 0;
       
    48     static final int FAILED = 2;
       
    49 
       
    50     // communication signals constants
       
    51     static final String READY = "ready";
       
    52     static final String QUIT = "quit";
       
    53 
       
    54     // package and classes names constants
       
    55     static final String PACKAGE_NAME = "nsk.jdwp.ClassLoaderReference.VisibleClasses";
       
    56     static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "visibclasses001";
       
    57     static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
       
    58 
       
    59     // tested JDWP command constants
       
    60     static final String JDWP_COMMAND_NAME = "ClassLoaderReference.VisibleClasses";
       
    61     static final int JDWP_COMMAND_ID = JDWP.Command.ClassLoaderReference.VisibleClasses;
       
    62 
       
    63     // tested class name and signature constants
       
    64     static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
       
    65     static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
       
    66 
       
    67     // usual scaffold objects
       
    68     ArgumentHandler argumentHandler = null;
       
    69     Log log = null;
       
    70     Binder binder = null;
       
    71     Debugee debugee = null;
       
    72     Transport transport = null;
       
    73     IOPipe pipe = null;
       
    74 
       
    75     // test passed or not
       
    76     boolean success = true;
       
    77 
       
    78     // -------------------------------------------------------------------
       
    79 
       
    80     /**
       
    81      * Start test from command line.
       
    82      */
       
    83     public static void main (String argv[]) {
       
    84         System.exit(run(argv,System.out) + JCK_STATUS_BASE);
       
    85     }
       
    86 
       
    87     /**
       
    88      * Start JCK-compilant test.
       
    89      */
       
    90     public static int run(String argv[], PrintStream out) {
       
    91         return new visibclasses001().runIt(argv, out);
       
    92     }
       
    93 
       
    94     // -------------------------------------------------------------------
       
    95 
       
    96     /**
       
    97      * Perform test execution.
       
    98      */
       
    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 
       
   105         // execute test and display results
       
   106         try {
       
   107             log.display("\n>>> Preparing debugee for testing \n");
       
   108 
       
   109             // launch debugee
       
   110             binder = new Binder(argumentHandler, log);
       
   111             log.display("Launching debugee");
       
   112             debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
       
   113             transport = debugee.getTransport();
       
   114             pipe = debugee.createIOPipe();
       
   115 
       
   116             // make debuggee ready for testing
       
   117             prepareDebugee();
       
   118 
       
   119             // work with prepared debugee
       
   120             try {
       
   121                 log.display("\n>>> Obtaining requred data from debugee \n");
       
   122 
       
   123                 // query debugee for TypeID of tested class
       
   124                 log.display("Getting ReferenceTypeID by signature:\n"
       
   125                             + "  " + TESTED_CLASS_SIGNATURE);
       
   126                 long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
       
   127                 log.display("  got classID: " + classID);
       
   128 
       
   129                 // query debugee for TypeIDs of classes been nested
       
   130                 log.display("Getting classLoaderID for tested classes");
       
   131                 long classLoaderID = queryClassLoaderID(classID);
       
   132                 log.display("  got classLoaderID: " + classLoaderID);
       
   133 
       
   134                 // perform testing JDWP command
       
   135                 log.display("\n>>> Testing JDWP command \n");
       
   136                 testCommand(classLoaderID, classID);
       
   137 
       
   138             } finally {
       
   139                 // quit debugee
       
   140                 log.display("\n>>> Finishing test \n");
       
   141                 quitDebugee();
       
   142             }
       
   143 
       
   144         } catch (Failure e) {
       
   145             log.complain("TEST FAILED: " + e.getMessage());
       
   146             success = false;
       
   147         } catch (Exception e) {
       
   148             e.printStackTrace(out);
       
   149             log.complain("Caught unexpected exception while running the test:\n\t" + e);
       
   150             success = false;
       
   151         }
       
   152 
       
   153         if (!success) {
       
   154             log.complain("TEST FAILED");
       
   155             return FAILED;
       
   156         }
       
   157 
       
   158         out.println("TEST PASSED");
       
   159         return PASSED;
       
   160 
       
   161     }
       
   162 
       
   163     /**
       
   164      * Prepare debugee for testing and waiting for ready signal.
       
   165      */
       
   166     void prepareDebugee() {
       
   167         // wait for VM_INIT event from debugee
       
   168         log.display("Waiting for VM_INIT event");
       
   169         debugee.waitForVMInit();
       
   170 
       
   171         // query debugee for VM-dependent ID sizes
       
   172         log.display("Querying for IDSizes");
       
   173         debugee.queryForIDSizes();
       
   174 
       
   175         // resume initially suspended debugee
       
   176         log.display("Resuming debugee VM");
       
   177         debugee.resume();
       
   178 
       
   179         // wait for READY signal from debugee
       
   180         log.display("Waiting for signal from debugee: " + READY);
       
   181         String signal = pipe.readln();
       
   182         log.display("Received signal from debugee: " + signal);
       
   183         if (! signal.equals(READY)) {
       
   184             throw new TestBug("Unexpected signal received from debugee: " + signal
       
   185                             + " (expected: " + READY + ")");
       
   186         }
       
   187     }
       
   188 
       
   189     /**
       
   190      * Sending debugee signal to quit and waiting for it exits.
       
   191      */
       
   192     void quitDebugee() {
       
   193         // send debugee signal to quit
       
   194         log.display("Sending signal to debugee: " + QUIT);
       
   195         pipe.println(QUIT);
       
   196 
       
   197         // wait for debugee exits
       
   198         log.display("Waiting for debugee exits");
       
   199         int code = debugee.waitFor();
       
   200 
       
   201         // analize debugee exit status code
       
   202         if (code == JCK_STATUS_BASE + PASSED) {
       
   203             log.display("Debugee PASSED with exit code: " + code);
       
   204         } else {
       
   205             log.complain("Debugee FAILED with exit code: " + code);
       
   206             success = false;
       
   207         }
       
   208     }
       
   209 
       
   210     /**
       
   211      * Query debugee for classLoaderID for specified classID.
       
   212      */
       
   213     long queryClassLoaderID(long classID) {
       
   214         CommandPacket command =
       
   215                         new CommandPacket(JDWP.Command.ReferenceType.ClassLoader);
       
   216         command.addReferenceTypeID(classID);
       
   217         ReplyPacket reply = debugee.receiveReplyFor(command);
       
   218 
       
   219         try {
       
   220             reply.resetPosition();
       
   221 
       
   222             long classLoaderID = reply.getObjectID();
       
   223             return classLoaderID;
       
   224         } catch (BoundException e) {
       
   225             throw new Failure("Unable to parse reply packet for ReferenceType.ClassLoader:\n\t"
       
   226                             + e);
       
   227         }
       
   228     }
       
   229 
       
   230     /**
       
   231      * Perform testing JDWP command for specified classLoaderID.
       
   232      */
       
   233     void testCommand(long classLoaderID, long expectedClassID) {
       
   234         // create command packet and fill requred out data
       
   235         log.display("Create command packet:");
       
   236         log.display("Command: " + JDWP_COMMAND_NAME);
       
   237         log.display("  classLoaderID: " + classLoaderID);
       
   238         CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
       
   239         command.addObjectID(classLoaderID);
       
   240         command.setLength();
       
   241 
       
   242         // send command packet to debugee
       
   243         try {
       
   244             log.display("Sending command packet:\n" + command);
       
   245             transport.write(command);
       
   246         } catch (IOException e) {
       
   247             log.complain("Unable to send command packet:\n\t" + e);
       
   248             success = false;
       
   249             return;
       
   250         }
       
   251 
       
   252         ReplyPacket reply = new ReplyPacket();
       
   253 
       
   254         // receive reply packet from debugee
       
   255         try {
       
   256             log.display("Waiting for reply packet");
       
   257             transport.read(reply);
       
   258             log.display("Reply packet received:\n" + reply);
       
   259         } catch (IOException e) {
       
   260             log.complain("Unable to read reply packet:\n\t" + e);
       
   261             success = false;
       
   262             return;
       
   263         }
       
   264 
       
   265         // check reply packet header
       
   266         try{
       
   267             log.display("Checking reply packet header");
       
   268             reply.checkHeader(command.getPacketID());
       
   269         } catch (BoundException e) {
       
   270             log.complain("Bad header of reply packet:\n\t" + e.getMessage());
       
   271             success = false;
       
   272             return;
       
   273         }
       
   274 
       
   275         // start parsing reply packet data
       
   276         log.display("Parsing reply packet:");
       
   277         reply.resetPosition();
       
   278 
       
   279         // extract and check number of nested classes
       
   280         int classes = 0;
       
   281         try {
       
   282             classes = reply.getInt();
       
   283             log.display("  classes: " + classes);
       
   284 
       
   285         } catch (BoundException e) {
       
   286             log.complain("Unable to extract number of nested classes from reply packet:\n\t"
       
   287                         + e.getMessage());
       
   288             success = false;
       
   289         }
       
   290 
       
   291         if (classes < 0) {
       
   292             log.complain("Negative number of classes in the reply packet:" + classes);
       
   293             success = false;
       
   294         } else if (classes == 0) {
       
   295             log.complain("Zero number of classes in the reply packet:" + classes);
       
   296             success = false;
       
   297         }
       
   298 
       
   299         boolean found = false;
       
   300         // extract and check TypeID for each received class
       
   301         for (int i = 0; i < classes; i++ ) {
       
   302                 log.display("  class #" + i);
       
   303 
       
   304             // extract TypeTag byte
       
   305             byte refTypeTag = (byte)0;
       
   306             String refTypeTagName = null;
       
   307             try {
       
   308                 refTypeTag = reply.getByte();
       
   309                 String tag;
       
   310                 switch (refTypeTag) {
       
   311                     case JDWP.TypeTag.CLASS:
       
   312                         refTypeTagName = "CLASS";
       
   313                         break;
       
   314                     case JDWP.TypeTag.INTERFACE:
       
   315                         refTypeTagName = "INTERFACE";
       
   316                         break;
       
   317                     case JDWP.TypeTag.ARRAY:
       
   318                         refTypeTagName = "ARRAY";
       
   319                         break;
       
   320                     default:
       
   321                         refTypeTagName = "UNKNOWN";
       
   322                         break;
       
   323                 }
       
   324                 log.display("    refTypeTag: " + refTypeTag + "=" + refTypeTagName);
       
   325             } catch (BoundException e) {
       
   326                 log.complain("Unable to extract refTypetag of " + i
       
   327                             + " class from reply packet:\n\t"
       
   328                             + e.getMessage());
       
   329                 success = false;
       
   330                 break;
       
   331             }
       
   332 
       
   333             // extract and check TypeID
       
   334             long typeID = 0;
       
   335             try {
       
   336                 typeID = reply.getReferenceTypeID();
       
   337                 log.display("    typeID: " + typeID);
       
   338 
       
   339             } catch (BoundException e) {
       
   340                 log.complain("Unable to extract TypeID of " + i
       
   341                                 + " nested class from reply packet:\n\t"
       
   342                                 + e.getMessage());
       
   343                 success = false;
       
   344                 break;
       
   345             }
       
   346 
       
   347             if (typeID == expectedClassID) {
       
   348                 log.display("Found expected classID: " + expectedClassID);
       
   349                 found = true;
       
   350                 if (refTypeTag != JDWP.TypeTag.CLASS) {
       
   351                     log.complain("unexpected refTypeTag returned for checked class: "
       
   352                                 + refTypeTag + "=" + refTypeTagName
       
   353                                 + " (expected: " + JDWP.TypeTag.CLASS + "=CLASS)");
       
   354                     success = false;
       
   355                 }
       
   356             }
       
   357         }
       
   358 
       
   359         // check for extra data in reply packet
       
   360         if (!reply.isParsed()) {
       
   361             log.complain("Extra trailing bytes found in reply packet at: " + reply.offsetString());
       
   362             success = false;
       
   363         }
       
   364 
       
   365         if (!found) {
       
   366             log.complain("Expected classID not found in the list of visible classes: " + expectedClassID);
       
   367             success = false;
       
   368         }
       
   369     }
       
   370 
       
   371 }