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.VirtualMachine;
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 InstanceCountsTest extends JDWPSyncTestCase {
30
31    static final int testStatusPassed = 0;
32
33    static final int testStatusFailed = -1;
34
35    static final String thisCommandName = "VirtualMachine.InstanceCounts command ";
36
37    static final String mockClass1Signature = "Lorg/apache/harmony/jpda/tests/jdwp/VirtualMachine/MockClass1;";
38
39    static final String mockClass2Signature = "Lorg/apache/harmony/jpda/tests/jdwp/VirtualMachine/MockClass2;";
40
41    static final String debuggeeSignature = "Lorg/apache/harmony/jpda/tests/jdwp/VirtualMachine/InstanceCountsDebuggee;";
42
43    protected String getDebuggeeClassName() {
44        return "org.apache.harmony.jpda.tests.jdwp.VirtualMachine.InstanceCountsDebuggee";
45    }
46
47    // InstanceCounts need canGetInstanceInfo VM capability support
48    private boolean isCapability() {
49        // check capability, relevant for this test
50        logWriter.println("=> Check capability: canGetInstanceInfo");
51        debuggeeWrapper.vmMirror.capabilities();
52        boolean isCapability = debuggeeWrapper.vmMirror.targetVMCapabilities.canGetInstanceInfo;
53        return isCapability;
54    }
55
56    /**
57     * This testcase exercises VirtualMachine.InstanceCounts command.
58     * <BR>The test starts InstanceCountsDebuggee class, requests referenceTypeId,
59     * MockClass1, MockClass2 for this class by VirtualMachine.ClassesBySignature command,
60     * then performs VirtualMachine.InstanceCounts command and checks that returned
61     * Reachable Objects of MockClass1 and MockClass2 are equal to the actual ones.
62     */
63    public void testInstanceCounts_Normal() {
64        String thisTestName = "testInstanceCounts_Normal";
65
66        if (!isCapability()) {
67            logWriter.println("##WARNING: this VM dosn't possess capability: canGetInstanceInfo");
68            return;
69        }
70
71        logWriter.println("==> " + thisTestName + " for " + thisCommandName + ": START...");
72        synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
73
74        long debuggeeRefTypeID = getClassIDBySignature(debuggeeSignature);
75        long mockClassRefTypeIDOfClass1 = getClassIDBySignature(mockClass1Signature);
76        long mockClassRefTypeIDOfClass2 = getClassIDBySignature(mockClass2Signature);
77
78        //Get the number of reachable objects of MockClass1 and MockClass2 in debuggee class
79        long reachableObjNumOfClass1ID = debuggeeWrapper.vmMirror.getFieldID(
80                debuggeeRefTypeID, "reachableObjNumOfClass1");
81        long reachableObjNumOfClass2ID = debuggeeWrapper.vmMirror.getFieldID(
82                debuggeeRefTypeID, "reachableObjNumOfClass2");
83
84        long[] fieldIDs = new long[2];
85        fieldIDs[0] = reachableObjNumOfClass1ID;
86        fieldIDs[1] = reachableObjNumOfClass2ID;
87
88        Value[] values = debuggeeWrapper.vmMirror.getReferenceTypeValues(
89                debuggeeRefTypeID, fieldIDs);
90        int expectedObjNumOfClass1 = values[0].getIntValue();
91        int expectedObjNumOfClass2 = values[1].getIntValue();
92
93        logWriter.println("=> ReachableObjNum of MockClass1 in debuggee is: " + expectedObjNumOfClass1);
94        logWriter.println("=> ReachableObjNum of MockClass2 in debuggee is: " + expectedObjNumOfClass2);
95
96        logWriter.println("=> CHECK: send " + thisCommandName
97                + " and check reply for ERROR...");
98
99        // Compose InstanceCounts command
100        CommandPacket InstanceCountsCommand = new CommandPacket(
101                JDWPCommands.VirtualMachineCommandSet.CommandSetID,
102                JDWPCommands.VirtualMachineCommandSet.InstanceCountsCommand);
103
104        final int refTypesCount = 2;
105        InstanceCountsCommand.setNextValueAsInt(refTypesCount);
106        InstanceCountsCommand.setNextValueAsReferenceTypeID(mockClassRefTypeIDOfClass1);
107        InstanceCountsCommand.setNextValueAsReferenceTypeID(mockClassRefTypeIDOfClass2);
108
109        // Perform InstanceCounts command and attain reply package
110        ReplyPacket checkedReply = debuggeeWrapper.vmMirror
111                .performCommand(InstanceCountsCommand);
112        InstanceCountsCommand = null;
113
114        short errorCode = checkedReply.getErrorCode();
115        if (errorCode != JDWPConstants.Error.NONE) {
116            if(errorCode == JDWPConstants.Error.ILLEGAL_ARGUMENT) {
117                logWriter.println("=> CHECK PASSED: Expected error (ILLEGAL_ARGUMENT) is returned");
118                return;
119            }
120        }
121
122        //Check the reference types count that returned.
123        int returnedRefTypesCount = checkedReply.getNextValueAsInt();
124        assertEquals(thisCommandName + "returned reference types count is wrong.",
125                refTypesCount, returnedRefTypesCount, null, null);
126        logWriter.println("=> CHECK: PASSED: expected reference types count is returned:");
127        logWriter.println("=> Returned reference types count is " + returnedRefTypesCount);
128
129        long returnedObjNumOfClass1 = checkedReply.getNextValueAsLong();
130        assertEquals(thisCommandName + "returned instance count of MockClass1 is wrong.",
131                expectedObjNumOfClass1, returnedObjNumOfClass1, null, null);
132        logWriter.println("=> CHECK: PASSED: expected instance count of MockClass1 is returned:");
133        logWriter.println("=> Returned instance count of MockClass1 is " + returnedObjNumOfClass1);
134
135        long returnedObjNumOfClass2 = checkedReply.getNextValueAsLong();
136        assertEquals(thisCommandName + "returned instance count of MockClass2 is wrong.",
137                expectedObjNumOfClass2, returnedObjNumOfClass2, null, null);
138        logWriter.println("=> CHECK: PASSED: expected instance count of MockClass2 is returned:");
139        logWriter.println("=> Returned instance count of MockClass2 is " + returnedObjNumOfClass2);
140
141        synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
142        logWriter.println("==> " + thisTestName + " for " + thisCommandName + ": FINISH");
143        assertAllDataRead(checkedReply);
144    }
145
146    /**
147     * This testcase exercises ReferenceType.InstanceCounts command. <BR>
148     * Compose a InstanceCounts command with negative reference types count
149     * The vm should throw a ILLEGAL_ARGUMENT exception.
150     */
151    public void testInstanceCounts_IllegalArgument() {
152        String thisTestName = "testInstanceCounts_IllegalArgument";
153
154        if (!isCapability()) {
155            logWriter.println("##WARNING: this VM dosn't possess capability: canGetInstanceInfo");
156            return;
157        }
158
159        int refTypesCount = -1;
160
161        logWriter.println("==> " + thisTestName + " for " + thisCommandName + ": START...");
162        synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
163
164        // Compose InstanceCounts commnad
165        CommandPacket InstanceCountsCommand = new CommandPacket(
166                JDWPCommands.VirtualMachineCommandSet.CommandSetID,
167                JDWPCommands.VirtualMachineCommandSet.InstanceCountsCommand);
168
169        InstanceCountsCommand.setNextValueAsInt(refTypesCount);
170        InstanceCountsCommand.setNextValueAsReferenceTypeID(0);
171
172        // Perform InstanceCounts command and attain reply package
173        ReplyPacket checkedReply = debuggeeWrapper.vmMirror
174                .performCommand(InstanceCountsCommand);
175        InstanceCountsCommand = null;
176
177        short errorCode = checkedReply.getErrorCode();
178        if (errorCode != JDWPConstants.Error.NONE) {
179            if (errorCode == JDWPConstants.Error.NOT_IMPLEMENTED) {
180                logWriter.println("=> CHECK PASSED: Expected error (NOT_IMPLEMENTED) is returned");
181                return;
182            }
183            else if(errorCode == JDWPConstants.Error.ILLEGAL_ARGUMENT) {
184                logWriter.println("=> CHECK PASSED: Expected error (ILLEGAL_ARGUMENT) is returned");
185                return;
186            }
187        }
188        printErrorAndFail(thisCommandName + " should throw ILLEGAL_ARGUMENT exception when refTypesCount is negative.");
189    }
190
191
192    /**
193     * This testcase exercises ReferenceType.InstanceCounts command. <BR>
194     * Compose a InstanceCounts command with zero reference types count.
195     * The data following the reference types count should be ignored.
196     * And debuggee vm should return a package with zero reference types count.
197     */
198    public void testInstanceCounts_Zero() {
199        String thisTestName = "testInstanceCounts_Zero";
200
201        if (!isCapability()) {
202            logWriter.println("##WARNING: this VM dosn't possess capability: canGetInstanceInfo");
203            return;
204        }
205
206        logWriter.println("==> " + thisTestName + " for " + thisCommandName + ": START...");
207        synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
208
209        // Compose InstanceCounts command
210        CommandPacket InstanceCountsCommand = new CommandPacket(
211                JDWPCommands.VirtualMachineCommandSet.CommandSetID,
212                JDWPCommands.VirtualMachineCommandSet.InstanceCountsCommand);
213
214        InstanceCountsCommand.setNextValueAsInt(0); // count == 0
215
216        // Perform InstanceCounts command and attain reply package
217        ReplyPacket checkedReply = debuggeeWrapper.vmMirror
218                .performCommand(InstanceCountsCommand);
219        InstanceCountsCommand = null;
220
221        short errorCode = checkedReply.getErrorCode();
222        if (errorCode != JDWPConstants.Error.NONE) {
223            if (errorCode == JDWPConstants.Error.NOT_IMPLEMENTED) {
224                logWriter.println("=> CHECK PASSED: Expected error (NOT_IMPLEMENTED) is returned");
225                return;
226            }
227            else if(errorCode == JDWPConstants.Error.ILLEGAL_ARGUMENT) {
228                logWriter.println("=> CHECK PASSED: Expected error (ILLEGAL_ARGUMENT) is returned");
229                return;
230            }
231        }
232
233        int returnedRefTypesCount = checkedReply.getNextValueAsInt();
234        assertEquals(thisCommandName + "returned reference types count is wrong.",
235                0, returnedRefTypesCount, null, null);
236
237        logWriter.println("=> CHECK: PASSED: expected reference types count is returned:");
238        logWriter.println("=> Returned reference types count is " + returnedRefTypesCount);
239        assertAllDataRead(checkedReply);
240    }
241}
242