• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /**
20  * @author Vitaly A. Provodin, Anatoly F. Bondarenko
21  */
22 
23 /**
24  * Created on 10.02.2005
25  */
26 package org.apache.harmony.jpda.tests.jdwp.VirtualMachine;
27 
28 import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
29 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
30 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
31 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
32 import org.apache.harmony.jpda.tests.framework.jdwp.exceptions.ReplyErrorCodeException;
33 import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase;
34 
35 import java.util.ArrayList;
36 import java.util.List;
37 
38 
39 /**
40  * JDWP Unit test for VirtualMachine.Resume command.
41  */
42 public class ResumeTest extends JDWPSyncTestCase {
43 
44     static final String debuggeeSignature =
45         "Lorg/apache/harmony/jpda/tests/jdwp/VirtualMachine/ResumeDebuggee;";
46 
getDebuggeeClassName()47     protected String getDebuggeeClassName() {
48         return ResumeDebuggee.class.getName();
49     }
50 
51     @Override
internalTearDown()52     protected void internalTearDown() {
53         // We need to finish the tested threads before detaching.
54         logWriter.println("Finish debuggee tested threads");
55         setStaticIntField(debuggeeSignature,
56                 ResumeDebuggee.TO_FINISH_DEBUGGEE_FIELD_NAME, 99);
57         super.internalTearDown();
58     }
59 
60     /**
61      * This testcase exercises VirtualMachine.Resume command.
62      * <BR>At first the test starts ResumeDebuggee which starts and runs some tested threads.
63      * <BR> Then the test performs VirtualMachine.Suspend command and checks with help of
64      * ThreadReference.Status command that all debuggee tested threads are suspended.
65      * <BR> Then the test performs VirtualMachine.Resume command and checks with help of
66      * ThreadReference.Status command that all debuggee tested threads are resumed.
67      */
testResume001()68     public void testResume001() {
69         logWriter.println("==> testResume001: START...");
70 
71         // The error messages in case of test failure.
72         List<String> errorMessages = new ArrayList<String>();
73 
74         // All the threads we're interested in.
75         ThreadInfo[] threadInfos = createThreadInfos();
76 
77         // Suspend all threads with VirtualMachine.Suspend command.
78         suspendAll();
79 
80         // Check all threads are suspended now.
81         logWriter.println("\n==> Check that all tested threads are suspended " +
82                 "after VirtualMachine.Suspend command...");
83         checkThreadStatus(threadInfos, true, errorMessages);
84 
85         // Resume all threads with VirtualMachine.Resume command.
86         resumeAll();
87 
88         // Check all threads are NOT suspended anymore.
89         logWriter.println("\n==> Check that all tested threads are resumed " +
90                 "after VirtualMachine.Resume command...");
91         checkThreadStatus(threadInfos, false, errorMessages);
92 
93         if (!errorMessages.isEmpty()) {
94             // Print error messages first.
95             for (String errorMessage : errorMessages) {
96                 logWriter.printError(errorMessage + "\n");
97             }
98             printErrorAndFail("\ntestResume001 FAILED");
99         } else {
100             logWriter.println("\n==> testResume001 - OK!");
101         }
102     }
103 
104     /**
105      * This testcase exercises VirtualMachine.Resume command.
106      * <BR>At first the test starts ResumeDebuggee which starts and runs some
107      * tested threads.
108      * <BR> Then the test performs VirtualMachine.Suspend command twice and
109      * checks, with help of ThreadReference.Status command, that all debuggee
110      * tested threads are suspended.
111      * <BR> Then the test performs VirtualMachine.Resume command and checks
112      * that all debuggee tested threads are still suspended.
113      * <BR> Then the test performs VirtualMachine.Resume command again and
114      * checks that all debuggee tested threads are resumed.
115      */
testResume002()116     public void testResume002() {
117         logWriter.println("==> testResume002: START...");
118 
119         // The error messages in case of test failure.
120         List<String> errorMessages = new ArrayList<String>();
121 
122         // All the threads we're interested in.
123         ThreadInfo[] threadInfos = createThreadInfos();
124 
125         // Suspend all threads with VirtualMachine.Suspend command.
126         suspendAll();
127 
128         // Check all threads are suspended now.
129         logWriter.println("\n==> Check that all tested threads are suspended " +
130                 "after VirtualMachine.Suspend command...");
131         checkThreadStatus(threadInfos, true, errorMessages);
132 
133         // Suspend all threads again.
134         suspendAll();
135 
136         // Check all threads are still suspended.
137         logWriter.println("\n==> Check that all tested threads are still " +
138                 "suspended after another VirtualMachine.Suspend command...");
139         checkThreadStatus(threadInfos, true, errorMessages);
140 
141         // Resume all threads with VirtualMachine.Resume command.
142         resumeAll();
143 
144         // Check all threads are still suspended.
145         logWriter.println("\n==> Check that all tested threads are still " +
146                 "suspended after VirtualMachine.Resume command...");
147         checkThreadStatus(threadInfos, true, errorMessages);
148 
149         // Resume all threads again.
150         resumeAll();
151 
152         // Check all threads are NOT suspended anymore.
153         logWriter.println("\n==> Check that all tested threads are resumed " +
154                 "after VirtualMachine.Resume command...");
155         checkThreadStatus(threadInfos, false, errorMessages);
156 
157         if (!errorMessages.isEmpty()) {
158             // Print error messages first.
159             for (String errorMessage : errorMessages) {
160                 logWriter.printError(errorMessage + "\n");
161             }
162             printErrorAndFail("\ntestResume002 FAILED");
163         } else {
164             logWriter.println("\n==> testResume002 - OK!");
165         }
166     }
167 
168     /**
169      * This testcase exercises VirtualMachine.Resume command.
170      * <BR>At first the test starts ResumeDebuggee which starts and runs some
171      * tested threads.
172      * <BR> Then the test performs VirtualMachine.Resume command and checks it
173      * does not cause any error if we do not perform VirtualMachine.Suspend
174      * before.
175      * <BR> Then the test performs VirtualMachine.Suspend command and checks
176      * that all debuggee tested threads are suspended.
177      * <BR> Then the test performs VirtualMachine.Resume command and checks
178      * that all debuggee tested threads are resumed.
179      */
testResume003()180     public void testResume003() {
181         logWriter.println("==> testResume002: START...");
182 
183         // The error messages in case of test failure.
184         List<String> errorMessages = new ArrayList<String>();
185 
186         // All the threads we're interested in.
187         ThreadInfo[] threadInfos = createThreadInfos();
188 
189         // Resume all threads: should be a no-op.
190         resumeAll();
191 
192         // Check all threads are NOT suspended.
193         logWriter.println("\n==> Check that no tested thread is suspended " +
194                 "after VirtualMachine.Resume command...");
195         checkThreadStatus(threadInfos, false, errorMessages);
196 
197         // Suspend all threads with VirtualMachine.Suspend command.
198         suspendAll();
199 
200         // Check all threads are suspended now.
201         logWriter.println("\n==> Check that all tested threads are suspended " +
202                 "after VirtualMachine.Suspend command...");
203         checkThreadStatus(threadInfos, true, errorMessages);
204 
205         // Resume all threads with VirtualMachine.Resume command.
206         resumeAll();
207 
208         // Check all threads are NOT suspended anymore.
209         logWriter.println("\n==> Check that all tested threads are resumed " +
210                 "after VirtualMachine.Resume command...");
211         checkThreadStatus(threadInfos, false, errorMessages);
212 
213         if (!errorMessages.isEmpty()) {
214             // Print error messages first.
215             for (String errorMessage : errorMessages) {
216                 logWriter.printError(errorMessage + "\n");
217             }
218             printErrorAndFail("\ntestResume002 FAILED");
219         } else {
220             logWriter.println("\n==> testResume002 - OK!");
221         }
222     }
223     private static class ThreadInfo {
224         final String threadName;
225         long threadId = 0;
226 
ThreadInfo(String threadName)227         public ThreadInfo(String threadName) {
228             this.threadName = threadName;
229         }
230     }
231 
232     /**
233      * Suspends all threads using VirtualMachine.Suspend command.
234      */
suspendAll()235     private void suspendAll() {
236         logWriter.println("\n==> Send VirtualMachine.Suspend command...");
237         CommandPacket packet = new CommandPacket(
238                 JDWPCommands.VirtualMachineCommandSet.CommandSetID,
239                 JDWPCommands.VirtualMachineCommandSet.SuspendCommand);
240         ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
241         checkReplyPacket(reply, "VirtualMachine.Suspend");
242         logWriter.println("==> VirtualMachine.Suspend command - OK.");
243     }
244 
245     /**
246      * Resumes all threads using VirtualMachine.Resume command.
247      */
resumeAll()248     private void resumeAll() {
249         logWriter.println("\n==> Send VirtualMachine.Resume command...");
250         CommandPacket packet = new CommandPacket(
251                 JDWPCommands.VirtualMachineCommandSet.CommandSetID,
252                 JDWPCommands.VirtualMachineCommandSet.ResumeCommand);
253         ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
254         checkReplyPacket(reply, "VirtualMachine.Resume");
255         logWriter.println("==> VirtualMachine.Resume command - OK.");
256     }
257 
258     /**
259      * Returns the number of threads used in the tests (including the main
260      * thread).
261      */
getThreadsNumber()262     private int getThreadsNumber() {
263         String debuggeeMessage = synchronizer.receiveMessage();
264         int testedThreadsNumber = 0;
265         try {
266             testedThreadsNumber = Integer.valueOf(debuggeeMessage).intValue();
267         } catch (NumberFormatException exception) {
268             logWriter.println("## FAILURE: Exception while getting number of"
269                     + " started threads from debuggee = " + exception);
270             printErrorAndFail("\n## Can NOT get number of started threads "
271                     + "from debuggee! ");
272         }
273         return testedThreadsNumber + 1;  // to add debuggee main thread
274     }
275 
276     /**
277      * Creates ThreadInfo array containing information about each tested thread:
278      * thread name and thread JDWP id.
279      */
createThreadInfos()280     private ThreadInfo[] createThreadInfos() {
281         int testedThreadsNumber = getThreadsNumber();
282         logWriter.println("==>  Number of threads in debuggee to test = "
283                 + testedThreadsNumber);
284         ThreadInfo[] threadInfos = new ThreadInfo[testedThreadsNumber];
285 
286         String debuggeeMainThreadName = synchronizer.receiveMessage();
287         // Initialize all threads
288         for (int i = 0, e = threadInfos.length - 1; i < e; ++i) {
289             threadInfos[i] = new ThreadInfo(ResumeDebuggee.THREAD_NAME_PATTERN + i);
290         }
291         threadInfos[threadInfos.length - 1] = new ThreadInfo(debuggeeMainThreadName);
292 
293         // Getting ID of the tested thread using VirtualMachine.AllThreads.
294         ReplyPacket allThreadIDReply = null;
295         try {
296             allThreadIDReply = debuggeeWrapper.vmMirror.getAllThreadID();
297         } catch (ReplyErrorCodeException exception) {
298             logWriter.println
299                 ("## FAILURE: Exception in vmMirror.getAllThreadID() = " + exception);
300             printErrorAndFail("\n## Can NOT get all ThreadID in debuggee! ");
301         }
302         int threads = allThreadIDReply.getNextValueAsInt();
303         logWriter.println("==>  Number of all threads in debuggee = " + threads);
304         for (int i = 0; i < threads; i++) {
305             long threadID = allThreadIDReply.getNextValueAsThreadID();
306             String threadName = null;
307             try {
308                 threadName = debuggeeWrapper.vmMirror.getThreadName(threadID);
309             } catch (ReplyErrorCodeException exception) {
310                 logWriter.println
311                     ("==> WARNING: Can NOT get thread name for threadID = " + threadID);
312                 continue;
313             }
314             for (ThreadInfo threadInfo : threadInfos) {
315                 if (threadInfo.threadName.equals(threadName) ) {
316                     threadInfo.threadId = threadID;
317                     break;
318                 }
319             }
320         }
321 
322         // Check we found thread id for each thread.
323         boolean testedThreadNotFound = false;
324         for (ThreadInfo threadInfo : threadInfos) {
325             if (threadInfo.threadId == 0) {
326                 logWriter.println("## FAILURE: Tested thread is not found out "
327                         + "among debuggee threads!");
328                 logWriter.println("##          Thread name = "
329                         + threadInfo.threadName);
330                 testedThreadNotFound = true;
331             }
332         }
333         if (testedThreadNotFound) {
334             printErrorAndFail("\n## Some of tested threads are not found!");
335         }
336 
337         return threadInfos;
338     }
339 
340     /**
341      * Checks suspend status of each tested thread is the expected one.
342      *
343      * @param threadInfos
344      *          the thread information
345      * @param isSuspended
346      *          if true, thread must be suspended; otherwise thread
347      *          must not be suspended.
348      * @param errorMessages
349      *          a list of String to append error message.
350      */
checkThreadStatus(ThreadInfo[] threadInfos, boolean isSuspended, List<String> errorMessages)351     private void checkThreadStatus(ThreadInfo[] threadInfos,
352             boolean isSuspended, List<String> errorMessages) {
353         boolean statusCommandFailed = false;
354         boolean suspendStatusFailed = false;
355 
356         for (ThreadInfo threadInfo : threadInfos) {
357             logWriter.println("\n==> Check for Thread: threadID = "
358                     + threadInfo.threadId
359                     + " (" + threadInfo.threadName + ")");
360 
361             logWriter.println("==> Send ThreadReference.Status command...");
362             CommandPacket packet = new CommandPacket(
363                     JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
364                     JDWPCommands.ThreadReferenceCommandSet.StatusCommand);
365             packet.setNextValueAsThreadID(threadInfo.threadId);
366             ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
367             if (!checkReplyPacketWithoutFail(reply, "ThreadReference.Status command")) {
368                 logWriter.println("Can't get thread status for thread " +
369                         threadInfo.threadId +
370                         " \"" + threadInfo.threadName + "\"");
371                 statusCommandFailed = true;
372                 continue;
373             }
374 
375             int threadStatus = reply.getNextValueAsInt();
376             int suspendStatus = reply.getNextValueAsInt();
377 
378             logWriter.println("==> threadStatus = " + threadStatus + " ("
379                     + JDWPConstants.ThreadStatus.getName(threadStatus) + ")");
380             logWriter.println("==> suspendStatus = " + suspendStatus + " ("
381                     + JDWPConstants.SuspendStatus.getName(suspendStatus) + ")");
382 
383             boolean isThreadSuspended =
384                     (suspendStatus == JDWPConstants.SuspendStatus.SUSPEND_STATUS_SUSPENDED);
385             if (isThreadSuspended != isSuspended) {
386                 logWriter.println("## FAILURE: Unexpected suspendStatus for " +
387                         "checked thread " + threadInfo.threadId +
388                         " \"" + threadInfo.threadName + "\"");
389                 logWriter.println("##          Expected suspendStatus  = "
390                         + JDWPConstants.SuspendStatus.SUSPEND_STATUS_SUSPENDED
391                         + "(" + JDWPConstants.SuspendStatus.getName
392                         (JDWPConstants.SuspendStatus.SUSPEND_STATUS_SUSPENDED) +")");
393                 suspendStatusFailed = true;
394                 continue;
395             }
396         }
397 
398         if (statusCommandFailed) {
399             errorMessages.add("## Error found out while ThreadReference.Status "
400                     + "command performing!");
401         }
402         if (suspendStatusFailed) {
403             errorMessages.add("## Unexpected suspendStatus found out!");
404         }
405     }
406 }
407