• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.Method;
20 
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25 import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
26 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
27 import org.apache.harmony.jpda.tests.framework.jdwp.Method;
28 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
29 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
30 
31 /**
32  * JDWP Unit test for Method.VariableTable command.
33  */
34 abstract class JDWPMethodVariableTableTestCase extends JDWPMethodTestCase {
35 
36     // All methods that must be checked against VariableTable[WithGeneric] reply.
37     private final Map<String, VariableTableChecker> checkerMap =
38             new HashMap<String, VariableTableChecker>();
39 
40     @Override
getDebuggeeClassName()41     protected final String getDebuggeeClassName() {
42         return MethodVariableTestDebuggee.class.getName();
43     }
44 
JDWPMethodVariableTableTestCase()45     protected JDWPMethodVariableTableTestCase() {
46         initCheckerMap();
47     }
48 
initCheckerMap()49     private void initCheckerMap() {
50         initStaticMethods();
51         initInstanceMethods();
52     }
53 
initStaticMethods()54     private void initStaticMethods() {
55         {
56             VariableTableChecker checker = new VariableTableChecker("static_NoParam");
57             addCheckerToMap(checker);
58         }
59         {
60             VariableTableChecker checker = new VariableTableChecker("static_BooleanParam");
61             checker.addParameter("booleanParam", "Z", 0);
62             addCheckerToMap(checker);
63         }
64         {
65             VariableTableChecker checker = new VariableTableChecker("static_ByteParam");
66             checker.addParameter("byteParam", "B", 0);
67             addCheckerToMap(checker);
68         }
69         {
70             VariableTableChecker checker = new VariableTableChecker("static_CharParam");
71             checker.addParameter("charParam", "C", 0);
72             addCheckerToMap(checker);
73         }
74         {
75             VariableTableChecker checker = new VariableTableChecker("static_ShortParam");
76             checker.addParameter("shortParam", "S", 0);
77             addCheckerToMap(checker);
78         }
79         {
80             VariableTableChecker checker = new VariableTableChecker("static_IntParam");
81             checker.addParameter("intParam", "I", 0);
82             addCheckerToMap(checker);
83         }
84         {
85             VariableTableChecker checker = new VariableTableChecker("static_FloatParam");
86             checker.addParameter("floatParam", "F", 0);
87             addCheckerToMap(checker);
88         }
89         {
90             VariableTableChecker checker = new VariableTableChecker("static_LongParam");
91             checker.addParameter("longParam", "J", 0);
92             addCheckerToMap(checker);
93         }
94         {
95             VariableTableChecker checker = new VariableTableChecker("static_DoubleParam");
96             checker.addParameter("doubleParam", "D", 0);
97             addCheckerToMap(checker);
98         }
99         {
100             VariableTableChecker checker = new VariableTableChecker("static_ObjectParam");
101             checker.addParameter("objectParam", "Ljava/lang/Object;", 0);
102             addCheckerToMap(checker);
103         }
104         {
105             VariableTableChecker checker = new VariableTableChecker("static_StringParam");
106             checker.addParameter("stringParam", "Ljava/lang/String;", 0);
107             addCheckerToMap(checker);
108         }
109         {
110             VariableTableChecker checker = new VariableTableChecker("static_ListOfStringsParam");
111             checker.addParameter("listOfStringsParam", "Ljava/util/List;", 0);
112             addCheckerToMap(checker);
113         }
114         {
115             VariableTableChecker checker = new VariableTableChecker("static_GenericParam");
116             checker.addParameter("genericParam", "Ljava/lang/CharSequence;", 0);
117             addCheckerToMap(checker);
118         }
119         {
120             VariableTableChecker checker = new VariableTableChecker("static_IntArrayParam");
121             checker.addParameter("intArrayParam", "[I", 0);
122             addCheckerToMap(checker);
123         }
124         {
125             VariableTableChecker checker = new VariableTableChecker("static_StringMultiArrayParam");
126             checker.addParameter("stringMultiArrayParam", "[[Ljava/lang/String;", 0);
127             addCheckerToMap(checker);
128         }
129         {
130             VariableTableChecker checker = new VariableTableChecker("static_IntLongParam");
131             checker.addParameter("intParam", "I", 0);
132             checker.addParameter("longParam", "J", 1);
133             addCheckerToMap(checker);
134         }
135         {
136             VariableTableChecker checker = new VariableTableChecker("static_LongIntParam");
137             checker.addParameter("longParam", "J", 0);
138             checker.addParameter("intParam", "I", 2);
139             addCheckerToMap(checker);
140         }
141 
142         {
143             VariableTableChecker checker = new VariableTableChecker("static_NoParamWithLocal");
144             checker.addLocal("i", "I");
145             checker.addLocal("l", "J");
146             addCheckerToMap(checker);
147         }
148     }
149 
initInstanceMethods()150     private void initInstanceMethods() {
151         {
152             VariableTableChecker checker = new VariableTableChecker("instance_NoParam");
153             checker.addParameter("this", getDebuggeeClassSignature(), 0);
154             addCheckerToMap(checker);
155         }
156         {
157             VariableTableChecker checker = new VariableTableChecker("instance_BooleanParam");
158             checker.addParameter("this", getDebuggeeClassSignature(), 0);
159             checker.addParameter("booleanParam", "Z", 1);
160             addCheckerToMap(checker);
161         }
162         {
163             VariableTableChecker checker = new VariableTableChecker("instance_ByteParam");
164             checker.addParameter("this", getDebuggeeClassSignature(), 0);
165             checker.addParameter("byteParam", "B", 1);
166             addCheckerToMap(checker);
167         }
168         {
169             VariableTableChecker checker = new VariableTableChecker("instance_CharParam");
170             checker.addParameter("this", getDebuggeeClassSignature(), 0);
171             checker.addParameter("charParam", "C", 1);
172             addCheckerToMap(checker);
173         }
174         {
175             VariableTableChecker checker = new VariableTableChecker("instance_ShortParam");
176             checker.addParameter("this", getDebuggeeClassSignature(), 0);
177             checker.addParameter("shortParam", "S", 1);
178             addCheckerToMap(checker);
179         }
180         {
181             VariableTableChecker checker = new VariableTableChecker("instance_IntParam");
182             checker.addParameter("this", getDebuggeeClassSignature(), 0);
183             checker.addParameter("intParam", "I", 1);
184             addCheckerToMap(checker);
185         }
186         {
187             VariableTableChecker checker = new VariableTableChecker("instance_FloatParam");
188             checker.addParameter("this", getDebuggeeClassSignature(), 0);
189             checker.addParameter("floatParam", "F", 1);
190             addCheckerToMap(checker);
191         }
192         {
193             VariableTableChecker checker = new VariableTableChecker("instance_LongParam");
194             checker.addParameter("this", getDebuggeeClassSignature(), 0);
195             checker.addParameter("longParam", "J", 1);
196             addCheckerToMap(checker);
197         }
198         {
199             VariableTableChecker checker = new VariableTableChecker("instance_DoubleParam");
200             checker.addParameter("this", getDebuggeeClassSignature(), 0);
201             checker.addParameter("doubleParam", "D", 1);
202             addCheckerToMap(checker);
203         }
204         {
205             VariableTableChecker checker = new VariableTableChecker("instance_ObjectParam");
206             checker.addParameter("this", getDebuggeeClassSignature(), 0);
207             checker.addParameter("objectParam", "Ljava/lang/Object;", 1);
208             addCheckerToMap(checker);
209         }
210         {
211             VariableTableChecker checker = new VariableTableChecker("instance_StringParam");
212             checker.addParameter("this", getDebuggeeClassSignature(), 0);
213             checker.addParameter("stringParam", "Ljava/lang/String;", 1);
214             addCheckerToMap(checker);
215         }
216         {
217             VariableTableChecker checker = new VariableTableChecker("instance_ListOfStringsParam");
218             checker.addParameter("this", getDebuggeeClassSignature(), 0);
219             checker.addParameter("listOfStringsParam", "Ljava/util/List;", 1);
220             addCheckerToMap(checker);
221         }
222         {
223             VariableTableChecker checker = new VariableTableChecker("instance_GenericParam");
224             checker.addParameter("this", getDebuggeeClassSignature(), 0);
225             checker.addParameter("genericParam", "Ljava/lang/CharSequence;", 1);
226             addCheckerToMap(checker);
227         }
228         {
229             VariableTableChecker checker = new VariableTableChecker("instance_IntArrayParam");
230             checker.addParameter("this", getDebuggeeClassSignature(), 0);
231             checker.addParameter("intArrayParam", "[I", 1);
232             addCheckerToMap(checker);
233         }
234         {
235             VariableTableChecker checker = new VariableTableChecker(
236                     "instance_StringMultiArrayParam");
237             checker.addParameter("this", getDebuggeeClassSignature(), 0);
238             checker.addParameter("stringMultiArrayParam", "[[Ljava/lang/String;", 1);
239             addCheckerToMap(checker);
240         }
241         {
242             VariableTableChecker checker = new VariableTableChecker("instance_IntLongParam");
243             checker.addParameter("this", getDebuggeeClassSignature(), 0);
244             checker.addParameter("intParam", "I", 1);
245             checker.addParameter("longParam", "J", 2);
246             addCheckerToMap(checker);
247         }
248         {
249             VariableTableChecker checker = new VariableTableChecker("instance_LongIntParam");
250             checker.addParameter("this", getDebuggeeClassSignature(), 0);
251             checker.addParameter("longParam", "J", 1);
252             checker.addParameter("intParam", "I", 3);
253             addCheckerToMap(checker);
254         }
255 
256         {
257             VariableTableChecker checker = new VariableTableChecker("instance_NoParamWithLocal");
258             checker.addParameter("this", getDebuggeeClassSignature(), 0);
259             checker.addLocal("i", "I");
260             checker.addLocal("l", "J");
261             addCheckerToMap(checker);
262         }
263     }
264 
addCheckerToMap(VariableTableChecker checker)265     private void addCheckerToMap(VariableTableChecker checker) {
266         checkerMap.put(checker.methodName, checker);
267     }
268 
269     /**
270      * This testcase exercises Method.VariableTable[WithGeneric] command. <BR>
271      * It runs MethodDebuggee, receives methods of debuggee. For each received
272      * method sends Method.VariableTable command and checks the returned
273      * VariableTable.
274      *
275      * @param withGenerics
276      *            true to test Method.VariableTableWithGeneric, false to test
277      *            Method.VariableTable.
278      */
checkMethodVariableTable(boolean withGenerics)279     protected void checkMethodVariableTable(boolean withGenerics) {
280         final String testName = getName();
281         logWriter.println(testName + " started");
282         synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
283 
284         long classID = getClassIDBySignature(getDebuggeeClassSignature());
285 
286         Method[] methodsInfo = debuggeeWrapper.vmMirror.getMethods(classID);
287         assertFalse("Invalid number of methods: 0", methodsInfo.length == 0);
288 
289         final byte commandCode;
290         final String commandName;
291         if (withGenerics) {
292             // Testing Method.VariableTableWithGeneric command.
293             commandCode = JDWPCommands.MethodCommandSet.VariableTableWithGenericCommand;
294             commandName = "Method::VariableTableWithGeneric";
295         } else {
296             // Testing Method.VariableTable command.
297             commandCode = JDWPCommands.MethodCommandSet.VariableTableCommand;
298             commandName = "Method::VariableTable";
299         }
300 
301         int checkedMethodsCount = 0;
302         for (Method methodInfo : methodsInfo) {
303             logWriter.println(methodInfo.toString());
304 
305             // get variable table for this class
306             CommandPacket packet = new CommandPacket(JDWPCommands.MethodCommandSet.CommandSetID,
307                     commandCode);
308             packet.setNextValueAsClassID(classID);
309             packet.setNextValueAsMethodID(methodInfo.getMethodID());
310             ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
311             checkReplyPacket(reply, commandName + " command");
312 
313             int argCnt = reply.getNextValueAsInt();
314             logWriter.println("argCnt = " + argCnt);
315             int slots = reply.getNextValueAsInt();
316             logWriter.println("slots = " + slots);
317 
318             VariableTableChecker checker = getCheckerForMethod(methodInfo.getName());
319             if (checker != null) {
320                 ++checkedMethodsCount;
321                 logWriter.println("# Check method \"" + checker.methodName + "\"");
322 
323                 // Check argCount.
324                 int expectedArgsCount = checker.getArgCount();
325                 assertEquals("Invalid argCount", expectedArgsCount, argCnt);
326             }
327             int checkedVariablesCount = 0;
328             for (int j = 0; j < slots; j++) {
329                 long codeIndex = reply.getNextValueAsLong();
330                 logWriter.println("codeIndex = " + codeIndex);
331                 String name = reply.getNextValueAsString();
332                 logWriter.println("name = \"" + name + "\"");
333                 String signature = reply.getNextValueAsString();
334                 logWriter.println("signature = \"" + signature + "\"");
335                 String genericSignature = "";
336                 if (withGenerics) {
337                     reply.getNextValueAsString();
338                     logWriter.println("genericSignature = \"" + genericSignature + "\"");
339                 }
340                 int length = reply.getNextValueAsInt();
341                 logWriter.println("length = " + length);
342                 int slot = reply.getNextValueAsInt();
343                 logWriter.println("slot = " + slot);
344 
345                 if (checker != null) {
346                     VariableInfo variableInfo = checker.getVariableInfo(name);
347                     if (variableInfo != null) {
348                         ++checkedVariablesCount;
349                         logWriter.println("## Check variable \"" + variableInfo.name + "\"");
350 
351                         // Check signature
352                         assertEquals("Invalid variable type signature",
353                             variableInfo.signature, signature);
354 
355                         if (variableInfo.isParameter) {
356                             // It would be nice to check the slot but that isn't specified by the
357                             // JLS. So different runtimes might have different values.
358                             //
359                             // A parameter's scope start is == 0.
360                             assertEquals("Invalid codeIndex " + codeIndex + " for parameter \"" +
361                                     name + "\"", 0, codeIndex);
362                         } else {
363                             // It would be nice to check the slot but that isn't specified by the
364                             // JLS. So different runtimes might have different values.
365                             //
366                             // A local variable's scope start is >= 0.
367                             assertTrue("Invalid codeIndex " + codeIndex + " for local var \"" +
368                                     name + "\"", codeIndex >= 0);
369                         }
370                     }
371                 }
372             }
373 
374             if (checker != null) {
375                 // Check that we found all the variables we want to check for the current method.
376                 assertEquals("Not all variables have been checked for method " + checker.methodName,
377                         checker.variableInfos.size(), checkedVariablesCount);
378             }
379 
380         }
381 
382         // Checks that we found all the methods that we want to check.
383         assertEquals("Not all methods have been checked", checkerMap.size(), checkedMethodsCount);
384 
385         synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
386         logWriter.println(testName + " ends");
387     }
388 
getCheckerForMethod(String methodName)389     private VariableTableChecker getCheckerForMethod(String methodName) {
390         return checkerMap.get(methodName);
391     }
392 
393     private static class VariableTableChecker {
394         final String methodName;
395         private final List<VariableInfo> variableInfos =
396                 new ArrayList<JDWPMethodVariableTableTestCase.VariableInfo>();
397 
VariableTableChecker(String methodName)398         public VariableTableChecker(String methodName) {
399             this.methodName = methodName;
400         }
401 
addVariableInfo(VariableInfo variableInfo)402         private void addVariableInfo(VariableInfo variableInfo) {
403             variableInfos.add(variableInfo);
404         }
405 
addParameter(String name, String signature, int slot)406         public void addParameter(String name, String signature, int slot) {
407             addVariableInfo(new VariableInfo(true, name, signature, slot));
408         }
409 
addLocal(String name, String signature)410         public void addLocal(String name, String signature) {
411             addVariableInfo(new VariableInfo(false, name, signature, -1));
412         }
413 
getArgCount()414         public int getArgCount() {
415             int argsCount = 0;
416             for (VariableInfo variableInfo : variableInfos) {
417                 if (variableInfo.isParameter) {
418                     String sig = variableInfo.signature;
419                     if (sig.equals("J") || sig.equals("D")) {
420                         // long and double take 2 slots.
421                         argsCount += 2;
422                     } else {
423                         argsCount += 1;
424                     }
425                 }
426             }
427             return argsCount;
428         }
429 
getVariableInfo(String variableName)430         public VariableInfo getVariableInfo(String variableName) {
431             for (VariableInfo v : variableInfos) {
432                 if (v.name.equals(variableName)) {
433                     return v;
434                 }
435             }
436             return null;
437         }
438     }
439 
440     private static class VariableInfo {
441         // Is it a parameter ?
442         private final boolean isParameter;
443         // The variable's name.
444         private final String name;
445         // The variable's signature.
446         private final String signature;
447         // The expected slot for parameters only.
448         private final int expectedParameterSlot;
449 
VariableInfo(boolean isParameter, String variableName, String variableSignature, int expectedParameterSlot)450         public VariableInfo(boolean isParameter, String variableName, String variableSignature,
451                             int expectedParameterSlot) {
452             this.isParameter = isParameter;
453             this.name = variableName;
454             this.signature = variableSignature;
455             this.expectedParameterSlot = expectedParameterSlot;
456         }
457     }
458 }
459