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
21  */
22 
23 /**
24  * Created on 15.02.2005
25  */
26 package org.apache.harmony.jpda.tests.jdwp.ThreadReference;
27 
28 import org.apache.harmony.jpda.tests.framework.jdwp.exceptions.*;
29 import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
30 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
31 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
32 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
33 import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase;
34 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
35 
36 
37 /**
38  * JDWP Unit test for ThreadReference.SuspendCount command.
39  */
40 public class SuspendCountTest extends JDWPSyncTestCase {
41 
42     static final int testStatusPassed = 0;
43     static final int testStatusFailed = -1;
44     static final String debuggeeSignature =
45             "Lorg/apache/harmony/jpda/tests/jdwp/ThreadReference/SuspendCountDebuggee;";
46 
getDebuggeeClassName()47     protected String getDebuggeeClassName() {
48         return "org.apache.harmony.jpda.tests.jdwp.ThreadReference.SuspendCountDebuggee";
49     }
50 
51     /**
52      * This testcase exercises ThreadReference.SuspendCount command.
53      * <BR>At first the test starts SuspendCountDebuggee which starts and runs some tested threads.
54      * <BR>After the tested threads starts, the test suspends every
55      * tested thread in debuggee some times and
56      * check that ThreadReference.SuspendCount command returns
57      * expected number of times thread was suspended.
58      * <BR>Then the test suspends all debuggee by VirtualMachine.Suspend command
59      * and check that ThreadReference.SuspendCount command returns 1 value
60      * for all tested threads and main thread.
61      * <BR>Then the test resumes all debuggee by VirtualMachine.Resume command
62      * and check that ThreadReference.SuspendCount command returns 0 value
63      * for all tested threads and main thread.
64      */
testSuspendCount001()65     public void testSuspendCount001() {
66         logWriter.println("==> testSuspendCount001: START...");
67         String debuggeeMessage = synchronizer.receiveMessage();
68         int testedThreadsNumber = 0;
69         try {
70             testedThreadsNumber = Integer.valueOf(debuggeeMessage).intValue();
71         } catch (NumberFormatException exception) {
72             logWriter.println
73                 ("## FAILURE: Exception while getting number of started threads from debuggee = " + exception);
74             synchronizer.sendMessage("FINISH");
75             printErrorAndFail("Can NOT get number of started threads from debuggee! ");
76         }
77         if ( testedThreadsNumber == 0 ) {
78             logWriter.println("==>  There are no started threads in debuggee to test"
79                     + " - testSuspendCount001 finishes!");
80             synchronizer.sendMessage("FINISH");
81             return;
82         }
83         logWriter.println("==>  Number of started threads in debuggee to test = " + testedThreadsNumber);
84         String[] testedThreadsNames = new String[testedThreadsNumber+1]; // +1 is for main debuggee thread
85         long[] testedThreadsIDs = new long[testedThreadsNumber+1];
86         for (int i = 0; i < testedThreadsNumber; i++) {
87             testedThreadsNames[i] = SuspendCountDebuggee.THREAD_NAME_PATTERN + i;
88             testedThreadsIDs[i] = 0;
89         }
90 
91         // getting ID of the tested thread
92         ReplyPacket allThreadIDReply = null;
93         try {
94             allThreadIDReply = debuggeeWrapper.vmMirror.getAllThreadID();
95         } catch (ReplyErrorCodeException exception) {
96             logWriter.println
97                 ("## FAILURE: Exception in vmMirror.getAllThreadID() = " + exception);
98             synchronizer.sendMessage("FINISH");
99             printErrorAndFail("Can NOT get all ThreadID in debuggee! ");
100         }
101         int threads = allThreadIDReply.getNextValueAsInt();
102         logWriter.println("==>  Number of all threads in debuggee = " + threads);
103         String[] allThreadsNames = new String[threads];
104         long[] allThreadsIDs = new long[threads];
105         boolean suspendCommandFailed = false;
106         boolean suspendCountCommandFailed = false;
107         boolean resumeCommandFailed = false;
108 
109         int suspendNumber = 0;
110         for (int i = 0; i < threads; i++) {
111             long threadID = allThreadIDReply.getNextValueAsThreadID();
112             allThreadsIDs[i] = threadID;
113             String threadName = null;
114             try {
115                 threadName = debuggeeWrapper.vmMirror.getThreadName(threadID);
116             } catch (ReplyErrorCodeException exception) {
117                 logWriter.println
118                     ("==> WARNING: Can NOT get thread name for threadID = " + threadID);
119                 continue;
120             }
121             allThreadsNames[i] = threadName;
122             int k = 0;
123             for (; k < testedThreadsNumber; k++) {
124                 if ( threadName.equals(testedThreadsNames[k]) ) {
125                     testedThreadsIDs[k] = threadID;
126                     break;
127                 }
128             }
129             if ( k == testedThreadsNumber ) {
130                 // it is not thread to test
131                 continue;
132             }
133 
134             logWriter.println("\n==> Check for Thread: threadID = " + threadID
135                     + "; threadName = " + threadName);
136 
137             logWriter.println("==> Send ThreadReference.SuspendCount command...");
138             CommandPacket packet = new CommandPacket(
139                     JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
140                     JDWPCommands.ThreadReferenceCommandSet.SuspendCountCommand);
141             packet.setNextValueAsThreadID(threadID);
142             ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
143             if ( ! checkReplyPacketWithoutFail(reply, "ThreadReference.SuspendCount command") ) {
144                 suspendCountCommandFailed = true;
145             } else {
146                 int suspendCount = reply.getNextValueAsInt();
147                 logWriter.println("==> ThreadReference.SuspendCount command returns suspendCount = " + suspendCount);
148                 if ( suspendCount != 0 ) {
149                     logWriter.println("## FAILURE: Unexpected suspendCount for thread = " + threadName);
150                     logWriter.println("##          Expected suspendCount  = 0");
151                     suspendCountCommandFailed = true;
152                 }
153             }
154 
155             suspendNumber++;
156             logWriter.println("==> Send ThreadReference.Suspend command number of times = "
157                     + suspendNumber + "...");
158             int j = 0;
159             for (; j < suspendNumber; j++) {
160                 packet = new CommandPacket(
161                         JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
162                         JDWPCommands.ThreadReferenceCommandSet.SuspendCommand);
163                 packet.setNextValueAsThreadID(threadID);
164                 reply = debuggeeWrapper.vmMirror.performCommand(packet);
165                 if ( ! checkReplyPacketWithoutFail(reply, "ThreadReference.Suspend command") ) {
166                     break;
167                 }
168             }
169             if ( j < suspendNumber ) {
170                 suspendCommandFailed = true;
171                 continue;
172             }
173 
174             logWriter.println("==> Send ThreadReference.SuspendCount command...");
175             packet = new CommandPacket(
176                     JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
177                     JDWPCommands.ThreadReferenceCommandSet.SuspendCountCommand);
178             packet.setNextValueAsThreadID(threadID);
179             reply = debuggeeWrapper.vmMirror.performCommand(packet);
180             if ( ! checkReplyPacketWithoutFail(reply, "ThreadReference.SuspendCount command") ) {
181                 suspendCountCommandFailed = true;
182             } else {
183                 int suspendCount = reply.getNextValueAsInt();
184                 logWriter.println("==> ThreadReference.SuspendCount command returns suspendCount = " + suspendCount);
185                 if ( suspendCount != suspendNumber ) {
186                     logWriter.println("## FAILURE: Unexpected suspendCount for thread = " + threadName);
187                     logWriter.println("##          Expected suspendCount  = " + suspendNumber);
188                     suspendCountCommandFailed = true;
189                 }
190             }
191 
192             logWriter.println("==> Send ThreadReference.Resume command...");
193             packet = new CommandPacket(
194                     JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
195                     JDWPCommands.ThreadReferenceCommandSet.ResumeCommand);
196             packet.setNextValueAsThreadID(threadID);
197             reply = debuggeeWrapper.vmMirror.performCommand(packet);
198             if ( ! checkReplyPacketWithoutFail(reply, "ThreadReference.Resume command") ) {
199                 resumeCommandFailed = true;
200             }
201 
202             logWriter.println("==> Send ThreadReference.SuspendCount command...");
203             packet = new CommandPacket(
204                     JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
205                     JDWPCommands.ThreadReferenceCommandSet.SuspendCountCommand);
206             packet.setNextValueAsThreadID(threadID);
207             reply = debuggeeWrapper.vmMirror.performCommand(packet);
208             if ( ! checkReplyPacketWithoutFail(reply, "ThreadReference.SuspendCount command") ) {
209                 suspendCountCommandFailed = true;
210             } else {
211                 int suspendCount = reply.getNextValueAsInt();
212                 logWriter.println("==> ThreadReference.SuspendCount command returns suspendCount = " + suspendCount);
213                 if ( suspendCount != (suspendNumber -1) ) {
214                     logWriter.println("## FAILURE: Unexpected suspendCount for thread = " + threadName);
215                     logWriter.println("##          Expected suspendCount  = " + (suspendNumber-1));
216                     suspendCountCommandFailed = true;
217                 }
218             }
219 
220             if ( suspendNumber == 1 ) {
221                 continue;
222             }
223 
224             logWriter.println("==> Send ThreadReference.Resume command number of times = "
225                     + (suspendNumber - 1) + "...");
226             j = 0;
227             for (; j < (suspendNumber-1); j++) {
228                 packet = new CommandPacket(
229                         JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
230                         JDWPCommands.ThreadReferenceCommandSet.ResumeCommand);
231                 packet.setNextValueAsThreadID(threadID);
232                 reply = debuggeeWrapper.vmMirror.performCommand(packet);
233                 if ( ! checkReplyPacketWithoutFail(reply, "ThreadReference.Resume command") ) {
234                     break;
235                 }
236             }
237             if ( j < (suspendNumber-1) ) {
238                 resumeCommandFailed = true;
239                 continue;
240             }
241 
242             logWriter.println("==> Send ThreadReference.SuspendCount command...");
243             packet = new CommandPacket(
244                     JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
245                     JDWPCommands.ThreadReferenceCommandSet.SuspendCountCommand);
246             packet.setNextValueAsThreadID(threadID);
247             reply = debuggeeWrapper.vmMirror.performCommand(packet);
248             if ( ! checkReplyPacketWithoutFail(reply, "ThreadReference.SuspendCount command") ) {
249                 suspendCountCommandFailed = true;
250                 continue;
251             }
252             int suspendCount = reply.getNextValueAsInt();
253             logWriter.println("==> ThreadReference.SuspendCount command returns suspendCount = " + suspendCount);
254             if ( suspendCount != 0 ) {
255                 logWriter.println("## FAILURE: Unexpected suspendCount for thread = " + threadName);
256                 logWriter.println("##          Expected suspendCount  = 0");
257                 suspendCountCommandFailed = true;
258             }
259         }
260 
261         String errorMessage = "";
262         if ( suspendCountCommandFailed ) {
263             errorMessage = errorMessage + "## Error found out while ThreadReference.SuspendCount command performing!\n";
264         }
265         if ( suspendCommandFailed ) {
266             errorMessage = errorMessage + "## Error found out while ThreadReference.Suspend command performing!\n";
267         }
268         if ( resumeCommandFailed ) {
269             errorMessage = errorMessage + "## Error found out while ThreadReference.Resume command performing!\n";
270         }
271 
272         boolean testedThreadNotFound = false;
273         for (int i = 0; i < testedThreadsNumber; i++) {
274             if ( testedThreadsIDs[i] == 0 ) {
275                 logWriter.println("## FAILURE: Tested thread is not found out among debuggee threads!");
276                 logWriter.println("##          Thread name = " + testedThreadsNames[i]);
277                 testedThreadNotFound = true;
278             }
279         }
280 
281         if ( testedThreadNotFound ) {
282             errorMessage = errorMessage + "## Some of tested threads are not found!\n";
283         }
284         if ( ! errorMessage.equals("") ) {
285             synchronizer.sendMessage("FINISH");
286             printErrorAndFail("\ntestSuspendCount001 FAILED:\n" + errorMessage);
287         }
288 
289         synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
290         logWriter.println("\n==> Check ThreadReference.SuspendCount command when all debuggee is suspended...");
291         testedThreadsNames[testedThreadsNumber] = synchronizer.receiveMessage(); // debuggee main thread name
292 
293         testedThreadsIDs[testedThreadsNumber] = 0; // debuggee main thread ID
294         for (int i = 0; i < threads; i++) {
295             if ( testedThreadsNames[testedThreadsNumber].equals(allThreadsNames[i]) ) {
296                 testedThreadsIDs[testedThreadsNumber] = allThreadsIDs[i];
297                 break;
298             }
299         }
300         if ( testedThreadsIDs[testedThreadsNumber] == 0 ) {
301             setStaticIntField(debuggeeSignature, SuspendCountDebuggee.TO_FINISH_DEBUGGEE_FIELD_NAME, 99);
302             logWriter.println("## FAILURE: Debuggee main thread is not found out among debuggee threads!");
303             logWriter.println("##          Thread name = " + testedThreadsNames[testedThreadsNumber]);
304             printErrorAndFail("\nCan NOT found out debuggee main thread!");
305         }
306 
307         logWriter.println("\n==> Send VirtualMachine.Suspend command...");
308         CommandPacket packet = new CommandPacket(
309                 JDWPCommands.VirtualMachineCommandSet.CommandSetID,
310                 JDWPCommands.VirtualMachineCommandSet.SuspendCommand);
311         ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
312         int errorCode = reply.getErrorCode();
313         if ( errorCode !=  JDWPConstants.Error.NONE ) {
314             setStaticIntField(debuggeeSignature, SuspendCountDebuggee.TO_FINISH_DEBUGGEE_FIELD_NAME, 99);
315             logWriter.println("## FAILURE: VirtualMachine.Suspend command returns error = " + errorCode
316                     + "(" + JDWPConstants.Error.getName(errorCode) + ")");
317             printErrorAndFail("\nVirtualMachine.Suspend command FAILED!");
318         }
319 
320         for (int i = 0; i < (testedThreadsNumber+1); i++) {
321             logWriter.println("==> Send ThreadReference.SuspendCount command for thread = "
322                     + testedThreadsNames[i] + " ...");
323             packet = new CommandPacket(
324                     JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
325                     JDWPCommands.ThreadReferenceCommandSet.SuspendCountCommand);
326             packet.setNextValueAsThreadID(testedThreadsIDs[i]);
327             reply = debuggeeWrapper.vmMirror.performCommand(packet);
328             if ( ! checkReplyPacketWithoutFail(reply, "ThreadReference.SuspendCount command") ) {
329                 suspendCountCommandFailed = true;
330                 continue;
331             }
332             int suspendCount = reply.getNextValueAsInt();
333             logWriter.println("==> ThreadReference.SuspendCount command returns suspendCount = " + suspendCount);
334             if ( suspendCount != 1 ) {
335                 logWriter.println("## FAILURE: Unexpected suspendCount for thread = " + testedThreadsNames[i]);
336                 logWriter.println("##          Expected suspendCount  = 1");
337                 suspendCountCommandFailed = true;
338             }
339         }
340 
341         logWriter.println("\n==> Send VirtualMachine.Resume command ...");
342         packet = new CommandPacket(
343                 JDWPCommands.VirtualMachineCommandSet.CommandSetID,
344                 JDWPCommands.VirtualMachineCommandSet.ResumeCommand);
345         reply = debuggeeWrapper.vmMirror.performCommand(packet);
346         if ( ! checkReplyPacketWithoutFail(reply, "VirtualMachine.Resume command") ) {
347             resumeCommandFailed = true;
348         } else {
349             logWriter.println("\n==> Check ThreadReference.SuspendCount command after debuggee is resumed...");
350             for (int i = 0; i < (testedThreadsNumber+1); i++) {
351                 logWriter.println("==> Send ThreadReference.SuspendCount command for thread = "
352                         + testedThreadsNames[i] + " ...");
353                 packet = new CommandPacket(
354                         JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
355                         JDWPCommands.ThreadReferenceCommandSet.SuspendCountCommand);
356                 packet.setNextValueAsThreadID(testedThreadsIDs[i]);
357                 reply = debuggeeWrapper.vmMirror.performCommand(packet);
358                 if ( ! checkReplyPacketWithoutFail(reply, "ThreadReference.SuspendCount command") ) {
359                     suspendCountCommandFailed = true;
360                     continue;
361                 }
362                 int suspendCount = reply.getNextValueAsInt();
363                 logWriter.println("==> ThreadReference.SuspendCount command returns suspendCount = " + suspendCount);
364                 if ( suspendCount != 0 ) {
365                     logWriter.println("## FAILURE: Unexpected suspendCount for thread = " + testedThreadsNames[i]);
366                     logWriter.println("##          Expected suspendCount  = 0");
367                     suspendCountCommandFailed = true;
368                 }
369             }
370         }
371 
372         setStaticIntField(debuggeeSignature, SuspendCountDebuggee.TO_FINISH_DEBUGGEE_FIELD_NAME, 99);
373 
374         if ( suspendCountCommandFailed ) {
375             errorMessage = "## Error found out while ThreadReference.SuspendCount command performing!\n";
376         }
377 
378         if ( resumeCommandFailed ) {
379             errorMessage = "## Error found out while VirtualMachine.Resume command performing!\n";
380         }
381 
382         if ( ! errorMessage.equals("") ) {
383             printErrorAndFail("\ntestSuspendCount001 FAILED:\n" + errorMessage);
384         }
385         logWriter.println("\n==> testSuspendCount001 - OK!");
386     }
387 /*
388     protected int setStaticIntField (String classSignature, String fieldName, int newValue) {
389 
390         long classID = debuggeeWrapper.vmMirror.getClassID(classSignature);
391         if ( classID == -1 ) {
392             logWriter.println
393             ("## setStaticIntField(): Can NOT get classID for class signature = '"
394                     + classSignature + "'");
395             return -1;
396         }
397 
398         long fieldID =
399             debuggeeWrapper.vmMirror.getFieldID(classID, fieldName);
400         if ( fieldID == -1 ) {
401             logWriter.println
402             ("## setStaticIntField(): Can NOT get fieldID for field = '"
403                     + fieldName + "'");
404             return -1;
405         }
406 
407         CommandPacket packet = new CommandPacket(
408                 JDWPCommands.ClassTypeCommandSet.CommandSetID,
409                 JDWPCommands.ClassTypeCommandSet.SetValuesCommand);
410         packet.setNextValueAsReferenceTypeID(classID);
411         packet.setNextValueAsInt(1);
412         packet.setNextValueAsFieldID(fieldID);
413         packet.setNextValueAsInt(newValue);
414 
415         ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
416         int errorCode = reply.getErrorCode();
417         if ( errorCode !=  JDWPConstants.Error.NONE ) {
418             logWriter.println
419             ("## setStaticIntField(): Can NOT set value for field = '"
420                     + fieldName + "' in class = '" + classSignature
421                     + "'; ClassType.SetValues command reurns error = " + errorCode);
422             return -1;
423         }
424         return 0;
425     }
426 */
427 }
428