summaryrefslogtreecommitdiff
path: root/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/ClassPrepare002Test.java
diff options
context:
space:
mode:
Diffstat (limited to 'jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/ClassPrepare002Test.java')
-rw-r--r--jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/ClassPrepare002Test.java136
1 files changed, 136 insertions, 0 deletions
diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/ClassPrepare002Test.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/ClassPrepare002Test.java
new file mode 100644
index 0000000..37a2c5a
--- /dev/null
+++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Events/ClassPrepare002Test.java
@@ -0,0 +1,136 @@
+/*
+ * 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 java.io.IOException;
+import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
+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.JDWPCommands;
+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.ReplyPacket;
+import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent.Event_CLASS_PREPARE;
+import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
+
+/**
+ * JDWP unit test for CLASS_PREPARE events sent from the debugger thread.
+ */
+public class ClassPrepare002Test extends JDWPEventTestCase {
+ @Override
+ protected String getDebuggeeClassName() {
+ return ClassPrepare002Debuggee.class.getName();
+ }
+
+ /**
+ * Tests that the CLASS_PREPARE event can be sent from the runtime's debugger thread.
+ *
+ * This test starts by requesting a CLASS_PREPARE event then sends a ReferenceType.GetValues
+ * command to cause the debugger thread to report a CLASS_PREPARE event. After checking the
+ * content of the event packet, we clear the event request then resume the debuggee.
+ */
+ public void testClassPrepareCausedByDebugger() {
+ logWriter.println("testClassPrepareCausedByDebugger started");
+
+ synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
+
+ // The TestClassA must be loaded but not initialized.
+ long classIDOfA = getClassIDBySignature(getClassSignature(TestClassA.class));
+
+ // Restrict class prepare only to the tested class.
+ String classPrepareClassName = "org.apache.harmony.jpda.tests.jdwp.Events.TestClassB";
+
+ // Request CLASS_PREPARE event. The event will be caused by the debugger thread when
+ // handling the ReferenceType.GetValues command we're going to send just after.
+ EventBuilder eventBuilder = new EventBuilder(JDWPConstants.EventKind.CLASS_PREPARE,
+ JDWPConstants.SuspendPolicy.EVENT_THREAD);
+ eventBuilder.setClassMatch(classPrepareClassName);
+ ReplyPacket eventReply = debuggeeWrapper.vmMirror.setEvent(eventBuilder.build());
+ checkReplyPacket(eventReply, "Failed to set CLASS_PREPARE event");
+ int classPrepareRequestId = eventReply.getNextValueAsInt();
+ assertAllDataRead(eventReply);
+
+ // Send a ReferenceType.GetValues command to force class initialization. This will trigger
+ // the CLASS_PREPARE event from the debugger thread.
+ logWriter.println("=> CHECK: send ReferenceType.GetValues");
+ long fieldId = checkField(classIDOfA, "field");
+ CommandPacket getValuesCommand = new CommandPacket(
+ JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
+ JDWPCommands.ReferenceTypeCommandSet.GetValuesCommand);
+ getValuesCommand.setNextValueAsReferenceTypeID(classIDOfA);
+ getValuesCommand.setNextValueAsInt(1);
+ getValuesCommand.setNextValueAsFieldID(fieldId);
+
+ // Send command but does not wait for reply because this will cause a CLASS_PREPARE event
+ // that will suspend every thread.
+ int rtGetValuesCommandId = -1;
+ try {
+ rtGetValuesCommandId = debuggeeWrapper.vmMirror.sendCommand(getValuesCommand);
+ } catch (IOException e) {
+ fail("Failed to send ReferenceType.GetValues command");
+ }
+
+ // Wait for the class prepare event.
+ EventPacket eventPacket = debuggeeWrapper.vmMirror
+ .receiveCertainEvent(JDWPConstants.EventKind.CLASS_PREPARE);
+ ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(eventPacket);
+ assertNotNull(parsedEvents);
+ logWriter.println("Received " + parsedEvents.length + " event(s)");
+ assertEquals(1, parsedEvents.length);
+
+ // Check event is the expected one.
+ ParsedEvent parsedEvent = parsedEvents[0];
+ // Only expect CLASS_PREPARE event.
+ assertEquals(JDWPConstants.EventKind.CLASS_PREPARE, parsedEvent.getEventKind());
+ // CLASS_PREPARE events caused by the debugger must have an ALL
+ // suspend policy.
+ assertEquals(JDWPConstants.SuspendPolicy.ALL, parsedEvent.getSuspendPolicy());
+ // Check that its the event that we have requested.
+ assertEquals(classPrepareRequestId, parsedEvent.getRequestID());
+ Event_CLASS_PREPARE classPrepareEvent = (Event_CLASS_PREPARE) parsedEvent;
+ // The JDWP spec says that if the event was caused by the debugger thread, the thread ID
+ // must be 0.
+ assertEquals(0, classPrepareEvent.getThreadID());
+ // Check that it is the expected class.
+ assertEquals(getClassSignature(classPrepareClassName), classPrepareEvent.getSignature());
+
+ // Check that we received the reply of the command that caused the CLASS_PREPARE event.
+ logWriter.println("=> CHECK: receive ReferenceType.GetValues reply (" +
+ rtGetValuesCommandId + ")");
+ ReplyPacket getValuesReply = null;
+ try {
+ getValuesReply = debuggeeWrapper.vmMirror.receiveReply(rtGetValuesCommandId);
+ } catch (InterruptedException | IOException e) {
+ fail("Failed to receive ReferenceType.GetValues reply");
+ }
+ checkReplyPacket(getValuesReply, "Failed to receive ReferenceType.GetValues reply");
+
+ // Clear the CLASS_PREPARE event request.
+ debuggeeWrapper.vmMirror.clearEvent(JDWPConstants.EventKind.CLASS_PREPARE,
+ classPrepareRequestId);
+
+ // Resume all threads suspended by the CLASS_PREPARE event.
+ debuggeeWrapper.vmMirror.resume();
+
+ // Let the debuggee finish.
+ synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
+
+ logWriter.println("testClassPrepareCausedByDebugger finished");
+ }
+}