Home | History | Annotate | Download | only in share
      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 29.01.2005
     25  */
     26 package org.apache.harmony.jpda.tests.jdwp.share;
     27 
     28 import org.apache.harmony.jpda.tests.framework.TestErrorException;
     29 import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
     30 import org.apache.harmony.jpda.tests.framework.jdwp.EventPacket;
     31 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
     32 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
     33 import org.apache.harmony.jpda.tests.framework.jdwp.Packet;
     34 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
     35 
     36 /**
     37  * Basic class for unit tests which use only one debuggee VM.
     38  */
     39 public abstract class JDWPTestCase extends JDWPRawTestCase {
     40 
     41     /**
     42      * DebuggeeWrapper instance for launched debuggee VM.
     43      */
     44     protected JDWPUnitDebuggeeWrapper debuggeeWrapper;
     45 
     46     /**
     47      * EventPacket instance with received VM_START event.
     48      */
     49     protected EventPacket initialEvent = null;
     50 
     51     /**
     52      * Overrides inherited method to launch one debuggee VM, establish JDWP
     53      * connection, and wait for VM_START event.
     54      */
     55     protected void internalSetUp() throws Exception {
     56         super.internalSetUp();
     57 
     58         // launch debuggee process
     59         debuggeeWrapper = createDebuggeeWrapper();
     60         beforeDebuggeeStart(debuggeeWrapper);
     61         startDebuggeeWrapper();
     62 
     63         // receive and handle initial event
     64         receiveInitialEvent();
     65 
     66         // adjust JDWP types length
     67         debuggeeWrapper.vmMirror.adjustTypeLength();
     68         logWriter.println("Adjusted VM-dependent type lengths");
     69     }
     70 
     71     /**
     72      * Creates wrapper for debuggee process.
     73      */
     74     protected JDWPUnitDebuggeeWrapper createDebuggeeWrapper() {
     75         if (settings.getDebuggeeLaunchKind().equals("manual")) {
     76             return new JDWPManualDebuggeeWrapper(settings, logWriter);
     77         } else {
     78             return new JDWPUnitDebuggeeWrapper(settings, logWriter);
     79         }
     80     }
     81 
     82     /**
     83      * Starts wrapper for debuggee process.
     84      */
     85     protected void startDebuggeeWrapper() {
     86     	debuggeeWrapper.start();
     87         logWriter.println("Established JDWP connection with debuggee VM");
     88     }
     89 
     90     /**
     91      * Receives initial VM_INIT event if debuggee is suspended on event.
     92      */
     93     protected void receiveInitialEvent() {
     94         if (settings.isDebuggeeSuspend()) {
     95             initialEvent =
     96                 debuggeeWrapper.vmMirror.receiveCertainEvent(JDWPConstants.EventKind.VM_INIT);
     97             logWriter.println("Received inital VM_INIT event");
     98         }
     99     }
    100 
    101     /**
    102      * Overrides inherited method to stop started debuggee VM and close all
    103      * connections.
    104      */
    105     protected void internalTearDown() {
    106         if (debuggeeWrapper != null) {
    107             debuggeeWrapper.stop();
    108             logWriter.println("Closed JDWP connection with debuggee VM");
    109         }
    110         super.internalTearDown();
    111     }
    112 
    113     /**
    114      * This method is invoked right before starting debuggee VM.
    115      */
    116     protected void beforeDebuggeeStart(JDWPUnitDebuggeeWrapper debuggeeWrapper) {
    117 
    118     }
    119 
    120     /**
    121      * Opens JDWP connection with debuggee (doesn't run debuggee and doesn't
    122      * establish synchronize connection).
    123      */
    124     public void openConnection() {
    125         debuggeeWrapper.openConnection();
    126         logWriter.println("Opened transport connection");
    127         debuggeeWrapper.vmMirror.adjustTypeLength();
    128         logWriter.println("Adjusted VM-dependent type lengths");
    129     }
    130 
    131     /**
    132      * Closes JDWP connection with debuggee (doesn't terminate debuggee and
    133      * doesn't stop synchronize connection).
    134      */
    135     public void closeConnection() {
    136         if (debuggeeWrapper != null) {
    137             debuggeeWrapper.disposeConnection();
    138             try {
    139                 debuggeeWrapper.vmMirror.closeConnection();
    140             } catch (Exception e) {
    141                 throw new TestErrorException(e);
    142             }
    143             logWriter.println("Closed transport connection");
    144         }
    145     }
    146 
    147     /**
    148      * Helper that returns reference type signature of input object ID.
    149      *
    150      * @param objectID -
    151      *            debuggee object ID
    152      * @return object signature of reference type
    153      */
    154     protected String getObjectSignature(long objectID) {
    155         long classID = getObjectReferenceType(objectID);
    156         return getClassSignature(classID);
    157     }
    158 
    159     /**
    160      * Helper that returns reference type ID for input object ID.
    161      *
    162      * @param objectID -
    163      *            debuggee object ID
    164      * @return reference type ID
    165      */
    166     protected long getObjectReferenceType(long objectID) {
    167         CommandPacket command = new CommandPacket(
    168                 JDWPCommands.ObjectReferenceCommandSet.CommandSetID,
    169                 JDWPCommands.ObjectReferenceCommandSet.ReferenceTypeCommand);
    170         command.setNextValueAsReferenceTypeID(objectID);
    171         ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(command);
    172         checkReplyPacket(reply, "ObjectReference::ReferenceType command");
    173         // byte refTypeTag =
    174         reply.getNextValueAsByte();
    175         long objectRefTypeID = reply.getNextValueAsReferenceTypeID();
    176         return objectRefTypeID;
    177     }
    178 
    179     /**
    180      * Helper for getting method ID of corresponding class and method name.
    181      *
    182      * @param classID -
    183      *            class ID
    184      * @param methodName -
    185      *            method name
    186      * @return method ID
    187      */
    188     protected long getMethodID(long classID, String methodName) {
    189         CommandPacket command = new CommandPacket(
    190                 JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
    191                 JDWPCommands.ReferenceTypeCommandSet.MethodsCommand);
    192         command.setNextValueAsClassID(classID);
    193         ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(command);
    194         checkReplyPacket(reply, "ReferenceType::Methods command");
    195         int methods = reply.getNextValueAsInt();
    196         for (int i = 0; i < methods; i++) {
    197             long methodID = reply.getNextValueAsMethodID();
    198             String name = reply.getNextValueAsString(); // method name
    199             reply.getNextValueAsString(); // method signature
    200             reply.getNextValueAsInt(); // method modifiers
    201             if (name.equals(methodName)) {
    202                 return methodID;
    203             }
    204         }
    205         return -1;
    206     }
    207 
    208     /**
    209      * Issues LineTable command.
    210      *
    211      * @param classID -
    212      *            class ID
    213      * @param methodID -
    214      *            method ID
    215      * @return reply packet
    216      */
    217     protected ReplyPacket getLineTable(long classID, long methodID) {
    218         CommandPacket lineTableCommand = new CommandPacket(
    219                 JDWPCommands.MethodCommandSet.CommandSetID,
    220                 JDWPCommands.MethodCommandSet.LineTableCommand);
    221         lineTableCommand.setNextValueAsReferenceTypeID(classID);
    222         lineTableCommand.setNextValueAsMethodID(methodID);
    223         ReplyPacket lineTableReply = debuggeeWrapper.vmMirror
    224                 .performCommand(lineTableCommand);
    225         checkReplyPacket(lineTableReply, "Method::LineTable command");
    226         return lineTableReply;
    227     }
    228 
    229     /**
    230      * Helper for getting method name of corresponding class and method ID.
    231      *
    232      * @param classID class id
    233      * @param methodID method id
    234      * @return String
    235      */
    236     protected String getMethodName(long classID, long methodID) {
    237         CommandPacket packet = new CommandPacket(
    238                 JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
    239                 JDWPCommands.ReferenceTypeCommandSet.MethodsCommand);
    240         packet.setNextValueAsClassID(classID);
    241         ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
    242         checkReplyPacket(reply, "ReferenceType::Methods command");
    243         int methods = reply.getNextValueAsInt();
    244         for (int i = 0; i < methods; i++) {
    245             long mid = reply.getNextValueAsMethodID();
    246             String name = reply.getNextValueAsString();
    247             reply.getNextValueAsString();
    248             reply.getNextValueAsInt();
    249             if (mid == methodID) {
    250                 return name;
    251             }
    252         }
    253         return "unknown";
    254     }
    255 
    256     /**
    257      * Returns jni signature for selected classID
    258      *
    259      * @param classID
    260      * @return jni signature for selected classID
    261      */
    262     protected String getClassSignature(long classID) {
    263         CommandPacket command = new CommandPacket(
    264                 JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
    265                 JDWPCommands.ReferenceTypeCommandSet.SignatureCommand);
    266         command.setNextValueAsReferenceTypeID(classID);
    267         ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(command);
    268         checkReplyPacket(reply, "ReferenceType::Signature command");
    269         String signature = reply.getNextValueAsString();
    270         return signature;
    271     }
    272 
    273     /**
    274      * Returns classID for the selected jni signature
    275      *
    276      * @param signature
    277      * @return classID for the selected jni signature
    278      */
    279     protected long getClassIDBySignature(String signature) {
    280         logWriter.println("=> Getting reference type ID for class: "
    281                 + signature);
    282         CommandPacket packet = new CommandPacket(
    283                 JDWPCommands.VirtualMachineCommandSet.CommandSetID,
    284                 JDWPCommands.VirtualMachineCommandSet.ClassesBySignatureCommand);
    285         packet.setNextValueAsString(signature);
    286         ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
    287         checkReplyPacket(reply, "VirtualMachine::ClassesBySignature command");
    288         int classes = reply.getNextValueAsInt();
    289         logWriter.println("=> Returned number of classes: " + classes);
    290         long classID = 0;
    291         for (int i = 0; i < classes; i++) {
    292             reply.getNextValueAsByte();
    293             classID = reply.getNextValueAsReferenceTypeID();
    294             reply.getNextValueAsInt();
    295             // we need the only class, even if there were multiply ones
    296             break;
    297         }
    298         assertTrue(
    299                 "VirtualMachine::ClassesBySignature command returned invalid classID:<"
    300                         + classID + "> for signature " + signature, classID > 0);
    301         return classID;
    302     }
    303 
    304     /**
    305      * Returns reference type ID.
    306      *
    307      * @param signature
    308      * @return type ID for the selected jni signature
    309      */
    310     protected long getReferenceTypeID(String signature) {
    311         CommandPacket packet = new CommandPacket(
    312                 JDWPCommands.VirtualMachineCommandSet.CommandSetID,
    313                 JDWPCommands.VirtualMachineCommandSet.ClassesBySignatureCommand);
    314         packet.setNextValueAsString(signature);
    315         ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
    316         checkReplyPacket(reply, "VirtualMachine::ClassesBySignature command");
    317         int classes = reply.getNextValueAsInt();
    318         // this class may be loaded only once
    319         assertEquals("Invalid number of classes for reference type: "
    320                 + signature + ",", 1, classes);
    321         byte refTypeTag = reply.getNextValueAsByte();
    322         long classID = reply.getNextValueAsReferenceTypeID();
    323         int status = reply.getNextValueAsInt();
    324         logWriter.println("VirtualMachine.ClassesBySignature: classes="
    325                 + classes + " refTypeTag=" + refTypeTag + " typeID= " + classID
    326                 + " status=" + status);
    327         assertAllDataRead(reply);
    328         assertEquals("", JDWPConstants.TypeTag.CLASS, refTypeTag);
    329         return classID;
    330     }
    331 
    332     /**
    333      * Helper function for resuming debuggee.
    334      */
    335     protected void resumeDebuggee() {
    336         logWriter.println("=> Resume debuggee");
    337         CommandPacket packet = new CommandPacket(
    338                 JDWPCommands.VirtualMachineCommandSet.CommandSetID,
    339                 JDWPCommands.VirtualMachineCommandSet.ResumeCommand);
    340         logWriter.println("Sending VirtualMachine::Resume command...");
    341         ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
    342         checkReplyPacket(reply, "VirtualMachine::Resume command");
    343         assertAllDataRead(reply);
    344     }
    345 
    346     /**
    347      * Performs string creation in debuggee.
    348      *
    349      * @param value -
    350      *            content for new string
    351      * @return StringID of new created string
    352      */
    353     protected long createString(String value) {
    354         CommandPacket packet = new CommandPacket(
    355                 JDWPCommands.VirtualMachineCommandSet.CommandSetID,
    356                 JDWPCommands.VirtualMachineCommandSet.CreateStringCommand);
    357         packet.setNextValueAsString(value);
    358         ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
    359         checkReplyPacket(reply, "VirtualMachine::CreateString command");
    360         long stringID = reply.getNextValueAsStringID();
    361         return stringID;
    362     }
    363 
    364     /**
    365      * Returns corresponding string from string ID.
    366      *
    367      * @param stringID -
    368      *            string ID
    369      * @return string value
    370      */
    371     protected String getStringValue(long stringID) {
    372         CommandPacket packet = new CommandPacket(
    373                 JDWPCommands.StringReferenceCommandSet.CommandSetID,
    374                 JDWPCommands.StringReferenceCommandSet.ValueCommand);
    375         packet.setNextValueAsObjectID(stringID);
    376         ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
    377         checkReplyPacket(reply, "StringReference::Value command");
    378         String returnedTestString = reply.getNextValueAsString();
    379         return returnedTestString;
    380     }
    381 
    382     /**
    383      * Multiple field verification routine.
    384      *
    385      * @param refTypeID -
    386      *            reference type ID
    387      * @param checkedFieldNames -
    388      *            list of field names to be checked
    389      * @return list of field IDs
    390      */
    391     protected long[] checkFields(long refTypeID, String checkedFieldNames[]) {
    392         return checkFields(refTypeID, checkedFieldNames, null, null);
    393     }
    394 
    395     /**
    396      * Single field verification routine.
    397      *
    398      * @param refTypeID -
    399      *            reference type ID
    400      * @param fieldName -
    401      *            name of single field
    402      * @return filed ID
    403      */
    404     protected long checkField(long refTypeID, String fieldName) {
    405         return checkFields(refTypeID, new String[] { fieldName }, null, null)[0];
    406     }
    407 
    408     /**
    409      * Multiple field verification routine.
    410      *
    411      * @param refTypeID -
    412      *            reference type ID
    413      * @param checkedFieldNames -
    414      *            list of field names to be checked
    415      * @param expectedSignatures -
    416      *            list of expected field signatures
    417      * @param expectedModifiers -
    418      *            list of expected field modifiers
    419      * @return list of field IDs
    420      */
    421     protected long[] checkFields(long refTypeID, String checkedFieldNames[],
    422             String expectedSignatures[], int expectedModifiers[]) {
    423 
    424         boolean checkedFieldFound[] = new boolean[checkedFieldNames.length];
    425         long checkedFieldIDs[] = new long[checkedFieldNames.length];
    426 
    427         logWriter
    428                 .println("=> Send ReferenceType::Fields command and get field ID(s)");
    429 
    430         CommandPacket fieldsCommand = new CommandPacket(
    431                 JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
    432                 JDWPCommands.ReferenceTypeCommandSet.FieldsCommand);
    433         fieldsCommand.setNextValueAsReferenceTypeID(refTypeID);
    434         ReplyPacket fieldsReply = debuggeeWrapper.vmMirror
    435                 .performCommand(fieldsCommand);
    436         fieldsCommand = null;
    437         checkReplyPacket(fieldsReply, "ReferenceType::Fields command");
    438 
    439         int returnedFieldsNumber = fieldsReply.getNextValueAsInt();
    440         logWriter
    441                 .println("=> Returned fields number = " + returnedFieldsNumber);
    442 
    443         int checkedFieldsNumber = checkedFieldNames.length;
    444         final int fieldSyntheticFlag = 0xf0000000;
    445 
    446         int nameDuplicated = 0;
    447         String fieldNameDuplicated = null; // <= collects all duplicated fields
    448         int nameMissing = 0;
    449         String fieldNameMissing = null; // <= collects all missed fields
    450 
    451         for (int i = 0; i < returnedFieldsNumber; i++) {
    452             long returnedFieldID = fieldsReply.getNextValueAsFieldID();
    453             String returnedFieldName = fieldsReply.getNextValueAsString();
    454             String returnedFieldSignature = fieldsReply.getNextValueAsString();
    455             int returnedFieldModifiers = fieldsReply.getNextValueAsInt();
    456             logWriter.println("");
    457             logWriter.println("=> Field ID: " + returnedFieldID);
    458             logWriter.println("=> Field name: " + returnedFieldName);
    459             logWriter.println("=> Field signature: " + returnedFieldSignature);
    460             logWriter.println("=> Field modifiers: 0x"
    461                     + Integer.toHexString(returnedFieldModifiers));
    462             if ((returnedFieldModifiers & fieldSyntheticFlag) == fieldSyntheticFlag) {
    463                 continue; // do not check synthetic fields
    464             }
    465             for (int k = 0; k < checkedFieldsNumber; k++) {
    466                 if (!checkedFieldNames[k].equals(returnedFieldName)) {
    467                     continue;
    468                 }
    469                 if (checkedFieldFound[k]) {
    470                     logWriter.println("");
    471                     logWriter
    472                             .println("## FAILURE: The field is found repeatedly in the list");
    473                     logWriter.println("## Field Name: " + returnedFieldName);
    474                     logWriter.println("## Field ID: " + returnedFieldID);
    475                     logWriter.println("## Field Signature: "
    476                             + returnedFieldSignature);
    477                     logWriter.println("## Field Modifiers: 0x"
    478                             + Integer.toHexString(returnedFieldModifiers));
    479                     fieldNameDuplicated = (0 == nameDuplicated ? returnedFieldName
    480                             : fieldNameDuplicated + "," + returnedFieldName);
    481                     nameDuplicated++;
    482                     break;
    483                 }
    484                 checkedFieldFound[k] = true;
    485                 checkedFieldIDs[k] = returnedFieldID;
    486                 if (null != expectedSignatures) {
    487                     assertString(
    488                             "Invalid field signature is returned for field:"
    489                                     + returnedFieldName + ",",
    490                             expectedSignatures[k], returnedFieldSignature);
    491                 }
    492                 if (null != expectedModifiers) {
    493                     assertEquals(
    494                             "Invalid field modifiers are returned for field:"
    495                                     + returnedFieldName + ",",
    496                             expectedModifiers[k], returnedFieldModifiers);
    497                 }
    498                 break;
    499             }
    500         }
    501 
    502         for (int k = 0; k < checkedFieldsNumber; k++) {
    503             if (!checkedFieldFound[k]) {
    504                 logWriter.println("");
    505                 logWriter
    506                         .println("\n## FAILURE: Expected field is NOT found in the list of retuned fields:");
    507                 logWriter.println("## Field name = " + checkedFieldNames[k]);
    508                 fieldNameMissing = 0 == nameMissing ? checkedFieldNames[k]
    509                         : fieldNameMissing + "," + checkedFieldNames[k];
    510                 nameMissing++;
    511                 // break;
    512             }
    513         }
    514 
    515         // String thisTestName = this.getClass().getName();
    516         // logWriter.println("==> " + thisTestName + " for " + thisCommandName +
    517         // ": FAILED");
    518 
    519         if (nameDuplicated > 1) {
    520             fail("Duplicated fields are found in the retuned by FieldsCommand list: "
    521                     + fieldNameDuplicated);
    522         }
    523         if (nameDuplicated > 0) {
    524             fail("Duplicated field is found in the retuned by FieldsCommand list: "
    525                     + fieldNameDuplicated);
    526         }
    527         if (nameMissing > 1) {
    528             fail("Expected fields are NOT found in the retuned by FieldsCommand list: "
    529                     + fieldNameMissing);
    530         }
    531         if (nameMissing > 0) {
    532             fail("Expected field is NOT found in the retuned by FieldsCommand list: "
    533                     + fieldNameMissing);
    534         }
    535 
    536         logWriter.println("");
    537         if (1 == checkedFieldsNumber) {
    538             logWriter
    539                     .println("=> Expected field was found and field ID was got");
    540         } else {
    541             logWriter
    542                     .println("=> Expected fields were found and field IDs were got");
    543         }
    544 
    545         assertAllDataRead(fieldsReply);
    546         return checkedFieldIDs;
    547     }
    548 
    549     /**
    550      * Helper for checking reply packet error code. Calls junit fail if packet
    551      * error code does not equal to expected error code.
    552      *
    553      * @param reply -
    554      *            returned from debuggee packet
    555      * @param message -
    556      *            additional message
    557      * @param errorCodeExpected -
    558      *            array of expected error codes
    559      */
    560     protected void checkReplyPacket(ReplyPacket reply, String message,
    561             int errorCodeExpected) {
    562         checkReplyPacket(reply, message, new int[] { errorCodeExpected });
    563     }
    564 
    565     /**
    566      * Helper for checking reply packet error code. Calls junit fail if packet
    567      * error code does not equal NONE.
    568      *
    569      * @param reply -
    570      *            returned from debuggee packet
    571      * @param message -
    572      *            additional message
    573      */
    574     protected void checkReplyPacket(ReplyPacket reply, String message) {
    575         checkReplyPacket(reply, message, JDWPConstants.Error.NONE);
    576     }
    577 
    578     /**
    579      * Helper for checking reply packet error code. Calls junit fail if packet
    580      * error code does not equal to expected error code.
    581      *
    582      * @param reply -
    583      *            returned from debuggee packet
    584      * @param message -
    585      *            additional message
    586      * @param expected -
    587      *            array of expected error codes
    588      */
    589     protected void checkReplyPacket(ReplyPacket reply, String message,
    590             int[] expected) {
    591         checkReplyPacket(reply, message, expected, true /* failSign */);
    592     }
    593 
    594     /**
    595      * Helper for checking reply packet error code. If reply packet does not
    596      * have error - returns true. Otherwise does not call junit fail - simply
    597      * prints error message and returns false. if packet error code does not
    598      * equal NONE.
    599      *
    600      * @param reply -
    601      *            returned from debuggee packet
    602      * @param message -
    603      *            additional message
    604      * @return true if error is not found, or false otherwise
    605      */
    606     protected boolean checkReplyPacketWithoutFail(ReplyPacket reply,
    607             String message) {
    608         return checkReplyPacket(reply, message,
    609                 new int[] { JDWPConstants.Error.NONE }, false /* failSign */);
    610     }
    611 
    612     /**
    613      * Helper for checking reply packet error code. If reply packet does not
    614      * have unexpected error - returns true. If reply packet has got unexpected
    615      * error: If failSign param = true - calls junit fail. Otherwise prints
    616      * message about error and returns false.
    617      *
    618      * @param reply -
    619      *            returned from debuggee packet
    620      * @param message -
    621      *            additional message
    622      * @param expected -
    623      *            array of expected error codes
    624      * @param failSign -
    625      *            defines to call junit fail or not
    626      * @return true if unexpected errors are not found, or false otherwise
    627      */
    628     protected boolean checkReplyPacket(ReplyPacket reply, String message,
    629             int[] expected, boolean failSign) {
    630         // check reply code against expected
    631         int errorCode = reply.getErrorCode();
    632         for (int i = 0; i < expected.length; i++) {
    633             if (reply.getErrorCode() == expected[i]) {
    634                 return true; // OK
    635             }
    636         }
    637 
    638         // replay code validation failed
    639         // start error message composition
    640         if (null == message) {
    641             message = "";
    642         } else {
    643             message = message + ", ";
    644         }
    645 
    646         // format error message
    647         if (expected.length == 1 && JDWPConstants.Error.NONE == expected[0]) {
    648             message = message + "Error Code:<" + errorCode + "("
    649                     + JDWPConstants.Error.getName(errorCode) + ")>";
    650         } else {
    651             message = message + "Unexpected error code:<" + errorCode + "("
    652                     + JDWPConstants.Error.getName(errorCode) + ")>"
    653                     + ", Expected error code"
    654                     + (expected.length == 1 ? ":" : "s:");
    655             for (int i = 0; i < expected.length; i++) {
    656                 message = message + (i > 0 ? ",<" : "<") + expected[i] + "("
    657                         + JDWPConstants.Error.getName(expected[i]) + ")>";
    658             }
    659         }
    660 
    661         if (failSign) {
    662             printErrorAndFail(message);
    663         }
    664         logWriter.printError(message);
    665         return false;
    666     }
    667 
    668     /**
    669      * Helper for comparison numbers and printing string equivalents.
    670      *
    671      * @param message -
    672      *            user message
    673      * @param expected -
    674      *            expected value
    675      * @param actual -
    676      *            actual value
    677      * @param strExpected -
    678      *            string equivalent of expected value
    679      * @param strActual -
    680      *            string equivalent of actual value
    681      */
    682     protected void assertEquals(String message, long expected, long actual,
    683             String strExpected, String strActual) {
    684         if (expected == actual) {
    685             return; // OK
    686         }
    687 
    688         if (null == message) {
    689             message = "";
    690         }
    691 
    692         if (null == strExpected) {
    693             strExpected = expected + "";
    694         } else {
    695             strExpected = expected + "(" + strExpected + ")";
    696         }
    697 
    698         if (null == strActual) {
    699             strActual = actual + "";
    700         } else {
    701             strActual = actual + "(" + strActual + ")";
    702         }
    703 
    704         printErrorAndFail(message + " expected:<" + strExpected + "> but was:<"
    705                 + strActual + ">");
    706     }
    707 
    708     /**
    709      * Asserts that two strings are equal.
    710      *
    711      * @param message -
    712      *            user message
    713      * @param expected -
    714      *            expected string
    715      * @param actual -
    716      *            actual string
    717      */
    718     protected void assertString(String message, String expected, String actual) {
    719         if (null == expected) {
    720             expected = "";
    721         }
    722         if (null == actual) {
    723             actual = "";
    724         }
    725         if (expected.equals(actual)) {
    726             return; // OK
    727         }
    728         printErrorAndFail(message + " expected:<" + expected + "> but was:<"
    729                 + actual + ">");
    730     }
    731 
    732     /**
    733      * Helper for checking reply packet data has been read.
    734      *
    735      * @param reply -
    736      *            reply packet from debuggee
    737      */
    738     protected void assertAllDataRead(Packet reply) {
    739         if (reply.isAllDataRead()) {
    740             return; // OK
    741         }
    742         printErrorAndFail("Not all data has been read");
    743     }
    744 
    745     /**
    746      * Prints error message in log writer and in junit fail.
    747      *
    748      * @param message -
    749      *            error message
    750      */
    751     protected void printErrorAndFail(String message) {
    752         logWriter.printError(message);
    753         fail(message);
    754     }
    755 
    756     /**
    757      * Helper for setting static int field in class with new value.
    758      *
    759      * @param classSignature -
    760      *            String defining signature of class
    761      * @param fieldName -
    762      *            String defining field name in specified class
    763      * @param newValue -
    764      *            int value to set for specified field
    765      * @return true, if setting is successfully, or false otherwise
    766      */
    767     protected boolean setStaticIntField(String classSignature,
    768             String fieldName, int newValue) {
    769 
    770         long classID = debuggeeWrapper.vmMirror.getClassID(classSignature);
    771         if (classID == -1) {
    772             logWriter
    773                     .println("## setStaticIntField(): Can NOT get classID for class signature = '"
    774                             + classSignature + "'");
    775             return false;
    776         }
    777 
    778         long fieldID = debuggeeWrapper.vmMirror.getFieldID(classID, fieldName);
    779         if (fieldID == -1) {
    780             logWriter
    781                     .println("## setStaticIntField(): Can NOT get fieldID for field = '"
    782                             + fieldName + "'");
    783             return false;
    784         }
    785 
    786         CommandPacket packet = new CommandPacket(
    787                 JDWPCommands.ClassTypeCommandSet.CommandSetID,
    788                 JDWPCommands.ClassTypeCommandSet.SetValuesCommand);
    789         packet.setNextValueAsReferenceTypeID(classID);
    790         packet.setNextValueAsInt(1);
    791         packet.setNextValueAsFieldID(fieldID);
    792         packet.setNextValueAsInt(newValue);
    793 
    794         ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
    795         int errorCode = reply.getErrorCode();
    796         if (errorCode != JDWPConstants.Error.NONE) {
    797             logWriter
    798                     .println("## setStaticIntField(): Can NOT set value for field = '"
    799                             + fieldName
    800                             + "' in class = '"
    801                             + classSignature
    802                             + "'; ClassType.SetValues command reurns error = "
    803                             + errorCode);
    804             return false;
    805         }
    806         return true;
    807     }
    808 
    809     /**
    810      * Removes breakpoint of the given event kind corresponding to the given
    811      * request id.
    812      *
    813      * @param eventKind
    814      *            request event kind
    815      * @param requestID
    816      *            request id
    817      * @param verbose
    818      *            print or don't extra log info
    819      */
    820     protected void clearEvent(byte eventKind, int requestID, boolean verbose) {
    821         CommandPacket packet = new CommandPacket(
    822                 JDWPCommands.EventRequestCommandSet.CommandSetID,
    823                 JDWPCommands.EventRequestCommandSet.ClearCommand);
    824         packet.setNextValueAsByte(eventKind);
    825         packet.setNextValueAsInt(requestID);
    826         if (verbose) {
    827             logWriter.println("Clearing event: "
    828                     + JDWPConstants.EventKind.getName(eventKind) + ", id: "
    829                     + requestID);
    830         }
    831         ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
    832         checkReplyPacket(reply, "EventRequest::Clear command");
    833         assertAllDataRead(reply);
    834     }
    835 }
    836