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.ThreadReference;
20 
21 import org.apache.harmony.jpda.tests.framework.TestErrorException;
22 import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
23 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
24 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
25 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
26 import org.apache.harmony.jpda.tests.framework.jdwp.Value;
27 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants.Tag;
28 import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase;
29 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
30 
31 /**
32  * JDWP Unit test for ThreadReference.ForceEarlyReturn command.
33  */
34 public class ForceEarlyReturnTest extends JDWPSyncTestCase {
35 
36     static final String thisCommandName = "ThreadReference.ForceEarlyReturn command ";
37 
38     static String thisTestName;
39 
40     static String testThreadName;
41 
42     static final int EXPECTED_INT = 5;
43 
44     static final short EXPECTED_SHORT = 20;
45 
46     static final char EXPECTED_CHAR = 'A';
47 
48     static final byte EXPECTED_BYTE = 30;
49 
50     static final boolean EXPECTED_BOOLEAN = true;
51 
52     static Value expectedValue;
53 
54     static final String debuggeeSignature = "Lorg/apache/harmony/jpda/tests/jdwp/ThreadReference/ForceEarlyReturnDebuggee;";
55 
getDebuggeeClassName()56     protected String getDebuggeeClassName() {
57         return "org.apache.harmony.jpda.tests.jdwp.ThreadReference.ForceEarlyReturnDebuggee";
58     }
59 
60     // ForceEarlyReturn needs canForceEarlyReturn VM capability support
isCapability()61     private boolean isCapability() {
62         // check capability, relevant for this test
63         logWriter.println("=> Check capability: canForceEarlyReturn");
64         debuggeeWrapper.vmMirror.capabilities();
65         boolean isCapability = debuggeeWrapper.vmMirror.targetVMCapabilities.canForceEarlyReturn;
66         return isCapability;
67     }
68 
toString(Value value)69     private String toString(Value value) {
70 
71         switch (value.getTag()) {
72         case JDWPConstants.Tag.BOOLEAN_TAG:
73             return (new Boolean(value.getBooleanValue())).toString();
74         case JDWPConstants.Tag.BYTE_TAG:
75             return (new Byte(value.getByteValue())).toString();
76         case JDWPConstants.Tag.CHAR_TAG:
77             return (new Character(value.getCharValue())).toString();
78         case JDWPConstants.Tag.INT_TAG:
79             return (new Integer(value.getIntValue())).toString();
80         case JDWPConstants.Tag.SHORT_TAG:
81             return (new Short(value.getShortValue())).toString();
82         }
83         return "";
84     }
85 
RunTestForceEarlyReturn()86     public void RunTestForceEarlyReturn() {
87         logWriter.println("==> " + thisTestName + " for " + thisCommandName
88                 + ": START...");
89         synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
90 
91         if (!isCapability()) {
92             logWriter
93                     .println("##WARNING: this VM dosn't possess capability: canForceEarlyReturn");
94             return;
95         }
96         // Tell debuggee to start a thread
97         synchronizer.sendMessage(testThreadName);
98 
99         // Wait until the func_Int is processing.
100         synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
101 
102         // Getting ID of the tested thread
103         logWriter.println("==> testedThreadName = " + testThreadName);
104         logWriter.println("==> Get testedThreadID...");
105         long testedThreadID = debuggeeWrapper.vmMirror
106                 .getThreadID(testThreadName);
107         logWriter.println("==> Get testedThreadID is" + testedThreadID);
108 
109         // Suspend the VM before perform command
110         logWriter.println("==> testedThreadID = " + testedThreadID);
111         logWriter.println("==> suspend testedThread...");
112         debuggeeWrapper.vmMirror.suspendThread(testedThreadID);
113 
114         // Compose the ForceEarlyReturn command
115         CommandPacket forceEarlyReturnPacket = new CommandPacket(
116                 JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
117                 JDWPCommands.ThreadReferenceCommandSet.ForceEarlyReturnCommand);
118         forceEarlyReturnPacket.setNextValueAsThreadID(testedThreadID);
119         forceEarlyReturnPacket.setNextValueAsValue(expectedValue);
120 
121         // Perform the command
122         logWriter.println("==> Perform " + thisCommandName);
123         ReplyPacket forceEarlyReturnReply = debuggeeWrapper.vmMirror
124                 .performCommand(forceEarlyReturnPacket);
125         forceEarlyReturnPacket = null;
126 
127         checkReplyPacket(forceEarlyReturnReply,
128                 "ThreadReference::ForceEarlyReturn command");
129 
130         // Resume the thread
131         logWriter.println("==> testedThreadID = " + testedThreadID);
132         logWriter.println("==> resume testedThread...");
133         debuggeeWrapper.vmMirror.resumeThread(testedThreadID);
134 
135         String actualValue = synchronizer.receiveMessage();
136         // Check the early returned value
137         if (!actualValue.equals(toString(expectedValue))) {
138             printErrorAndFail(thisCommandName
139                     + "returned value is not set by ForceEarlyReturn command"
140                     + " expected:<" + expectedValue.toString() + "> but was:<"
141                     + actualValue + ">");
142         }
143         logWriter
144                 .println("==> CHECK: PASSED: returned value does set by ForceEarlyReturn command.");
145         logWriter.println("==> Returned value: " + actualValue);
146 
147         synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
148     }
149 
150     /**
151      * This testcase exercises ThreadReference.ForceEarlyReturn command. <BR>
152      * At first the test starts ForceEarlyReturnDebuggee and send it the thread
153      * name through which to start a specific thread. Then the test performs the
154      * ThreadReference.ForceEarlyReturn command for the tested thread and gets
155      * the returned value of the called method. The returned value should be
156      * equal to the value which is used in ForceEarlyReturn Command. In this
157      * testcase, an Int value is returned.
158      */
testForceEarlyReturn_ReturnInt()159     public void testForceEarlyReturn_ReturnInt() {
160         thisTestName = "testForceEarlyReturn_ReturnInt";
161         testThreadName = ForceEarlyReturnDebuggee.THREAD_INT;
162         expectedValue = new Value(EXPECTED_INT);
163         RunTestForceEarlyReturn();
164     }
165 
166     /**
167      * This testcase exercises ThreadReference.ForceEarlyReturn command. <BR>
168      * At first the test starts ForceEarlyReturnDebuggee and send it the thread
169      * name through which to start a specific thread. Then the test performs the
170      * ThreadReference.ForceEarlyReturn command for the tested thread and gets
171      * the returned value of the called method. The returned value should be
172      * equal to the value which is used in ForceEarlyReturn Command. In this
173      * testcase, an Short value is returned.
174      */
testForceEarlyReturn_ReturnShort()175     public void testForceEarlyReturn_ReturnShort() {
176         thisTestName = "testForceEarlyReturn_ReturnShort";
177         testThreadName = ForceEarlyReturnDebuggee.THREAD_SHORT;
178         expectedValue = new Value(EXPECTED_SHORT);
179         RunTestForceEarlyReturn();
180     }
181 
182     /**
183      * This testcase exercises ThreadReference.ForceEarlyReturn command. <BR>
184      * At first the test starts ForceEarlyReturnDebuggee and send it the thread
185      * name through which to start a specific thread. Then the test performs the
186      * ThreadReference.ForceEarlyReturn command for the tested thread and gets
187      * the returned value of the called method. The returned value should be
188      * equal to the value which is used in ForceEarlyReturn Command. In this
189      * testcase, an Byte value is returned.
190      */
testForceEarlyReturn_ReturnByte()191     public void testForceEarlyReturn_ReturnByte() {
192         thisTestName = "testForceEarlyReturn_ReturnByte";
193         testThreadName = ForceEarlyReturnDebuggee.THREAD_BYTE;
194         expectedValue = new Value(EXPECTED_BYTE);
195         RunTestForceEarlyReturn();
196     }
197 
198     /**
199      * This testcase exercises ThreadReference.ForceEarlyReturn command. <BR>
200      * At first the test starts ForceEarlyReturnDebuggee and send it the thread
201      * name through which to start a specific thread. Then the test performs the
202      * ThreadReference.ForceEarlyReturn command for the tested thread and gets
203      * the returned value of the called method. The returned value should be
204      * equal to the value which is used in ForceEarlyReturn Command. In this
205      * testcase, an Char value is returned.
206      */
testForceEarlyReturn_ReturnChar()207     public void testForceEarlyReturn_ReturnChar() {
208         thisTestName = "testForceEarlyReturn_ReturnChar";
209         testThreadName = ForceEarlyReturnDebuggee.THREAD_CHAR;
210         expectedValue = new Value(EXPECTED_CHAR);
211         RunTestForceEarlyReturn();
212     }
213 
214     /**
215      * This testcase exercises ThreadReference.ForceEarlyReturn command. <BR>
216      * At first the test starts ForceEarlyReturnDebuggee and send it the thread
217      * name through which to start a specific thread. Then the test performs the
218      * ThreadReference.ForceEarlyReturn command for the tested thread and gets
219      * the returned value of the called method. The returned value should be
220      * equal to the value which is used in ForceEarlyReturn Command. In this
221      * testcase, an Boolean value is returned.
222      */
testForceEarlyReturn_ReturnBoolean()223     public void testForceEarlyReturn_ReturnBoolean() {
224         thisTestName = "testForceEarlyReturn_ReturnBoolean";
225         testThreadName = ForceEarlyReturnDebuggee.THREAD_BOOLEAN;
226         expectedValue = new Value(EXPECTED_BOOLEAN);
227         RunTestForceEarlyReturn();
228     }
229 
230     /**
231      * This testcase exercises ThreadReference.ForceEarlyReturn command. <BR>
232      * At first the test starts ForceEarlyReturnDebuggee and send it the thread
233      * name through which to start a specific thread. Then the test performs the
234      * ThreadReference.ForceEarlyReturn command for the tested thread without
235      * suspending the VM. In this testcase, THREAD_NOT_SUSPENDED exception is returned.
236      */
testForceEarlyReturn_NotSuspended()237     public void testForceEarlyReturn_NotSuspended() {
238         thisTestName = "testForceEarlyReturn_NotSuspended";
239         testThreadName = "test";
240         expectedValue = new Value(Tag.VOID_TAG, 0);
241 
242         logWriter.println("==> " + thisTestName + " for " + thisCommandName
243                 + ": START...");
244         synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
245 
246         if (!isCapability()) {
247             logWriter
248                     .println("##WARNING: this VM dosn't possess capability: canForceEarlyReturn");
249             return;
250         }
251         // Tell debuggee to start a thread
252         synchronizer.sendMessage(testThreadName);
253 
254         // Wait thread signal.
255         synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
256 
257         // Getting ID of the tested thread
258         logWriter.println("==> testedThreadName = " + testThreadName);
259         logWriter.println("==> Get testedThreadID...");
260         long testedThreadID = debuggeeWrapper.vmMirror
261                 .getThreadID(testThreadName);
262         logWriter.println("==> Get testedThreadID is" + testedThreadID);
263 
264         // Compose the ForceEarlyReturn command
265         CommandPacket forceEarlyReturnPacket = new CommandPacket(
266                 JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
267                 JDWPCommands.ThreadReferenceCommandSet.ForceEarlyReturnCommand);
268         forceEarlyReturnPacket.setNextValueAsThreadID(testedThreadID);
269         forceEarlyReturnPacket.setNextValueAsValue(expectedValue);
270 
271         // Perform the command
272         logWriter.println("==> Perform " + thisCommandName);
273         ReplyPacket forceEarlyReturnReply = debuggeeWrapper.vmMirror
274                 .performCommand(forceEarlyReturnPacket);
275         forceEarlyReturnPacket = null;
276 
277         short errorCode = forceEarlyReturnReply.getErrorCode();
278         if (errorCode != JDWPConstants.Error.NONE) {
279             if (errorCode == JDWPConstants.Error.THREAD_NOT_SUSPENDED) {
280                 logWriter
281                         .println("=> CHECK PASSED: Expected error (THREAD_NOT_SUSPENDED) is returned");
282                 synchronizer.sendMessage("ThreadExit");
283                 synchronizer
284                         .sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
285                 return;
286             }
287         }
288         printErrorAndFail(thisCommandName
289                 + " should throw exception when VM is not suspended.");
290 
291     }
292 }
293