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