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