test/jdk/com/sun/jdi/GetSetLocalTest.java
changeset 47216 71c04702a3d5
parent 44529 c1e6dd7a7326
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/jdi/GetSetLocalTest.java	Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,689 @@
+/*
+ * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+//    THIS TEST IS LINE NUMBER SENSITIVE
+
+/**
+ * @test
+ * @bug 4300412
+ * @summary Test GetLocal* and SetLocal* functions
+ * @author Serguei Spitsyn
+ *
+ * @run build TestScaffold VMConnection TargetListener TargetAdapter
+ * @run compile -g GetSetLocalTest.java
+ * @run driver GetSetLocalTest
+ */
+import com.sun.jdi.*;
+import com.sun.jdi.event.*;
+import com.sun.jdi.request.*;
+
+import java.util.*;
+
+    /********** target program **********/
+
+class GetSetLocalTarg {
+    public static void main(String[] args){
+        int intVar = 10;
+        System.out.println("GetSetLocalTarg: Started");
+        intVar = staticMeth(intVar);
+        System.out.println("GetSetLocalTarg: Finished");
+    }
+
+    /*
+     * The line numbers of this method *MUST NOT* be changed
+     * because the testing algorithm counts on this layout!
+     * It's in calls to resumeTo("GetSetLocalTarg", line).
+     */
+    public static int staticMeth(int intArg) {
+        System.out.println("staticMeth: Started");
+        int result;
+        {
+             { boolean bool_1 = false;
+               intArg++; // START_LINE
+             }
+
+             boolean bool_2 = true;
+             intArg++;
+        }
+        {
+             { byte byte_1 = 1;
+               intArg++;
+             }
+
+             byte byte_2 = 2;
+             intArg++;
+        }
+        {
+             { char   char_1 = '1';
+               intArg++;
+             }
+
+             char   char_2 = '2';
+             intArg++;
+        }
+        {
+             { short  short_1 = 1;
+               intArg++;
+             }
+
+             short  short_2 = 2;
+             intArg++;
+        }
+        {
+             { int    int_1 = 1;
+               intArg++;
+             }
+
+             int int_2 = 2;
+             intArg++;
+        }
+        {
+             { long long_1 = 1;
+               intArg++;
+             }
+
+             long long_2 = 2;
+             intArg++;
+        }
+        {
+             { float  float_1 = 1;
+               intArg++;
+             }
+
+             float float_2 = 2;
+             intArg++;
+        }
+        {
+             { double double_1 = 1;
+               intArg++;
+             }
+
+             double double_2 = 2;
+             intArg++;
+        }
+        {
+             { String string_1 = "1";
+               intArg++;
+             }
+
+             String string_2 = "2";
+             intArg++;
+        }
+        {
+             { Object obj_1 = new Object();
+               intArg++;
+             }
+
+             Object obj_2 = new Object();
+             intArg++;  // STOP_LINE. Last stop is at this point.
+                        //     Only obj_2 and intArg are valid
+                        // Note: even result is not valid here!
+        }
+        result = 10;    // <- This is first init of result var
+        System.out.println("staticMeth: Finished");
+        return result;
+    }
+}
+
+
+    /********** test program **********/
+
+public class GetSetLocalTest extends TestScaffold {
+    static final int START_LINE = 62;
+    static final int STOP_LINE = 138;
+    ReferenceType targetClass;
+    ThreadReference mainThread;
+
+    GetSetLocalTest (String args[]) {
+        super(args);
+    }
+
+    public static void main(String[] args) throws Exception {
+        new GetSetLocalTest(args).startTests();
+    }
+
+    /********** test assist **********/
+
+    Method getMethod(String className, String methodName) {
+        List refs = vm().classesByName(className);
+        if (refs.size() != 1) {
+            failure(" Failure: " + refs.size() +
+                    " ReferenceTypes named: " + className);
+            return null;
+        }
+        ReferenceType refType = (ReferenceType)refs.get(0);
+        List meths = refType.methodsByName(methodName);
+        if (meths.size() != 1) {
+            failure(" Failure: " + meths.size() +
+                    " methods named: " + methodName);
+            return null;
+        }
+        return (Method)meths.get(0);
+    }
+
+    List printAllVariables(String className, String methodName) throws Exception {
+        println("printAllVariables for method: " + className + "." + methodName);
+        Method method = getMethod(className, methodName);
+        List localVars;
+        try {
+            localVars = method.variables();
+            println(" Success: got a list of all method variables: " + methodName);
+        }
+        catch (com.sun.jdi.AbsentInformationException ex) {
+            failure(" Failure: AbsentInformationException has been thrown");
+            return null;
+        }
+
+        int index = 0;
+        for (Iterator it = localVars.iterator(); it.hasNext();) {
+            LocalVariable lv = (LocalVariable) it.next();
+            printOneVariable(lv, index++);
+        }
+        println("");
+        return localVars;
+    }
+
+    void checkGetSetAllVariables(List localVars, StackFrame frame) throws Exception {
+        println("\n checkGetSetAllVariables for method at particular frame location: ");
+        int index = 0;
+        for (Iterator it = localVars.iterator(); it.hasNext();) {
+            LocalVariable lv = (LocalVariable) it.next();
+            String lv_name = lv.name();
+            print(" Variable " + lv_name);
+            try {
+                Value val = frame.getValue(lv);
+                frame.setValue(lv, val);
+                println(" has been get/set");
+                if (lv_name.compareTo("intArg") != 0 &&
+                    lv_name.compareTo("obj_2")  != 0) {
+                    failure(" Failure: AbsentInformationException is expected");
+                }
+            } catch (java.lang.IllegalArgumentException ex) {
+                println(" is not valid");
+                if (lv_name.compareTo("intArg") == 0 &&
+                    lv_name.compareTo("obj_2")  == 0) {
+                    failure(" Failure: AbsentInformationException was not expected");
+                }
+            }
+        }
+        println("");
+    }
+
+    void printOneVariable(LocalVariable lv, int index) throws Exception {
+        String tyname = lv.typeName();
+        println("");
+        println(" Var  name: " + lv.name());
+        println(" Var  type: " + tyname);
+        println(" Var index: " + index);
+        println(" Signature: " + lv.type().signature());
+        // Sorry, there is no way to get (and print)
+        // a local variable slot numbers using JDI!
+    }
+
+    void printFrameVariables(StackFrame frame) throws Exception {
+        int index = 0;
+        List localVars = frame.visibleVariables();
+        println("\n Visible variables at this point are: ");
+
+        for (Iterator it = localVars.iterator(); it.hasNext();) {
+            LocalVariable lv = (LocalVariable) it.next();
+            printOneVariable(lv, index++);
+            println(" Var value: " + frame.getValue(lv));
+        }
+    }
+
+    BooleanValue incrValue(BooleanValue val) {
+        boolean value = val.value();
+        return vm().mirrorOf(!value);
+    }
+
+    ByteValue incrValue(ByteValue val) {
+        byte value = val.value();
+        return vm().mirrorOf(++value);
+    }
+
+    CharValue incrValue(CharValue val) {
+        char value = val.value();
+        return vm().mirrorOf(++value);
+    }
+
+    ShortValue incrValue(ShortValue val) {
+        short value = val.value();
+        return vm().mirrorOf(++value);
+    }
+
+    IntegerValue incrValue(IntegerValue val) {
+        int value = val.value();
+        return vm().mirrorOf(++value);
+    }
+
+    LongValue incrValue(LongValue val) {
+        long value = val.value();
+        return vm().mirrorOf(++value);
+    }
+
+    FloatValue incrValue(FloatValue val) {
+        float value = val.value();
+        return  vm().mirrorOf(++value);
+    }
+
+    DoubleValue incrValue(DoubleValue val) {
+        double value = val.value();
+        return vm().mirrorOf(++value);
+    }
+
+    StringReference incrValue(StringReference val) {
+        String newstr = new String("Set String ").concat(val.value());
+        return vm().mirrorOf(newstr);
+    }
+
+    void checkSetBooleanTypes(StackFrame frame, LocalVariable lv) throws Exception {
+        BooleanValue get = (BooleanValue) frame.getValue(lv);
+        BooleanValue set = incrValue(get);
+        frame.setValue(lv, set);
+
+        // To get the new value which has been set
+        get = (BooleanValue) frame.getValue(lv);
+        println(" Var  Set: " + set);
+        println(" Var  Get: " + get);
+        println("");
+        boolean v1 = get.value();
+        boolean v2 = set.value();
+
+        // Check if set was done properly
+        if (v1 == v2) {
+            println(" Success: Value was set correctly!");
+        } else {
+            failure(" Failure: Value was NOT set correctly!");
+        }
+        println("");
+    }
+
+    void checkSetByteTypes(StackFrame frame, LocalVariable lv) throws Exception {
+        ByteValue get = (ByteValue) frame.getValue(lv);
+        ByteValue set = incrValue(get);
+        frame.setValue(lv, set);
+
+        // To get the new value which has been set
+        get = (ByteValue) frame.getValue(lv);
+        println(" Var  Set: " + set);
+        println(" Var  Get: " + get);
+        println("");
+        byte v1 = get.value();
+        byte v2 = set.value();
+
+        // Check if set was done properly
+        if (v1 == v2) {
+            println(" Success: Value was set correctly!");
+        } else {
+            failure(" Failure: Value was NOT set correctly!");
+        }
+        println("");
+    }
+
+    void checkSetCharTypes(StackFrame frame, LocalVariable lv) throws Exception {
+        CharValue get = (CharValue) frame.getValue(lv);
+        CharValue set = incrValue(get);
+        frame.setValue(lv, set);
+
+        // To get the new value which has been set
+        get = (CharValue) frame.getValue(lv);
+        println(" Var  Set: " + set);
+        println(" Var  Get: " + get);
+        println("");
+        char v1 = get.value();
+        char v2 = set.value();
+
+        // Check if set was done properly
+        if (v1 == v2) {
+            println(" Success: Value was set correctly!");
+        } else {
+            failure(" Failure: Value was NOT set correctly!");
+        }
+        println("");
+    }
+
+    void checkSetShortTypes(StackFrame frame, LocalVariable lv) throws Exception {
+        ShortValue get = (ShortValue) frame.getValue(lv);
+        ShortValue set = incrValue(get);
+        frame.setValue(lv, set);
+
+        // To get the new value which has been set
+        get = (ShortValue) frame.getValue(lv);
+        println(" Var  Set: " + set);
+        println(" Var  Get: " + get);
+        println("");
+        short v1 = get.value();
+        short v2 = set.value();
+
+        // Check if set was done properly
+        if (v1 == v2) {
+            println(" Success: Value was set correctly!");
+        } else {
+            failure(" Failure: Value was NOT set correctly!");
+        }
+        println("");
+    }
+
+    void checkSetIntegerTypes(StackFrame frame, LocalVariable lv) throws Exception {
+        IntegerValue get = (IntegerValue) frame.getValue(lv);
+        IntegerValue set = incrValue(get);
+        frame.setValue(lv, set);
+
+        // To get the new value which has been set
+        get = (IntegerValue) frame.getValue(lv);
+        println(" Var  Set: " + set);
+        println(" Var  Get: " + get);
+        println("");
+        int v1 = get.value();
+        int v2 = set.value();
+
+        // Check if set was done properly
+        if (v1 == v2) {
+            println(" Success: Value was set correctly!");
+        } else {
+            failure(" Failure: Value was NOT set correctly!");
+        }
+        println("");
+    }
+
+    void checkSetLongTypes(StackFrame frame, LocalVariable lv) throws Exception {
+        LongValue get = (LongValue) frame.getValue(lv);
+        LongValue set = incrValue(get);
+        frame.setValue(lv, set);
+
+        // To get the new value which has been set
+        get = (LongValue) frame.getValue(lv);
+        println(" Var  Set: " + set);
+        println(" Var  Get: " + get);
+        println("");
+        long v1 = get.value();
+        long v2 = set.value();
+
+        // Check if set was done properly
+        if (v1 == v2) {
+            println(" Success: Value was set correctly!");
+        } else {
+            failure(" Failure: Value was NOT set correctly!");
+        }
+        println("");
+    }
+
+    void checkSetFloatTypes(StackFrame frame, LocalVariable lv) throws Exception {
+        FloatValue get = (FloatValue) frame.getValue(lv);
+        FloatValue set = incrValue(get);
+        frame.setValue(lv, set);
+
+        // To get the new value which has been set
+        get = (FloatValue) frame.getValue(lv);
+        println(" Var  Set: " + set);
+        println(" Var  Get: " + get);
+        println("");
+        float v1 = get.value();
+        float v2 = set.value();
+
+        // Check if set was done properly
+        if (v1 == v2) {
+            println(" Success: Value was set correctly!");
+        } else {
+            failure(" Failure: Value was NOT set correctly!");
+        }
+        println("");
+    }
+
+    void checkSetDoubleTypes(StackFrame frame, LocalVariable lv) throws Exception {
+        DoubleValue get = (DoubleValue) frame.getValue(lv);
+        DoubleValue set = incrValue(get);
+        frame.setValue(lv, set);
+
+        // To get the new value which has been set
+        get = (DoubleValue) frame.getValue(lv);
+        println(" Var  Set: " + set);
+        println(" Var  Get: " + get);
+        println("");
+        double v1 = get.value();
+        double v2 = set.value();
+
+        // Check if set was done properly
+        if (v1 == v2) {
+            println(" Success: Value was set correctly!");
+        } else {
+            failure(" Failure: Value was NOT set correctly!");
+        }
+        println("");
+    }
+
+    void checkSetStringTypes(StackFrame frame, LocalVariable lv) throws Exception {
+        StringReference get = (StringReference) frame.getValue(lv);
+        StringReference set = incrValue((StringReference) frame.getValue(lv));
+        frame.setValue(lv, set);
+
+        // To get the new value which has been set
+        get = (StringReference) frame.getValue(lv);
+        println(" Var  Set: " + set);
+        println(" Var  Get: " + get);
+        println("");
+        String str1 = get.value();
+        String str2 = set.value();
+
+        // Check if set was done properly
+        if (str1.compareTo(str2) == 0) {
+            println(" Success: String was set correctly!");
+        } else {
+            failure(" Failure: String was NOT set correctly!");
+        }
+        println("");
+    }
+
+    void checkSetObjectTypes(StackFrame frame, LocalVariable lv) throws Exception {
+        ObjectReference get = (ObjectReference) frame.getValue(lv);
+        ObjectReference set = get; // FIXME: Don't know how to create a mirror of Object
+        frame.setValue(lv, set);
+
+        // To get the new value which has been set
+        get = (ObjectReference) frame.getValue(lv);
+        println(" Var  Set: " + set);
+        println(" Var  Get: " + get);
+        println("");
+
+        if (set.uniqueID() == get.uniqueID()) {
+            println(" Success: Object was set correctly!");
+        } else {
+            failure(" Failure: Object was NOT set correctly!");
+        }
+        println("");
+    }
+
+    void negativeIntegerCheck(StackFrame frame, LocalVariable lv) throws Exception {
+        try {
+            IntegerValue get = (IntegerValue) frame.getValue(lv);
+            println(" Get: No ClassCastException error!");
+        } catch(java.lang.ClassCastException ex) {
+            println(" Success: Get: ClassCastException error has cought as expected!");
+        }
+        try {
+            IntegerValue set = vm().mirrorOf((int) 0x3F);
+            frame.setValue(lv, set);
+            println(" Set: No InvalidTypeException with Integer error!");
+        } catch(com.sun.jdi.InvalidTypeException ex) {
+            println(" Success: Set: InvalidTypeException with Integer error has cought as expected!");
+        }
+    }
+
+    void negativeFloatCheck(StackFrame frame, LocalVariable lv) throws Exception {
+        try {
+            FloatValue get = (FloatValue) frame.getValue(lv);
+            println(" Get: No ClassCastException error!");
+        } catch(java.lang.ClassCastException ex) {
+            println(" Success: Get: ClassCastException with Float error has cought as expected!");
+        }
+        try {
+            FloatValue set = vm().mirrorOf(1.2345f);
+            frame.setValue(lv, set);
+            println(" Set: No InvalidTypeException with Float error!");
+        } catch(com.sun.jdi.InvalidTypeException ex) {
+            println(" Success: Set: InvalidTypeException error has cought as expected!");
+        }
+    }
+
+    void negativeDoubleCheck(StackFrame frame, LocalVariable lv) throws Exception {
+        try {
+            DoubleValue get = (DoubleValue) frame.getValue(lv);
+            println(" Get: No ClassCastException error!");
+        } catch(java.lang.ClassCastException ex) {
+            println(" Success: Get: ClassCastException  with Double error has cought as expected!");
+        }
+        try {
+            DoubleValue set = vm().mirrorOf(1.2345E02);
+            frame.setValue(lv, set);
+            println(" Set: No InvalidTypeException with Double error!");
+        } catch(com.sun.jdi.InvalidTypeException ex) {
+            println(" Success: Set: InvalidTypeException error has cought as expected!");
+        }
+    }
+
+    void checkSetFrameVariables(StackFrame frame) throws Exception {
+        List localVars = frame.visibleVariables();
+        int index = 0;
+        println("\n Set variable values:");
+
+        for (Iterator it = localVars.iterator(); it.hasNext();index++) {
+            LocalVariable lv = (LocalVariable) it.next();
+            String signature = lv.type().signature();
+
+            switch (signature.charAt(0)) {
+            case 'Z': // Boolean Type
+                checkSetBooleanTypes(frame, lv);
+                negativeIntegerCheck(frame, lv);
+                negativeFloatCheck(frame, lv);
+                negativeDoubleCheck(frame, lv);
+                break;
+            case 'B': // Byte Type
+                checkSetByteTypes(frame, lv);
+                negativeIntegerCheck(frame, lv);
+                negativeFloatCheck(frame, lv);
+                negativeDoubleCheck(frame, lv);
+                break;
+            case 'C': // Char Type
+                checkSetCharTypes(frame, lv);
+                negativeIntegerCheck(frame, lv);
+                negativeFloatCheck(frame, lv);
+                negativeDoubleCheck(frame, lv);
+                break;
+            case 'S': // Short Type
+                checkSetShortTypes(frame, lv);
+                negativeIntegerCheck(frame, lv);
+                negativeFloatCheck(frame, lv);
+                negativeDoubleCheck(frame, lv);
+                break;
+            case 'I': // Integer Type
+                checkSetIntegerTypes(frame, lv);
+                if (index > 0) { // To skip integer method parameter
+                    negativeFloatCheck(frame, lv);
+                    negativeDoubleCheck(frame, lv);
+                }
+                break;
+            case 'J': // Long Type
+                checkSetLongTypes(frame, lv);
+                negativeIntegerCheck(frame, lv);
+                negativeFloatCheck(frame, lv);
+                negativeDoubleCheck(frame, lv);
+                break;
+            case 'F': // Float Type
+                checkSetFloatTypes(frame, lv);
+                negativeIntegerCheck(frame, lv);
+                negativeDoubleCheck(frame, lv);
+                break;
+            case 'D': // Double Type
+                checkSetDoubleTypes(frame, lv);
+                negativeIntegerCheck(frame, lv);
+                negativeFloatCheck(frame, lv);
+                break;
+            case 'L':
+                if (signature.compareTo("Ljava/lang/String;") == 0) {
+                    checkSetStringTypes(frame, lv);
+                    negativeIntegerCheck(frame, lv);
+                    negativeFloatCheck(frame, lv);
+                }
+                if (signature.compareTo("Ljava/lang/Object;") == 0) {
+                    checkSetObjectTypes(frame, lv);
+                    negativeIntegerCheck(frame, lv);
+                    negativeFloatCheck(frame, lv);
+                }
+                break;
+            default:
+                printOneVariable(lv, index);
+                failure(" Failure: List of local variables has a wrong entry!");
+            };
+        }
+    }
+
+
+    /********** test core **********/
+
+    protected void runTests() throws Exception {
+
+        /*
+         * Get to the top of main() to determine targetClass and mainThread
+         */
+        BreakpointEvent bpe = startToMain("GetSetLocalTarg");
+        println("startToMain(GetSetLocalTarg)");
+
+        List localVars = printAllVariables("GetSetLocalTarg", "staticMeth");
+
+        targetClass = bpe.location().declaringType();
+        println("targetClass");
+
+        mainThread = bpe.thread();
+        println("mainThread");
+
+        EventRequestManager erm = vm().eventRequestManager();
+        println("EventRequestManager");
+        StackFrame frame = null;
+
+        for (int line = START_LINE; line <= STOP_LINE; line += 4) {
+            println("\n resumeTo(GetSetLocalTarg, " + line + ")");
+            bpe = resumeTo("GetSetLocalTarg", line);
+            frame = bpe.thread().frame(0);
+            printFrameVariables(frame);
+            checkSetFrameVariables(frame);
+        }
+        // Check if we can Get/Set all local vars using last frame state
+        checkGetSetAllVariables(localVars, frame);
+
+        /*
+         * resume until the end
+         */
+        listenUntilVMDisconnect();
+
+        /*
+         * deal with results of test
+         * if anything has called failure("foo") testFailed will be true
+         */
+        if (!testFailed) {
+            println("GetSetLocalTest: passed");
+        } else {
+            throw new Exception("GetSetLocalTest: failed");
+        }
+    }
+}