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
19package org.apache.harmony.jpda.tests.jdwp.ReferenceType;
20
21import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
22import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
23import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
24import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
25import org.apache.harmony.jpda.tests.framework.jdwp.Value;
26import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase;
27import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
28
29public 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
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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