Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues002.java
41162 views
/*1* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223package nsk.jdwp.ArrayReference.GetValues;2425import java.io.*;2627import nsk.share.*;28import nsk.share.jpda.*;29import nsk.share.jdwp.*;3031/**32* Test for JDWP command: ArrayReference.GetValues.33*34* See getvalues002.README for description of test execution.35*36* Test is executed by invoking method runIt().37* JDWP command is tested in method testCommand().38*39* @see #runIt()40* @see #testCommand()41*/42public class getvalues002 {4344// exit status constants45static final int JCK_STATUS_BASE = 95;46static final int PASSED = 0;47static final int FAILED = 2;4849// communication signals constants50static final String READY = "ready";51static final String QUIT = "quit";5253// package and classes names constants54static final String PACKAGE_NAME = "nsk.jdwp.ArrayReference.GetValues";55static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "getvalues002";56static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";5758// tested JDWP command constants59static final String JDWP_COMMAND_NAME = "ArrayReference.GetValues";60static final int JDWP_COMMAND_ID = JDWP.Command.ArrayReference.GetValues;6162// tested class name and signature constants63static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";64static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";6566// name of the static field in the tested class with the tested object value67static final String ARRAY_FIELD_NAME = getvalues002a.ARRAY_FIELD_NAME;68static final int ARRAY_LENGTH = getvalues002a.ARRAY_LENGTH;6970// names of the statc fields with object values71static final int FIELDS_COUNT = getvalues002a.FIELDS_COUNT;72static final String FIELD_NAMES[] = {73"nullObject",74"baseObject",75"derivedObject",76"stringObject",77"primitiveArrayObject",78"objectArrayObject",79"threadObject",80"threadGroupObject",81"classObject",82"classLoaderObject",83};84static final byte FIELD_TAGS[] = {85JDWP.Tag.OBJECT, // nullObject86JDWP.Tag.OBJECT, // baseobject87JDWP.Tag.OBJECT, // derivedObject88JDWP.Tag.STRING, // stringObject89JDWP.Tag.ARRAY, // primitiveArrayObject90JDWP.Tag.ARRAY, // objectArrayObject91JDWP.Tag.THREAD, // threadObject92JDWP.Tag.THREAD_GROUP, // threadGroupObject93JDWP.Tag.CLASS_OBJECT, // classObject94JDWP.Tag.CLASS_LOADER // classLoaderObject95};9697// first index and number of array components to get98static final int ARRAY_FIRST_INDEX = getvalues002a.ARRAY_FIRST_INDEX;99static final int ARRAY_ITEMS_COUNT = FIELDS_COUNT;100101// usual scaffold objects102ArgumentHandler argumentHandler = null;103Log log = null;104Binder binder = null;105Debugee debugee = null;106Transport transport = null;107IOPipe pipe = null;108109// test passed or not110boolean success = true;111112// -------------------------------------------------------------------113114/**115* Start test from command line.116*/117public static void main (String argv[]) {118System.exit(run(argv,System.out) + JCK_STATUS_BASE);119}120121/**122* Start JCK-compilant test.123*/124public static int run(String argv[], PrintStream out) {125return new getvalues002().runIt(argv, out);126}127128// -------------------------------------------------------------------129130/**131* Perform test execution.132*/133public int runIt(String argv[], PrintStream out) {134135// make log for debugger messages136argumentHandler = new ArgumentHandler(argv);137log = new Log(out, argumentHandler);138139// execute test and display results140try {141log.display("\n>>> Preparing debugee for testing \n");142143// launch debugee144binder = new Binder(argumentHandler, log);145log.display("Launching debugee");146debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);147transport = debugee.getTransport();148pipe = debugee.createIOPipe();149150// make debuggee ready for testing151prepareDebugee();152153// work with prepared debugee154try {155log.display("\n>>> Obtaining requred data from debugee \n");156157// query debugee for TypeID of tested class158log.display("Getting ReferenceTypeID by signature:\n"159+ " " + TESTED_CLASS_SIGNATURE);160long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);161log.display(" got classID: " + classID);162163// query debugee for fieldIDs of the class static fields164log.display("Getting fieldIDs for static fields of the class");165long fieldIDs[] = queryClassFieldIDs(classID);166log.display(" got fields: " + fieldIDs.length);167168// query debugee for object values of the fields169log.display("Getting objectID values of the static fields");170long objectIDs[] = queryClassFieldValues(classID, fieldIDs);171log.display(" got objectIDs: " + objectIDs.length);172173// query debuggee for arrayID value from static field174log.display("Getting arrayID value from static field: "175+ ARRAY_FIELD_NAME);176long arrayID = queryObjectID(classID,177ARRAY_FIELD_NAME, JDWP.Tag.ARRAY);178log.display(" got arrayID: " + arrayID);179180// perform testing JDWP command181log.display("\n>>> Testing JDWP command \n");182testCommand(arrayID, objectIDs);183184} finally {185// quit debugee186log.display("\n>>> Finishing test \n");187quitDebugee();188}189190} catch (Failure e) {191log.complain("TEST FAILED: " + e.getMessage());192e.printStackTrace(out);193success = false;194} catch (Exception e) {195log.complain("Caught unexpected exception:\n" + e);196e.printStackTrace(out);197success = false;198}199200if (!success) {201log.complain("TEST FAILED");202return FAILED;203}204205out.println("TEST PASSED");206return PASSED;207208}209210/**211* Prepare debugee for testing and waiting for ready signal.212*/213void prepareDebugee() {214// wait for VM_INIT event from debugee215log.display("Waiting for VM_INIT event");216debugee.waitForVMInit();217218// query debugee for VM-dependent ID sizes219log.display("Querying for IDSizes");220debugee.queryForIDSizes();221222// resume initially suspended debugee223log.display("Resuming debugee VM");224debugee.resume();225226// wait for READY signal from debugee227log.display("Waiting for signal from debugee: " + READY);228String signal = pipe.readln();229log.display("Received signal from debugee: " + signal);230if (! signal.equals(READY)) {231throw new TestBug("Unexpected signal received form debugee: " + signal232+ " (expected: " + READY + ")");233}234}235236/**237* Sending debugee signal to quit and waiting for it exits.238*/239void quitDebugee() {240// send debugee signal to quit241log.display("Sending signal to debugee: " + QUIT);242pipe.println(QUIT);243244// wait for debugee exits245log.display("Waiting for debugee exits");246int code = debugee.waitFor();247248// analize debugee exit status code249if (code == JCK_STATUS_BASE + PASSED) {250log.display("Debugee PASSED with exit code: " + code);251} else {252log.complain("Debugee FAILED with exit code: " + code);253success = false;254}255}256257/**258* Query debugee for fieldID's of the class static fields.259*/260long[] queryClassFieldIDs(long classID) {261262long[] fieldIDs = new long[FIELDS_COUNT];263for (int i = 0; i < FIELDS_COUNT; i++) {264fieldIDs[i] = 0;265}266267// compose ReferenceType.Fields command packet268CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.Fields);269command.addReferenceTypeID(classID);270command.setLength();271272// send the command and receive reply273ReplyPacket reply = debugee.receiveReplyFor(command);274275// extract fieldIDs from the reply packet276try {277reply.resetPosition();278279int declared = reply.getInt();280281for (int i = 0; i < declared; i++ ) {282long fieldID = reply.getFieldID();283String name = reply.getString();284String signature = reply.getString();285int modBits = reply.getInt();286287for (int j = 0; j < FIELDS_COUNT; j++) {288if (FIELD_NAMES[j].equals(name)) {289fieldIDs[j] = fieldID;290}291}292}293294for (int i = 0; i < FIELDS_COUNT; i++) {295if (fieldIDs[i] == 0) {296log.complain("Not found fieldID for static field: " + FIELD_NAMES[i]);297throw new Failure("Error occured while getting static fieldIDs for classID: "298+ classID);299}300}301302} catch (BoundException e) {303log.complain("Unable to parse reply packet for ReferenceType.Fields command:\n\t"304+ e);305log.complain("Received reply packet:\n"306+ reply);307throw new Failure("Error occured while getting static fieldIDs for classID: " + classID);308}309310return fieldIDs;311}312313/**314* Query debugee for objectID values of the class fields.315*/316long[] queryClassFieldValues(long classID, long fieldIDs[]) {317String error = "Error occured while getting object values for static fields of classID: "318+ classID;319320// compose ReferenceType.Fields command packet321CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.GetValues);322command.addReferenceTypeID(classID);323command.addInt(FIELDS_COUNT);324for (int i = 0; i < FIELDS_COUNT; i++) {325command.addFieldID(fieldIDs[i]);326}327command.setLength();328329// send the command and receive reply330ReplyPacket reply = debugee.receiveReplyFor(command);331332// extract values from the reply packet333try {334reply.resetPosition();335336int valuesCount = reply.getInt();337if (valuesCount != FIELDS_COUNT) {338log.complain("Unexpected number of values for static fields: " + valuesCount339+ " (expected: " + FIELDS_COUNT + ")");340throw new Failure(error);341}342343long objectIDs[] = new long[valuesCount];344for (int i = 0; i < valuesCount; i++ ) {345JDWP.Value value = reply.getValue();346byte tag = value.getTag();347if (tag != FIELD_TAGS[i]) {348log.complain("Unexpected tag of oblectID value for static field "349+ FIELD_NAMES[i] + ": " + tag350+ " (expected: " + FIELD_TAGS[i] + ")");351throw new Failure(error);352}353long objectID = ((Long)value.getValue()).longValue();354objectIDs[i] = objectID;355}356return objectIDs;357} catch (BoundException e) {358log.complain("Unable to parse reply packet for ReferenceType.GetValues command:\n\t"359+ e);360log.complain("Received reply packet:\n"361+ reply);362throw new Failure("Error occured while getting static fields values for classID: " + classID);363}364}365366/**367* Query debuggee for objectID value of static class field.368*/369long queryObjectID(long classID, String fieldName, byte tag) {370// get fieledID for static field (declared in the class)371long fieldID = debugee.getClassFieldID(classID, fieldName, true);372// get value of the field373JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);374375// check that value has THREAD tag376if (value.getTag() != tag) {377throw new Failure("Wrong objectID tag received from field \"" + fieldName378+ "\": " + value.getTag() + " (expected: " + tag + ")");379}380381// extract threadID from the value382long objectID = ((Long)value.getValue()).longValue();383return objectID;384}385386/**387* Perform testing JDWP command for specified objectID.388*/389void testCommand(long arrayID, long objectIDs[]) {390// create command packet391log.display("Create command packet:");392log.display("Command: " + JDWP_COMMAND_NAME);393CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);394395// add out data to the command packet396log.display(" arrayID: " + arrayID);397command.addObjectID(arrayID);398log.display(" firstIndex: " + ARRAY_FIRST_INDEX);399command.addInt(ARRAY_FIRST_INDEX);400log.display(" length: " + ARRAY_ITEMS_COUNT);401command.addInt(ARRAY_ITEMS_COUNT);402command.setLength();403404// send command packet to debugee405try {406log.display("Sending command packet:\n" + command);407transport.write(command);408} catch (IOException e) {409log.complain("Unable to send command packet:\n" + e);410success = false;411return;412}413414ReplyPacket reply = new ReplyPacket();415416// receive reply packet from debugee417try {418log.display("Waiting for reply packet");419transport.read(reply);420log.display("Reply packet received:\n" + reply);421} catch (IOException e) {422log.complain("Unable to read reply packet:\n" + e);423success = false;424return;425}426427// check reply packet header428try{429log.display("Checking reply packet header");430reply.checkHeader(command.getPacketID());431} catch (BoundException e) {432log.complain("Bad header of reply packet: " + e.getMessage());433success = false;434}435436// start parsing reply packet data437log.display("Parsing reply packet:");438reply.resetPosition();439440// extract values tag441byte tag = (byte)0;442try {443tag = reply.getByte();444log.display(" tag: " + tag);445446} catch (BoundException e) {447log.complain("Unable to extract values tag from reply packet:\n\t"448+ e.getMessage());449success = false;450}451452// check if number of values are as expected453if (tag != JDWP.Tag.OBJECT) {454log.complain("Unexpected values tag received:" + tag455+ " (expected: " + JDWP.Tag.OBJECT + ")");456success = false;457}458459// extract number of values460int values = 0;461try {462values = reply.getInt();463log.display(" values: " + values);464465} catch (BoundException e) {466log.complain("Unable to extract number of values from reply packet:\n\t"467+ e.getMessage());468success = false;469}470471// check if number of values are as expected472if (values < 0) {473log.complain("Negative number of values received:" + values474+ " (expected: " + ARRAY_ITEMS_COUNT + ")");475success = false;476} else if (values != ARRAY_ITEMS_COUNT) {477log.complain("Unexpected number of values received:" + values478+ " (expected: " + ARRAY_ITEMS_COUNT + ")");479success = false;480}481482// extract and check each value483for (int i = 0; i < values; i++ ) {484int index = i + ARRAY_FIRST_INDEX;485log.display(" value #" + i + " (index: " + index + ")");486487// extract value488JDWP.Value value = null;489try {490value = reply.getValue();491log.display(" value: " + value);492} catch (BoundException e) {493log.complain("Unable to extract " + i + " value from reply packet:\n\t"494+ e.getMessage());495success = false;496break;497}498499// check that value's tag is as expected500byte valueTag = value.getTag();501if (valueTag != FIELD_TAGS[i]) {502log.complain("Unexpected value tag for " + index + " component ("503+ FIELD_NAMES[i] + ") received: " + valueTag504+ " (expected: " + FIELD_TAGS[i] + ")");505success = false;506}507508// check that value's objectID is as expected509long objectID = ((Long)value.getValue()).longValue();510if (objectID != objectIDs[i]) {511log.complain("Unexpected objectID for " + index + " component ("512+ FIELD_NAMES[i] + ") received: " + objectID513+ " (expected: " + objectIDs[i] + ")");514success = false;515}516}517518// check for extra data in reply packet519if (! reply.isParsed()) {520log.complain("Extra trailing bytes found in reply packet at: "521+ "0x" + reply.toHexString(reply.currentDataPosition(), 4));522success = false;523}524}525526}527528529