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.ReferenceType;
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.ReplyPacket;
25 import org.apache.harmony.jpda.tests.framework.jdwp.Value;
26 import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase;
27 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
28 
29 public class InstancesTest extends JDWPSyncTestCase {
30 
31     static final int testStatusPassed = 0;
32 
33     static final int testStatusFailed = -1;
34 
35     static int maxInstances;
36 
37     static final String thisCommandName = "ReferenceType.Instances command";
38 
39     static String thisTestName;
40 
41     static final String debuggeeSignature = "Lorg/apache/harmony/jpda/tests/jdwp/ReferenceType/InstancesDebuggee;";
42 
43     static final String mockClassSignature = "Lorg/apache/harmony/jpda/tests/jdwp/ReferenceType/MockClass;";
44 
45     static final String stringSignature = "Ljava/lang/String;";
46 
47     static final String intArraySignature = "[I";
48     @Override
getDebuggeeClassName()49     protected String getDebuggeeClassName() {
50         return "org.apache.harmony.jpda.tests.jdwp.ReferenceType.InstancesDebuggee";
51     }
52 
53     /**
54      * All test cases is based on this process. <BR>
55      * It starts InstancesDebuggee class, requests referenceTypeId for
56      * MockClass class by VirtualMachine.ClassesBySignature command, then performs
57      * ReferenceType.Instances command and checks that returned reachable
58      * objects are expected ones.
59      */
runTestInstances()60     private void runTestInstances() {
61         // check capability, relevant for this test
62         logWriter.println("=> Check capability: canGetInstanceInfo");
63         debuggeeWrapper.vmMirror.capabilities();
64         boolean isCapability = debuggeeWrapper.vmMirror.targetVMCapabilities.canGetInstanceInfo;
65         if (!isCapability) {
66             logWriter
67                     .println("##WARNING: this VM dosn't possess capability: canGetInstanceInfo");
68             return;
69         }
70 
71         logWriter.println("==> " + thisTestName + " for " + thisCommandName
72                 + ": START...");
73         synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
74 
75         long mockClassRefTypeID = getClassIDBySignature(mockClassSignature);
76         long debuggeeRefTypeID = getClassIDBySignature(debuggeeSignature);
77 
78         //Get the number of reachable objects in debuggee class
79         long reachableObjNumID = debuggeeWrapper.vmMirror.getFieldID(
80                 debuggeeRefTypeID, "reachableObjNum");
81         long[] fieldIDs = new long[1];
82         fieldIDs[0] = reachableObjNumID;
83 
84         Value[] values = debuggeeWrapper.vmMirror.getReferenceTypeValues(
85                 debuggeeRefTypeID, fieldIDs);
86         int expectedReachableObjNum = values[0].getIntValue();
87 
88         logWriter.println("=> ReachableObjNum in debuggee is: " + expectedReachableObjNum);
89 
90         //maxInstances is maximum number of instances to return.
91         //So expectedReachableObjNum should be less than maxInstances
92         if (expectedReachableObjNum > maxInstances && maxInstances > 0) {
93             expectedReachableObjNum = maxInstances;
94         }
95 
96         logWriter.println("=> CHECK: send " + thisCommandName
97                 + " and check reply for ERROR...");
98 
99         CommandPacket InstancesCommand = new CommandPacket(
100                 JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
101                 JDWPCommands.ReferenceTypeCommandSet.InstancesCommand);
102         InstancesCommand.setNextValueAsReferenceTypeID(mockClassRefTypeID);
103         InstancesCommand.setNextValueAsInt(maxInstances);
104 
105         ReplyPacket checkedReply = debuggeeWrapper.vmMirror
106                 .performCommand(InstancesCommand);
107         InstancesCommand = null;
108 
109         short errorCode = checkedReply.getErrorCode();
110         if (errorCode != JDWPConstants.Error.NONE) {
111             if (errorCode == JDWPConstants.Error.NOT_IMPLEMENTED) {
112                 logWriter
113                         .println("=> CHECK PASSED: Expected error (NOT_IMPLEMENTED) is returned");
114                 return;
115             }
116             else if(errorCode == JDWPConstants.Error.ILLEGAL_ARGUMENT) {
117                 logWriter
118                         .println("=> CHECK PASSED: Expected error (ILLEGAL_ARGUMENT) is returned");
119                 return;
120             }
121 
122         }
123 
124         //Get the number of instances that returned.
125         int reachableInstancesNum = checkedReply.getNextValueAsInt();
126         assertEquals(thisCommandName + "returned instances number is wrong.",
127                 expectedReachableObjNum, reachableInstancesNum, null, null);
128 
129         long mockClassFieldID = debuggeeWrapper.vmMirror.getFieldID(
130                 mockClassRefTypeID, "isReachable");
131         for (int i = 0; i < reachableInstancesNum; i++) {
132             //Get the tagged-objectID
133             byte tag = checkedReply.getNextValueAsByte();
134             assertEquals(thisCommandName
135                     + "returned object tag is invalid.", 'L', tag, null, null);
136 
137             long objectID = checkedReply.getNextValueAsObjectID();
138             logWriter.println("=> ObjectID is: " + objectID);
139             values = debuggeeWrapper.vmMirror.getObjectReferenceValues(
140                     objectID, new long[] { mockClassFieldID });
141             boolean isReachable = values[0].getBooleanValue();
142             if (!isReachable) {
143                 printErrorAndFail(thisCommandName
144                         + "returned object is not reachable.");
145             }
146         }
147         logWriter.println("=> CHECK: PASSED: expected instances are returned:");
148         logWriter.println("=> Returned reachable instances number is" + expectedReachableObjNum);
149 
150         synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
151         logWriter.println("==> " + thisTestName + " for " + thisCommandName + ": FINISH");
152         assertAllDataRead(checkedReply);
153 
154     }
155 
156     /**
157      * This testcase exercises ReferenceType.Instances command. <BR>
158      * The test starts InstancesDebuggee class, requests referenceTypeId for
159      * MockClass class by VirtualMachine.ClassesBySignature command, then performs
160      * ReferenceType.Instances command and checks that returned reachable
161      * objects are expected ones. Maximum number of instances is zero, so all instances
162      * are returned.
163      */
testInstances001()164     public void testInstances001() {
165         thisTestName = "testInstances001";
166         maxInstances = 0;
167         runTestInstances();
168     }
169 
170     /**
171      * This testcase exercises ReferenceType.Instances command. <BR>
172      * The test starts InstancesDebuggee class, requests referenceTypeId for
173      * MockClass class by VirtualMachine.ClassesBySignature command, then performs
174      * ReferenceType.Instances command. Since maximum number of instances is negtive, so
175      * ILLEGAL_ARGUMENT exception are replied.
176      */
testInstances002()177     public void testInstances002() {
178         thisTestName = "testInstances002";
179         maxInstances = -1;
180         runTestInstances();
181     }
182 
183     /**
184      * This testcase exercises ReferenceType.Instances command. <BR>
185      * The test starts InstancesDebuggee class, requests referenceTypeId for
186      * MockClass class by VirtualMachine.ClassesBySignature command, then performs
187      * ReferenceType.Instances command and checks that returned reachable
188      * objects are expected ones. Maximum number of instances is more than the reachable
189      * objects of this reference type, so all instances are returned.
190      */
testInstances003()191     public void testInstances003() {
192         thisTestName = "testInstances003";
193         maxInstances = 20;
194         runTestInstances();
195     }
196 
197     /**
198      * This testcase exercises ReferenceType.Instances command. <BR>
199      * The test starts InstancesDebuggee class, requests referenceTypeId for
200      * MockClass class by VirtualMachine.ClassesBySignature command, then performs
201      * ReferenceType.Instances command and checks that returned reachable
202      * objects are expected ones. Maximum number of instances is less than the reachable
203      * objects of this reference type, so maximum number of instances are returned.
204      */
testInstances004()205     public void testInstances004() {
206         thisTestName = "testInstances004";
207         maxInstances = 1;
208         runTestInstances();
209     }
210 
211     /**
212      * It starts InstancesDebuggee class, requests referenceTypeId for String
213      * class by VirtualMachine.ClassesBySignature command, then performs
214      * ReferenceType.Instances command and checks that returned reachable String
215      * objects are expected.
216      */
testInstances_String()217     public void testInstances_String() {
218         String thisTestName = "testInstances_String";
219 
220         // check capability, relevant for this test
221         logWriter.println("=> Check capability: canGetInstanceInfo");
222         debuggeeWrapper.vmMirror.capabilities();
223         boolean isCapability = debuggeeWrapper.vmMirror.targetVMCapabilities.canGetInstanceInfo;
224         if (!isCapability) {
225             logWriter
226                     .println("##WARNING: this VM dosn't possess capability: canGetInstanceInfo");
227             return;
228         }
229 
230         logWriter.println("==> " + thisTestName + " for " + thisCommandName
231                 + ": START...");
232         synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
233 
234         long stringRefTypeID = getClassIDBySignature(stringSignature);
235         maxInstances = 10;
236 
237         logWriter.println("=> CHECK: send " + thisCommandName
238                 + " and check reply for ERROR...");
239 
240         CommandPacket InstancesCommand = new CommandPacket(
241                 JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
242                 JDWPCommands.ReferenceTypeCommandSet.InstancesCommand);
243         InstancesCommand.setNextValueAsReferenceTypeID(stringRefTypeID);
244         InstancesCommand.setNextValueAsInt(maxInstances);
245 
246         ReplyPacket checkedReply = debuggeeWrapper.vmMirror
247                 .performCommand(InstancesCommand);
248         InstancesCommand = null;
249         checkReplyPacket(checkedReply, thisTestName);
250 
251         // Get the number of instances that returned.
252         int reachableInstancesNum = checkedReply.getNextValueAsInt();
253 
254         for (int i = 0; i < reachableInstancesNum; i++) {
255             // Get the tagged-objectID
256             byte tag = checkedReply.getNextValueAsByte();
257             assertEquals(thisCommandName + "returned String tag is invalid.",
258                     's', tag, null, null);
259             long objectID = checkedReply.getNextValueAsObjectID();
260             logWriter.println("=> ObjectID is: " + objectID);
261 
262         }
263         logWriter.println("=> CHECK: PASSED: expected instances are returned:");
264         synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
265         logWriter.println("==> " + thisTestName + " for " + thisCommandName
266                 + ": FINISH");
267         assertAllDataRead(checkedReply);
268 
269     }
270 
271     /**
272      * It starts InstancesDebuggee class, requests referenceTypeId for Array
273      * class by VirtualMachine.ClassesBySignature command, then performs
274      * ReferenceType.Instances command and checks that returned reachable Array
275      * objects are expected.
276      */
testInstances_Array()277     public void testInstances_Array() {
278         String thisTestName = "testInstances_Array";
279 
280         // check capability, relevant for this test
281         logWriter.println("=> Check capability: canGetInstanceInfo");
282         debuggeeWrapper.vmMirror.capabilities();
283         boolean isCapability = debuggeeWrapper.vmMirror.targetVMCapabilities.canGetInstanceInfo;
284         if (!isCapability) {
285             logWriter
286                     .println("##WARNING: this VM dosn't possess capability: canGetInstanceInfo");
287             return;
288         }
289 
290         logWriter.println("==> " + thisTestName + " for " + thisCommandName
291                 + ": START...");
292         synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
293 
294         long intArrayRefTypeID = getClassIDBySignature(intArraySignature);
295         maxInstances = 10;
296 
297         logWriter.println("=> CHECK: send " + thisCommandName
298                 + " and check reply for ERROR...");
299 
300         CommandPacket InstancesCommand = new CommandPacket(
301                 JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
302                 JDWPCommands.ReferenceTypeCommandSet.InstancesCommand);
303         InstancesCommand.setNextValueAsReferenceTypeID(intArrayRefTypeID);
304         InstancesCommand.setNextValueAsInt(maxInstances);
305 
306         ReplyPacket checkedReply = debuggeeWrapper.vmMirror
307                 .performCommand(InstancesCommand);
308         InstancesCommand = null;
309         checkReplyPacket(checkedReply, thisTestName);
310 
311         // Get the number of instances that returned.
312         int reachableInstancesNum = checkedReply.getNextValueAsInt();
313 
314         for (int i = 0; i < reachableInstancesNum; i++) {
315             // Get the tagged-objectID
316             byte tag = checkedReply.getNextValueAsByte();
317             assertEquals(thisCommandName + "returned Array tag is invalid.",
318                     '[', tag, null, null);
319             long objectID = checkedReply.getNextValueAsObjectID();
320             logWriter.println("=> ObjectID is: " + objectID);
321 
322         }
323         logWriter.println("=> CHECK: PASSED: expected instances are returned:");
324         synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
325         logWriter.println("==> " + thisTestName + " for " + thisCommandName
326                 + ": FINISH");
327         assertAllDataRead(checkedReply);
328     }
329 }
330