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