diff options
author | Sebastien Hertz <shertz@google.com> | 2014-10-10 08:23:11 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-10-10 08:23:11 +0000 |
commit | a56966f5f8c66f861d69f4bd90c985e44501766e (patch) | |
tree | 0a7b91d786309d5cb0d2cccff898cb8c6dffe372 | |
parent | 6e5af32ffb0ca9a6de807685a97062d2016d4947 (diff) | |
parent | 684d91ef9b8c8022f19cc0d51598c2402303ed7c (diff) | |
download | apache-harmony-l-preview.tar.gz |
Merge "Test event requests with LocationOnly modifier other than breakpoint"android-l-preview_r2l-preview
11 files changed, 667 insertions, 6 deletions
diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ClassType/InvokeMethodTest.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ClassType/InvokeMethodTest.java index 68cefd6..6576065 100644 --- a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ClassType/InvokeMethodTest.java +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ClassType/InvokeMethodTest.java @@ -362,7 +362,6 @@ public class InvokeMethodTest extends JDWPSyncTestCase { checkReplyPacket(reply, "ClassType::InvokeMethod command", JDWPConstants.Error.INVALID_METHODID); logWriter.println("==> PASSED: Expected error (INVALID_METHODID) is returned"); - logWriter.println("\n==> resumeDebuggee..."); resumeDebuggee(); synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); @@ -490,7 +489,6 @@ public class InvokeMethodTest extends JDWPSyncTestCase { checkReplyPacket(reply, "ClassType::InvokeMethod command", JDWPConstants.Error.INVALID_METHODID); logWriter.println("==> PASSED: Expected error (INVALID_METHODID) is returned"); - logWriter.println("\n==> resumeDebuggee..."); resumeDebuggee(); synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/EventLocationEventTestCase.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/EventLocationEventTestCase.java new file mode 100644 index 0000000..a363121 --- /dev/null +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/EventLocationEventTestCase.java @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.jpda.tests.jdwp.Events; + +import org.apache.harmony.jpda.tests.framework.jdwp.Event; +import org.apache.harmony.jpda.tests.framework.jdwp.EventBuilder; +import org.apache.harmony.jpda.tests.framework.jdwp.EventPacket; +import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants; +import org.apache.harmony.jpda.tests.framework.jdwp.Location; +import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent; +import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket; +import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; + +import java.util.HashSet; +import java.util.Set; + +/** + * Base class to test event with LocationOnly modifier. + */ +abstract class EventLocationEventTestCase extends JDWPEventTestCase { + + private Set<Integer> requestIds = new HashSet<Integer>(); + + protected abstract String getDebuggeeSignature(); + protected abstract String getExpectedLocationMethodName(); + protected abstract void createEventBuilder(EventBuilder builder); + protected abstract void checkEvent(ParsedEvent event); + + protected void runEventWithLocationTest(byte eventKind) { + synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); + + // Request event for all possible locations in the expected + // method. + requestEventForAllLocations(eventKind); + + synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); + + // Wait for the event. + EventPacket event = debuggeeWrapper.vmMirror.receiveEvent(); + ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(event); + + // We expect only one event. + assertEquals("Invalid number of events,", 1, parsedEvents.length); + + ParsedEvent parsedEvent = parsedEvents[0]; + + // Check this is the event we expect. + assertEquals("Invalid event kind,", + eventKind, + parsedEvent.getEventKind(), + JDWPConstants.EventKind.getName(eventKind), + JDWPConstants.EventKind.getName(parsedEvent.getEventKind())); + + // Check this is one event we requested. + int eventRequestId = parsedEvent.getRequestID(); + assertTrue("Unexpected event request " + eventRequestId, + requestIds.contains(Integer.valueOf(eventRequestId))); + + // Check the event is the expected one. + checkEvent(parsedEvent); + + // Clear all event requests. + clearAllEvents(eventKind); + + // Resume debuggee before leaving. + resumeDebuggee(); + } + + /** + * Since we don't know the location where the event can be reported, + * we send a request for all possible locations inside the method. + */ + private void requestEventForAllLocations(byte eventKind) { + // Ensure we start with no request. + requestIds.clear(); + + // Find the method where we expect the event to occur. + long typeId = getClassIDBySignature(getDebuggeeSignature()); + long methodId = getMethodID(typeId, getExpectedLocationMethodName()); + + // Get its line table + ReplyPacket replyPacket = getLineTable(typeId, methodId); + long startIndex = replyPacket.getNextValueAsLong(); + long endIndex = replyPacket.getNextValueAsLong(); + logWriter.println("Method code index starts at " + startIndex + + " and ends at " + endIndex); + + // Request event at all possible locations. We'd like to do + // this for each code instruction but we do not know them and + // do not know their size. Therefore we include any code + // index between start and end. + logWriter.println("Creating request for each possible index"); + for (long idx = startIndex; idx <= endIndex; ++idx) { + Location location = new Location(JDWPConstants.TypeTag.CLASS, + typeId, methodId, idx); + EventBuilder builder = new EventBuilder(eventKind, + JDWPConstants.SuspendPolicy.ALL); + createEventBuilder(builder); + setEvent(builder, location); + + } + logWriter.println("Created " + requestIds.size() + " requests"); + } + + private void setEvent(EventBuilder builder, Location location) { + builder.setLocationOnly(location); + Event event = builder.build(); + ReplyPacket reply = debuggeeWrapper.vmMirror.setEvent(event); + int requestId = reply.getNextValueAsInt(); + logWriter.println("=> New request " + requestId); + requestIds.add(Integer.valueOf(requestId)); + } + + private void clearAllEvents(byte eventKind) { + logWriter.println("Clear all field requests"); + for (Integer requestId : requestIds) { + clearEvent(eventKind, requestId.intValue()); + } + requestIds.clear(); + } + + private void clearEvent(byte fieldEventKind, int requestId) { + logWriter.println("=> Clear request " + requestId); + debuggeeWrapper.vmMirror.clearEvent(fieldEventKind, requestId); + } +} diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/ExceptionWithLocationDebuggee.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/ExceptionWithLocationDebuggee.java new file mode 100644 index 0000000..0563a11 --- /dev/null +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/ExceptionWithLocationDebuggee.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.jpda.tests.jdwp.Events; + +import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; +import org.apache.harmony.jpda.tests.share.SyncDebuggee; + +/** + * Debuggee for ExceptionWithLocationTest unit test. + */ +public class ExceptionWithLocationDebuggee extends SyncDebuggee { + + public static void main(String[] args) { + runDebuggee(ExceptionWithLocationDebuggee.class); + } + + public void unexpectedThrowException() { + try { + throw new DebuggeeException("Unexpected exception"); + } catch (DebuggeeException e) { + logWriter.println("ExceptionWithLocationDebuggee: Exception: \""+e.getMessage()+"\" was thrown"); + } + } + + public void expectedThrowException() { + try { + throw new DebuggeeException("Expected exception"); + } catch (DebuggeeException e) { + logWriter.println("ExceptionLocationDebuggee: Exception: \""+e.getMessage()+"\" was thrown"); + } + } + + public void run() { + logWriter.println("ExceptionWithLocationDebuggee: STARTED"); + // load and prepare DebuggeeException class + DebuggeeException ex = new DebuggeeException("dummy exception"); + + synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_READY); + + synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); + + unexpectedThrowException(); + expectedThrowException(); + + logWriter.println("ExceptionWithLocationDebuggee: FINISHing..."); + } +} diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/ExceptionWithLocationTest.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/ExceptionWithLocationTest.java new file mode 100644 index 0000000..b646a65 --- /dev/null +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/ExceptionWithLocationTest.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.jpda.tests.jdwp.Events; + +import org.apache.harmony.jpda.tests.framework.jdwp.EventBuilder; +import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants; +import org.apache.harmony.jpda.tests.framework.jdwp.Location; +import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent; +import org.apache.harmony.jpda.tests.framework.jdwp.TaggedObject; + +/** + * JDWP Unit test for caught EXCEPTION event with LocationOnly modifier. + */ +public class ExceptionWithLocationTest extends EventLocationEventTestCase { + private static final String EXCEPTION_SIGNATURE = "Lorg/apache/harmony/jpda/tests/jdwp/Events/DebuggeeException;"; + + // Cache exception class ID. + private long exceptionClassId = -1; + + /** + * This testcase is for caught EXCEPTION event with LocationOnly + * modifier.<BR> + * It runs ExceptionWithLocationDebuggee that throws caught + * DebuggeeException in two different methods. + * The test verifies that requested EXCEPTION event occurs in the + * expected method. + */ + public void testExceptionLocationEvent() { + logWriter.println("testExceptionLocationEvent STARTED"); + + runEventWithLocationTest(JDWPConstants.EventKind.EXCEPTION); + + logWriter.println("testExceptionLocationEvent FINISHED"); + } + + @Override + protected String getDebuggeeClassName() { + return ExceptionWithLocationDebuggee.class.getName(); + } + + @Override + protected String getDebuggeeSignature() { + return "Lorg/apache/harmony/jpda/tests/jdwp/Events/ExceptionWithLocationDebuggee;"; + } + + @Override + protected String getExpectedLocationMethodName() { + return "expectedThrowException"; + } + + @Override + protected void createEventBuilder(EventBuilder builder) { + if (exceptionClassId == -1) { + exceptionClassId = getClassIDBySignature(EXCEPTION_SIGNATURE); + } + // Receive caught DebuggeeException. + builder.setExceptionOnly(exceptionClassId, true, false); + } + + @Override + protected void checkEvent(ParsedEvent event) { + ParsedEvent.Event_EXCEPTION eventException = + (ParsedEvent.Event_EXCEPTION) event; + + TaggedObject exception = eventException.getException(); + assertEquals(JDWPConstants.Tag.OBJECT_TAG, exception.tag); + + long thrownExceptionClassId = getObjectReferenceType(exception.objectID); + assertEquals("Received incorrect exception", + exceptionClassId, thrownExceptionClassId); + + Location catchLocation = eventException.getCatchLocation(); + assertNotNull("Incorrect catch location", catchLocation); + } +} diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/FieldWithLocationDebuggee.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/FieldWithLocationDebuggee.java new file mode 100644 index 0000000..a8c707d --- /dev/null +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/FieldWithLocationDebuggee.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.jpda.tests.jdwp.Events; + +import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; +import org.apache.harmony.jpda.tests.share.SyncDebuggee; + +/** + * Debuggee for FieldWithLocationTest unit test. + */ +public class FieldWithLocationDebuggee extends SyncDebuggee { + + public static void main(String[] args) { + runDebuggee(FieldWithLocationDebuggee.class); + } + + private int testIntField = 0; + + private void unexpectedMethodForFieldEvent() { + System.out.println("incrementMethodOne"); + int currentValue = testIntField; // field access + System.out.println("testIntField = " + currentValue); + testIntField = currentValue + 1; // field modification + } + + private void expectedMethodForFieldEvent() { + System.out.println("incrementMethodTwo"); + int currentValue = testIntField; // field access + System.out.println("testIntField = " + currentValue); + testIntField = currentValue + 1; // field modification + } + + public void run() { + logWriter.println("FieldWithLocationDebuggee started"); + + synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_READY); + + synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); + + unexpectedMethodForFieldEvent(); + expectedMethodForFieldEvent(); + + logWriter.println("FieldWithLocationDebuggee finished"); + } +} diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/FieldWithLocationTest.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/FieldWithLocationTest.java new file mode 100644 index 0000000..abdeda7 --- /dev/null +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/FieldWithLocationTest.java @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.jpda.tests.jdwp.Events; + +import org.apache.harmony.jpda.tests.framework.jdwp.EventBuilder; +import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants; +import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent; +import org.apache.harmony.jpda.tests.framework.jdwp.TaggedObject; +import org.apache.harmony.jpda.tests.framework.jdwp.VmMirror; + +/** + * + * JDWP Unit test for FIELD_ACCESS and FIELD_MODIFICATION events with + * LocationOnly modifier. + */ +public class FieldWithLocationTest extends EventLocationEventTestCase { + + private static final String DEBUGGEE_SIGNATURE = + "Lorg/apache/harmony/jpda/tests/jdwp/Events/FieldWithLocationDebuggee;"; + private static final String FIELD_NAME = "testIntField"; + + // Cache debuggee class ID. + private long debuggeeClassId = -1; + + // Cache field ID. + private long fieldId = -1; + + /** + * This testcase is for FIELD_ACCESS event. + * <BR>It runs FieldDebuggee that accesses to the value of its internal field + * and verify that requested FIELD_ACCESS event occurs in the + * expected method. + */ + public void testFieldAccessLocationEvent() { + logWriter.println("testFieldAccessLocationEvent started"); + + runFieldLocationTest(false); + + logWriter.println("testFieldAccessLocationEvent done"); + } + + /** + * This testcase is for FIELD_MODIFICATION event. + * <BR>It runs FieldDebuggee that modifies the value of its internal field + * and verify that requested FIELD_MODIFICATION event occurs in the + * expected method. + */ + public void testFieldModificationLocationEvent() { + logWriter.println("testFieldModificationLocationEvent started"); + + runFieldLocationTest(true); + + logWriter.println("testFieldModificationLocationEvent done"); + } + + @Override + protected final String getDebuggeeClassName() { + return FieldWithLocationDebuggee.class.getName(); + } + + @Override + protected final String getDebuggeeSignature() { + return DEBUGGEE_SIGNATURE; + } + + @Override + protected final String getExpectedLocationMethodName() { + return "expectedMethodForFieldEvent"; + } + + @Override + protected final void createEventBuilder(EventBuilder builder) { + if (debuggeeClassId == -1) { + debuggeeClassId = getClassIDBySignature(DEBUGGEE_SIGNATURE); + } + if (fieldId == -1) { + fieldId = debuggeeWrapper.vmMirror.getFieldID(debuggeeClassId, FIELD_NAME); + } + builder.setFieldOnly(debuggeeClassId, fieldId); + } + + @Override + protected void checkEvent(ParsedEvent event) { + TaggedObject accessedField = null; + byte fieldEventKind = event.getEventKind(); + if (fieldEventKind == JDWPConstants.EventKind.FIELD_ACCESS) { + accessedField = ((ParsedEvent.Event_FIELD_ACCESS)event).getObject(); + } else if (fieldEventKind == JDWPConstants.EventKind.FIELD_MODIFICATION) { + accessedField = ((ParsedEvent.Event_FIELD_MODIFICATION)event).getObject(); + } + + // Check the field receiver is an instance of our debuggee class. + long typeID = getObjectReferenceType(accessedField.objectID); + String returnedExceptionSignature = getClassSignature(typeID); + assertString("Invalid class signature,", + DEBUGGEE_SIGNATURE, returnedExceptionSignature); + } + + private boolean supportFieldCapability(boolean modification) { + VmMirror mirror = debuggeeWrapper.vmMirror; + return modification ? mirror.canWatchFieldModification() : + mirror.canWatchFieldAccess(); + } + + private static String getFieldCapabilityName(boolean modification) { + return modification ? "canWatchFieldModification" : + "canWatchFieldAccess"; + } + + private static byte getFieldEventKind(boolean modification) { + return modification ? JDWPConstants.EventKind.FIELD_MODIFICATION : + JDWPConstants.EventKind.FIELD_ACCESS; + } + + private void runFieldLocationTest(boolean modification) { + final byte eventKind = getFieldEventKind(modification); + final String capabilityname = getFieldCapabilityName(modification); + + logWriter.println("Check capability " + capabilityname); + if (supportFieldCapability(modification)) { + runEventWithLocationTest(eventKind); + } else { + logWriter.println("##WARNING: this VM doesn't possess capability " + + capabilityname); + } + } +} diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/SingleStepWithLocationTest.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/SingleStepWithLocationTest.java new file mode 100644 index 0000000..af01250 --- /dev/null +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/SingleStepWithLocationTest.java @@ -0,0 +1,162 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.jpda.tests.jdwp.Events; + +import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket; +import org.apache.harmony.jpda.tests.framework.jdwp.EventMod; +import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands; +import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants; +import org.apache.harmony.jpda.tests.framework.jdwp.Location; +import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent; +import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket; +import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; + +/** + * JDWP Unit test for SINGLE_STEP event with LocationOnly modifier. + */ +public class SingleStepWithLocationTest extends JDWPEventTestCase { + + private String debuggeeSignature = "Lorg/apache/harmony/jpda/tests/jdwp/Events/SingleStepDebuggee;"; + + private static final String BREAKPOINT_METHOD_NAME = "breakpointTest"; + + protected String getDebuggeeClassName() { + return SingleStepDebuggee.class.getName(); + } + + /** + * This test case exercises SINGLE_STEP event.<BR> + * + * Runs SingleStepDebuggee and sets breakpoint to its + * breakpointTest method, sends a request for single step event with the + * location of the last line so we single-step until there. Then verifies + * that requested SINGLE_STEP event occurs. + */ + public void testSingleStepToLocation() { + logWriter.println("=> testSingleStepToLocation started"); + + synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); + + // Set breakpoint. + long refTypeID = getClassIDBySignature(debuggeeSignature); + + logWriter.println("=> Debuggee class = " + getDebuggeeClassName()); + logWriter.println("=> referenceTypeID for Debuggee class = " + refTypeID); + logWriter.println("=> Send ReferenceType::Methods command and get methodIDs "); + + long requestID = debuggeeWrapper.vmMirror.setBreakpointAtMethodBegin( + refTypeID, BREAKPOINT_METHOD_NAME); + logWriter.println("=> breakpointID = " + requestID); + logWriter.println("=> starting thread"); + + // Execute the breakpoint + synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); + + // Wait for breakpoint event so the program is suspended. + long breakpointThreadID = debuggeeWrapper.vmMirror + .waitForBreakpoint(requestID); + + logWriter.println("=> breakpointThreadID = " + breakpointThreadID); + + // Remove breakpoint. + debuggeeWrapper.vmMirror.clearBreakpoint((int)requestID); + + // Get line table and get code index of the last line. + long methodID = getMethodID(refTypeID, BREAKPOINT_METHOD_NAME); + ReplyPacket lineTableReply = getLineTable(refTypeID, methodID); + checkReplyPacket(lineTableReply, "Method.LineTable"); + lineTableReply.getNextValueAsLong(); // startIndex + lineTableReply.getNextValueAsLong(); // endIndex + int linesCount = lineTableReply.getNextValueAsInt(); + long lastLineCodeIndex = -1; + int lastLineNumber = -1; + for (int i = 0; i < linesCount; ++i) { + lastLineCodeIndex = lineTableReply.getNextValueAsLong(); + lastLineNumber = lineTableReply.getNextValueAsInt(); + } + + logWriter.println("Single-step until line " + lastLineNumber); + + // Location of last line. + Location location = new Location(JDWPConstants.TypeTag.CLASS, + refTypeID, methodID, lastLineCodeIndex); + + // Sending a SINGLE_STEP request + CommandPacket setRequestCommand = new CommandPacket( + JDWPCommands.EventRequestCommandSet.CommandSetID, + JDWPCommands.EventRequestCommandSet.SetCommand); + setRequestCommand.setNextValueAsByte( + JDWPConstants.EventKind.SINGLE_STEP); + setRequestCommand.setNextValueAsByte(JDWPConstants.SuspendPolicy.ALL); + setRequestCommand.setNextValueAsInt(2); + setRequestCommand.setNextValueAsByte(EventMod.ModKind.Step); + setRequestCommand.setNextValueAsThreadID(breakpointThreadID); + setRequestCommand.setNextValueAsInt(JDWPConstants.StepSize.LINE); + setRequestCommand.setNextValueAsInt(JDWPConstants.StepDepth.OVER); + setRequestCommand.setNextValueAsByte(EventMod.ModKind.LocationOnly); + setRequestCommand.setNextValueAsLocation(location); + + ReplyPacket setRequestReply = debuggeeWrapper.vmMirror + .performCommand(setRequestCommand); + checkReplyPacket(setRequestReply, "Set SINGLE_STEP event"); + requestID = setRequestReply.getNextValueAsInt(); + + logWriter.println("=> RequestID = " + requestID); + assertAllDataRead(setRequestReply); + + // Resume debuggee so we can suspend on single-step. + resumeDebuggee(); + + // Wait for event. + logWriter.println("==> Wait for SINGLE_STEP event"); + CommandPacket event = debuggeeWrapper.vmMirror.receiveEvent(); + ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(event); + + // Check if received event is expected. + logWriter.println("==> Received " + parsedEvents.length + " events"); + + // Trace events + for (int i = 0; i < parsedEvents.length; i++) { + logWriter.println(""); + logWriter.println("==> Event #" + i + ";"); + logWriter.println("==> EventKind: " + parsedEvents[i].getEventKind() + "(" + + JDWPConstants.EventKind.getName(parsedEvents[i].getEventKind()) + ")"); + logWriter.println("==> RequestID: " + parsedEvents[i].getRequestID()); + } + + // Check all + assertEquals("Received wrong number of events,", 1, parsedEvents.length); + assertEquals("Received wrong event request ID,", requestID, parsedEvents[0].getRequestID()); + assertEquals("Invalid event kind,", JDWPConstants.EventKind.SINGLE_STEP, + parsedEvents[0].getEventKind(), + JDWPConstants.EventKind.getName(JDWPConstants.EventKind.SINGLE_STEP), + JDWPConstants.EventKind.getName(parsedEvents[0].getEventKind())); + + // Clear SINGLE_STEP event + logWriter.println("==> Clearing SINGLE_STEP event.."); + ReplyPacket clearRequestReply = + debuggeeWrapper.vmMirror.clearEvent(JDWPConstants.EventKind.SINGLE_STEP, (int) requestID); + checkReplyPacket(clearRequestReply, "Clear SINGLE_STEP event"); + logWriter.println("==> SINGLE_STEP event has been cleared"); + + // Resuming debuggee before leaving. + resumeDebuggee(); + logWriter.println("==> Test PASSED!"); + } +} diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/VMDeath002Test.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/VMDeath002Test.java index 6799c52..1ba7f10 100644 --- a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/VMDeath002Test.java +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/VMDeath002Test.java @@ -192,7 +192,6 @@ public class VMDeath002Test extends JDWPSyncTestCase { assertTrue("Failure in processing VM_DEATH event", success); } - logWriter.println("=> Resume debuggee"); resumeDebuggee(); logWriter.println("==> test PASSED!"); diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ObjectReference/MonitorInfoTest.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ObjectReference/MonitorInfoTest.java index 71170e8..5e803e7 100644 --- a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ObjectReference/MonitorInfoTest.java +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ObjectReference/MonitorInfoTest.java @@ -187,8 +187,6 @@ public class MonitorInfoTest extends JDWPSyncTestCase { logWriter.println("=> CHECK 1: PASSED - expected monitor info is received"); checkedReply = null; - logWriter.println("\n=> Send VirtualMachine::Resume command ..."); - resumeDebuggee(); logWriter.println("=> Send to Debuggee signal to continue and to enter in synchronized block ..."); diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/share/JDWPTestCase.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/share/JDWPTestCase.java index 039300b..4191f2c 100644 --- a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/share/JDWPTestCase.java +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/share/JDWPTestCase.java @@ -333,6 +333,7 @@ public abstract class JDWPTestCase extends JDWPRawTestCase { * Helper function for resuming debuggee. */ protected void resumeDebuggee() { + logWriter.println("=> Resume debuggee"); CommandPacket packet = new CommandPacket( JDWPCommands.VirtualMachineCommandSet.CommandSetID, JDWPCommands.VirtualMachineCommandSet.ResumeCommand); diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/share/AllTests.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/share/AllTests.java index a8e10d2..3f3cade 100644 --- a/jdwp/src/test/java/org/apache/harmony/jpda/tests/share/AllTests.java +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/share/AllTests.java @@ -80,14 +80,17 @@ public class AllTests { suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.CombinedEvents003Test.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.CombinedEventsTest.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.ExceptionTest.class); + suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.ExceptionWithLocationTest.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.FieldAccessTest.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.FieldModification002Test.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.FieldModificationTest.class); + suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.FieldWithLocationTest.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.MethodEntryTest.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.MethodExitTest.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.MethodExitWithReturnValueTest.class); - suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.SingleStepThroughReflectionTest.class); + suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.SingleStepWithLocationTest.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.SingleStepTest.class); + suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.SingleStepThroughReflectionTest.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.ThreadEndTest.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.ThreadStartTest.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.VMDeath002Test.class); |