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