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 package org.apache.harmony.jpda.tests.jdwp.VirtualMachine; 20 21 import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket; 22 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands; 23 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants; 24 import org.apache.harmony.jpda.tests.framework.jdwp.Location; 25 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket; 26 import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase; 27 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; 28 29 /** 30 * JDWP Unit test for VirtualMachine.Resume command. 31 */ 32 public class Resume002Test extends JDWPSyncTestCase { 33 private static final String BREAKPOINT_METHOD_NAME = "breakpointMethod"; 34 35 @Override getDebuggeeClassName()36 protected String getDebuggeeClassName() { 37 return Resume002Debuggee.class.getName(); 38 } 39 40 /** 41 * This testcase exercises VirtualMachine.Resume command when some threads are suspended and 42 * others are running. 43 * <BR>At first the test starts Resume002Debuggee, installs a breakpoint and waits for tested 44 * threads to suspend on this breakpoint. 45 * <BR> Then the test checks all suspended threads have a suspend count of 1 and their 46 * suspend status is SUSPEND_STATUS_SUSPENDED. 47 * <BR> Finally the test performs VirtualMachine.Resume command and checks all threads 48 * are resumed by waiting for them to finish (the debuggee waits for them using Thread.join 49 * method). 50 */ testResume_PartialSuspension()51 public void testResume_PartialSuspension() { 52 logWriter.println("==> testResume_PartialSuspension: START..."); 53 54 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 55 56 // Install breakpoint with EVENT_THREAD suspend policy so only some threads are 57 // suspended. 58 int requestID = installBreakpoint(); 59 60 // Continue debuggee. 61 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 62 63 // Wait for each thread to hit our breakpoint. 64 waitBreakpointHits(requestID); 65 66 // Now some threads are suspended by a breakpoint while others are running. Check we can 67 // resume all suspended threads at once with a VirtualMachine.Resume command. 68 debuggeeWrapper.vmMirror.resume(); 69 70 // Check with the debuggee all threads have been resumed correctly and finished. 71 boolean debuggeeReady = synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 72 assertTrue("Threads did not finish", debuggeeReady); 73 74 logWriter.println("==> testResume_PartialSuspension: END"); 75 } 76 installBreakpoint()77 private int installBreakpoint() { 78 long classID = getClassIDBySignature(getDebuggeeClassSignature()); 79 long methodID = getMethodID(classID, BREAKPOINT_METHOD_NAME); 80 Location location = new Location(JDWPConstants.TypeTag.CLASS, classID, methodID, 0); 81 ReplyPacket breakpointReply = debuggeeWrapper.vmMirror.setBreakpoint(location, 82 JDWPConstants.SuspendPolicy.EVENT_THREAD); 83 checkReplyPacket(breakpointReply, "Failed to set breakpoint"); 84 int requestID = breakpointReply.getNextValueAsInt(); 85 return requestID; 86 } 87 waitBreakpointHits(int requestID)88 private void waitBreakpointHits(int requestID) { 89 logWriter.println("Wait for all breakpoints to hit in each thread"); 90 for (int i = 0; i < Resume002Debuggee.THREAD_COUNT; ++i) { 91 long eventThreadID = debuggeeWrapper.vmMirror.waitForBreakpoint(requestID); 92 String threadName = debuggeeWrapper.vmMirror.getThreadName(eventThreadID); 93 logWriter.println("Thread \"" + threadName + "\" hit breakpoint"); 94 checkThreadSuspendStatus(eventThreadID); 95 checkThreadSuspendCount(eventThreadID); 96 } 97 } 98 checkThreadSuspendStatus(long eventThreadID)99 private void checkThreadSuspendStatus(long eventThreadID) { 100 // Getting the thread status 101 CommandPacket packet = new CommandPacket( 102 JDWPCommands.ThreadReferenceCommandSet.CommandSetID, 103 JDWPCommands.ThreadReferenceCommandSet.StatusCommand); 104 packet.setNextValueAsThreadID(eventThreadID); 105 106 ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet); 107 checkReplyPacket(reply, "ThreadReference::Status command"); 108 109 reply.getNextValueAsInt(); // 'threadStatus' unused 110 int suspendStatus = reply.getNextValueAsInt(); 111 assertAllDataRead(reply); 112 113 assertEquals("Invalid suspend status for thread " + eventThreadID, 114 JDWPConstants.SuspendStatus.SUSPEND_STATUS_SUSPENDED, 115 suspendStatus); 116 } 117 checkThreadSuspendCount(long eventThreadID)118 private void checkThreadSuspendCount(long eventThreadID) { 119 // Getting the thread suspend count 120 CommandPacket packet = new CommandPacket( 121 JDWPCommands.ThreadReferenceCommandSet.CommandSetID, 122 JDWPCommands.ThreadReferenceCommandSet.SuspendCountCommand); 123 packet.setNextValueAsThreadID(eventThreadID); 124 125 ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet); 126 checkReplyPacket(reply, "ThreadReference::SuspendCount command"); 127 128 int suspendCount = reply.getNextValueAsInt(); 129 assertAllDataRead(reply); 130 131 assertEquals("Invalid suspend count for thread " + eventThreadID, 1, suspendCount); 132 } 133 134 } 135