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.ObjectReference;
20 
21 import java.util.Random;
22 
23 import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
24 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
25 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
26 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
27 import org.apache.harmony.jpda.tests.framework.jdwp.Value;
28 import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase;
29 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
30 
31 public class ReferringObjectsTest extends JDWPSyncTestCase {
32 
33     static final int testStatusPassed = 0;
34 
35     static final int testStatusFailed = -1;
36 
37     static int maxReferrers;
38 
39     static final String thisCommandName = "ObjectReference.ReferringObjects command";
40 
41     static final String debuggeeSignature = "Lorg/apache/harmony/jpda/tests/jdwp/ObjectReference/ReferringObjectsDebuggee;";
42 
43     static final String referreeObjSignature = "Lorg/apache/harmony/jpda/tests/jdwp/ObjectReference/ReferringObjectsReferree001;";
44 
45     static final String referrerObjSignature = "Lorg/apache/harmony/jpda/tests/jdwp/ObjectReference/ReferringObjectsReferrer001;";
46 
getDebuggeeClassName()47     protected String getDebuggeeClassName() {
48         return "org.apache.harmony.jpda.tests.jdwp.ObjectReference.ReferringObjectsDebuggee";
49     }
50 
51     // ReferringObjects need canGetInstanceInfo VM capability support
isCapability()52     private boolean isCapability() {
53         // check capability, relevant for this test
54         logWriter.println("=> Check capability: canGetInstanceInfo");
55         debuggeeWrapper.vmMirror.capabilities();
56         boolean isCapability = debuggeeWrapper.vmMirror.targetVMCapabilities.canGetInstanceInfo;
57         return isCapability;
58     }
59 
60     /**
61      * This testcase exercises ObjectReference.ReferringObjects command.
62      * <BR>The test starts ReferringObjectsDebuggee class, requests referree objectID,
63      * for this class by ReferenceType.Instances command, then performs ObjectReference.ReferringObjects
64      * command and checks that returned instances are equal to the expected referrer objects. Since maxReferrers
65      * equals zero, all instances are returned.
66      */
testReferringObjects_MaxReferrersIsZero()67     public void testReferringObjects_MaxReferrersIsZero() {
68         maxReferrers = 0;
69         DoTestReferringObjects();
70     }
71 
72     /**
73      * This testcase exercises ObjectReference.ReferringObjects command.
74      * <BR>The test starts ReferringObjectsDebuggee class, requests referree objectID,
75      * for this class by ReferenceType.Instances command, then performs ObjectReference.ReferringObjects
76      * command and checks that returned instances are equal to the expected referrer objects. Since maxReferrers
77      * is more than the number of referrer objects, all instances are returned.
78      */
testReferringObjects_MaxReferrersIsLarge()79     public void testReferringObjects_MaxReferrersIsLarge() {
80         maxReferrers = 20;
81         DoTestReferringObjects();
82     }
83 
84     /**
85      * This testcase exercises ObjectReference.ReferringObjects command.
86      * <BR>The test starts ReferringObjectsDebuggee class, requests referree objectID,
87      * for this class by ReferenceType.Instances command, then performs ObjectReference.ReferringObjects
88      * command and checks that returned instances are equal to the expected referrer objects. Since maxReferrers
89      * is less than the number of referrer objects, the number of instances returned is equal to maxReferrers.
90      */
testReferringObjects_MaxReferrersIsSmall()91     public void testReferringObjects_MaxReferrersIsSmall() {
92         maxReferrers = 1;
93         DoTestReferringObjects();
94     }
95 
96     /**
97      * This is the real body of the testcase which exercises ObjectReference.ReferringObjects command.
98      * <BR>The test starts ReferringObjectsDebuggee class, requests referree objectID,
99      * for this class by ReferenceType.Instances command, then performs ObjectReference.ReferringObjects
100      * command and checks that returned instances are equal to the expected referrer objects.
101      */
DoTestReferringObjects()102     public void DoTestReferringObjects() {
103         String thisTestName = "testReferringObjects_Normal";
104 
105         if (!isCapability()) {
106             logWriter.println("##WARNING: this VM dosn't possess capability: canGetInstanceInfo");
107             return;
108         }
109 
110         logWriter.println("==> " + thisTestName + " for " + thisCommandName + ": START...");
111         synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
112 
113         // Get the number of referrer objects in ReferringObjectsDebugee
114         long debuggeeRefTypeID = getClassIDBySignature(debuggeeSignature);
115         long referringObjNumID = debuggeeWrapper.vmMirror.getFieldID(
116                 debuggeeRefTypeID, "referringObjNum");
117         long[] fieldIDs = new long[1];
118         fieldIDs[0] = referringObjNumID;
119         Value[] values = debuggeeWrapper.vmMirror.getReferenceTypeValues(
120                 debuggeeRefTypeID, fieldIDs);
121         int expectedReferringObjNum = values[0].getIntValue();
122 
123         logWriter.println("=> ReferringObjNum in debuggee is: " + expectedReferringObjNum);
124 
125         if(maxReferrers > 0) {
126             expectedReferringObjNum = (maxReferrers > expectedReferringObjNum) ? expectedReferringObjNum : maxReferrers;
127         }
128 
129         // Compose Instances command to get referree objectID
130         CommandPacket InstancesCommand = new CommandPacket(
131                 JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
132                 JDWPCommands.ReferenceTypeCommandSet.InstancesCommand);
133 
134         long referreeObjTypeID = getClassIDBySignature(referreeObjSignature);
135         InstancesCommand.setNextValueAsReferenceTypeID(referreeObjTypeID);
136         InstancesCommand.setNextValueAsInt(1);
137 
138         ReplyPacket checkedReply = debuggeeWrapper.vmMirror.performCommand(InstancesCommand);
139         InstancesCommand = null;
140 
141         // Get the number of instances that returned.
142         int objNum = checkedReply.getNextValueAsInt();
143         // Get the tagged-objectID
144         byte tag = checkedReply.getNextValueAsByte();
145         long objectID = checkedReply.getNextValueAsObjectID();
146 
147         // Compose ReferringObjects commnad
148         CommandPacket ReferringObjectsCommand = new CommandPacket(
149                 JDWPCommands.ObjectReferenceCommandSet.CommandSetID,
150                 JDWPCommands.ObjectReferenceCommandSet.ReferringObjectsCommand);
151 
152         ReferringObjectsCommand.setNextValueAsObjectID(objectID);
153         ReferringObjectsCommand.setNextValueAsInt(maxReferrers);
154 
155         // Perform ReferringObjects command and attain reply package
156         checkedReply = debuggeeWrapper.vmMirror
157                 .performCommand(ReferringObjectsCommand);
158         ReferringObjectsCommand = null;
159 
160         // Get referrer objects numbers
161         int referringObjects = checkedReply.getNextValueAsInt();
162         assertEquals(thisCommandName + "returned instances number is wrong.", expectedReferringObjNum, referringObjects,null,null);
163 
164         long referrerTypeID = getClassIDBySignature(referrerObjSignature);
165         long referrerFieldID = debuggeeWrapper.vmMirror.getFieldID(
166                 referrerTypeID, "isReferrer");
167 
168         // Check the returned objects are referrer objects
169         for (int i = 0; i < referringObjects; i++) {
170             //Get the tagged-objectID
171             tag = checkedReply.getNextValueAsByte();
172             assertEquals(thisCommandName
173                     + "returned object tag is invalid.", 'L', tag, null, null);
174 
175             objectID = checkedReply.getNextValueAsObjectID();
176             logWriter.println("=> ObjectID is: " + objectID);
177             values = debuggeeWrapper.vmMirror.getObjectReferenceValues(
178                     objectID, new long[] { referrerFieldID });
179             boolean isReferrer = values[0].getBooleanValue();
180             if (!isReferrer) {
181                 printErrorAndFail(thisCommandName
182                         + "returned object is not a referrer which references this object.");
183             }
184         }
185         logWriter.println("=> CHECK: PASSED: expected instances are returned:");
186         logWriter.println("=> Returned referringObjects number is" + referringObjects);
187 
188         synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
189         logWriter.println("==> " + thisTestName + " for " + thisCommandName + ": FINISH");
190         assertAllDataRead(checkedReply);
191     }
192 
193     /**
194      * This testcase exercises ObjectReference.ReferringObjects command. <BR>
195      * Compose a ReferringObjects command with negative maxReferrers
196      * The vm should throw a ILLEGAL_ARGUMENT exception.
197      */
testReferringObjects_IllegalArgument()198     public void testReferringObjects_IllegalArgument() {
199         String thisTestName = "testReferringObjects_IllegalArgument";
200 
201         if (!isCapability()) {
202             logWriter.println("##WARNING: this VM dosn't possess capability: canGetInstanceInfo");
203             return;
204         }
205 
206         int maxReferrers = -1;
207 
208         logWriter.println("==> " + thisTestName + " for " + thisCommandName + ": START...");
209         synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
210 
211         // Compose Instances command to get referree objectID
212         CommandPacket InstancesCommand = new CommandPacket(
213                 JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
214                 JDWPCommands.ReferenceTypeCommandSet.InstancesCommand);
215 
216         long referreeObjTypeID = getClassIDBySignature(referreeObjSignature);
217         InstancesCommand.setNextValueAsReferenceTypeID(referreeObjTypeID);
218         InstancesCommand.setNextValueAsInt(1);
219 
220         ReplyPacket checkedReply = debuggeeWrapper.vmMirror.performCommand(InstancesCommand);
221         InstancesCommand = null;
222 
223         // Get the number of instances that returned.
224         int objNum = checkedReply.getNextValueAsInt();
225         // Get the tagged-objectID
226         byte tag = checkedReply.getNextValueAsByte();
227         long objectID = checkedReply.getNextValueAsObjectID();
228 
229         // Compose ReferringObjects commnad
230         CommandPacket ReferringObjectsCommand = new CommandPacket(
231                 JDWPCommands.ObjectReferenceCommandSet.CommandSetID,
232                 JDWPCommands.ObjectReferenceCommandSet.ReferringObjectsCommand);
233 
234         ReferringObjectsCommand.setNextValueAsObjectID(objectID);
235         ReferringObjectsCommand.setNextValueAsInt(maxReferrers);
236 
237         // Perform ReferringObjects command and attain reply package
238         checkedReply = debuggeeWrapper.vmMirror
239                 .performCommand(ReferringObjectsCommand);
240         ReferringObjectsCommand = null;
241 
242         short errorCode = checkedReply.getErrorCode();
243         if (errorCode != JDWPConstants.Error.NONE) {
244             if (errorCode == JDWPConstants.Error.NOT_IMPLEMENTED) {
245                 logWriter.println("=> CHECK PASSED: Expected error (NOT_IMPLEMENTED) is returned");
246                 return;
247             }
248             else if(errorCode == JDWPConstants.Error.ILLEGAL_ARGUMENT) {
249                 logWriter.println("=> CHECK PASSED: Expected error (ILLEGAL_ARGUMENT) is returned");
250                 return;
251             }
252         }
253         printErrorAndFail(thisCommandName + " should throw ILLEGAL_ARGUMENT exception when maxReferrers is negative.");
254     }
255 }
256