diff -r fd16c54261b3 -r 90ce3da70b43 jdk/test/com/sun/jdi/redefineMethod/RedefineTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/com/sun/jdi/redefineMethod/RedefineTest.java Sat Dec 01 00:00:00 2007 +0000 @@ -0,0 +1,295 @@ +/* + * Copyright 2002 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 4628726 + * @summary Test class redefinition - method data line numbers and local vars, + * + * @author Robert Field + * + * @library .. + * @run build TestScaffold VMConnection TargetListener TargetAdapter + * @run compile -g RedefineTest.java + * @run shell RedefineSetUp.sh + * @run main RedefineTest -repeat 3 + * @run main RedefineTest + */ +import com.sun.jdi.*; +import com.sun.jdi.event.*; +import com.sun.jdi.request.*; +import java.util.*; +import java.io.*; + + /********** target program **********/ + +class RedefineTarg { + public static void main(String[] args){ + RedefineSubTarg.stemcp(); + RedefineSubTarg sub = new RedefineSubTarg(); + sub.bottom(); + RedefineSubTarg.stnemcp(); + RedefineSubTarg.stemcp(); + } +} + + /********** test program **********/ + +public class RedefineTest extends TestScaffold { + static int redefineRepeat = 1; + int bpCnt = 0; + + // isObsolete, linenumber, lv name, lv value, lv isArg + String[] before = { + "+ 3", + "+ 6 eights 888 T", + "+ 11 rot 4 F", + "+ 15", + "+ 20 myArg 56 T paramy 12 F", + "+ 24", + "+ 28", + "+ 33" }; + String[] after = { + "+ 5", + "O", + "O", + "+ 16", + "+ 21 whoseArg 56 T parawham 12 F", + "+ 25", + "O", + "+ 34" }; + String[] shorter = { + "+ 5", + "+ 9 eights 88 T", + "+ 13", + "+ 16", + "+ 21 whoseArg 56 T parawham 12 F", + "+ 25" }; + String[] refresh = { + "+ 5", + "+ 9 eights 88 T", + "+ 13", + "+ 16", + "+ 21 whoseArg 56 T parawham 12 F", + "+ 25", + "+ 29", + "+ 34" }; + int[] bps = {7, 12, 16, 21, 25, 30, 34}; + String[][] bpPlaces = { + {"+ 16"}, + {"+ 21 myArg 56 T paramy 12 F"}, + {"+ 25"}, + {"+ 34"} }; + + static String[] processArgs(String args[]) { + if (args.length > 0 && args[0].equals("-repeat")) { + redefineRepeat = Integer.decode(args[1]).intValue(); + String[] args2 = new String[args.length - 2]; + System.arraycopy(args, 2, args2, 0, args.length - 2); + return args2; + } else { + return args; + } + } + + RedefineTest (String args[]) { + super(args); + } + + public static void main(String[] args) throws Exception { + new RedefineTest(processArgs(args)).startTests(); + } + + + /********** event handlers **********/ + + public void breakpointReached(BreakpointEvent event) { + println("Got BreakpointEvent - " + event); + try { + checkFrames(event.thread(), bpPlaces[bpCnt++]); + if (bpCnt >= bpPlaces.length) { + eventRequestManager().deleteAllBreakpoints(); + } + } catch (Exception exc) { + failure("FAIL: breakpoint checking threw " + exc); + } + } + + /********** test assists **********/ + + // isObsolete, linenumber, lv name, lv value, lv isArg + // equals: ref type (always), method (not obsolete) + void checkFrames(ThreadReference thread, String[] matchList) throws Exception { + for (int i = 0; i < matchList.length; ++i) { + String match = matchList[i]; + StackFrame frame = thread.frame(i); + Location loc = frame.location(); + ReferenceType refType = loc.declaringType(); + Method meth = loc.method(); + String errInfo = "\nframe " + i + ": " + loc + "\n match: " + match; + if (!findReferenceType("RedefineSubTarg").equals(refType)) { + failure("FAIL: Bad reference type - " + errInfo); + return; // might be bad class, but might have run past bottom + } + StringTokenizer st = new StringTokenizer(match); + boolean expectObs = st.nextToken().equals("O"); + println("Frame " + i + ": " + meth); + if (meth.isObsolete()) { + if (!expectObs) { + failure("FAIL: Method should NOT be obsolete - " + errInfo); + } + } else { + if (expectObs) { + failure("FAIL: Method should be obsolete - " + errInfo); + break; // no more data to read + } + if (!findMethod(refType, meth.name(), meth.signature()).equals(meth)) { + failure("FAIL: Non matching method - " + errInfo); + } + int line = loc.lineNumber(); + if (line != Integer.parseInt(st.nextToken())) { + failure("FAIL: Unexpected line number: " + errInfo); + } + // local var matching + int lvCnt = 0; + while (st.hasMoreTokens()) { + ++lvCnt; + String lvName = st.nextToken(); + int lvValue = Integer.parseInt(st.nextToken()); + boolean isArg = st.nextToken().equals("T"); + LocalVariable lv = frame.visibleVariableByName(lvName); + if (lv == null) { + failure("FAIL: local var not found: '" + lvName + + "' -- " + errInfo); + } else { + Value val = frame.getValue(lv); + int ival = ((IntegerValue)val).value(); + if (ival != lvValue) { + failure("FAIL: expected value: '" + lvValue + + "' got: '" + ival + "' -- " + errInfo); + } + if (lv.isArgument() != isArg) { + failure("FAIL: expected argument: '" + isArg + + "' got: '" + lv.isArgument() + "' -- " + errInfo); + } + } + } + List locals = frame.visibleVariables(); + if (locals.size() != lvCnt) { + failure("FAIL: expected '" + lvCnt + + "' locals were '" + locals.size() + + "' -- " + errInfo + "' -- " + locals); + } + } + } + } + + + void doRedefine(String fileName) throws Exception { + File phyl = new File(fileName); + byte[] bytes = new byte[(int)phyl.length()]; + InputStream in = new FileInputStream(phyl); + in.read(bytes); + in.close(); + + Map map = new HashMap(); + map.put(findReferenceType("RedefineSubTarg"), bytes); + + try { + for (int i = 0; i < redefineRepeat; ++i) { + vm().redefineClasses(map); + } + } catch (Exception thr) { + failure("FAIL: unexpected exception: " + thr); + } + } + + ThreadReference toTop() { + BreakpointEvent bpe = resumeTo("RedefineSubTarg", "top", "()V"); + return bpe.thread(); + } + + void setBP(int line) { + try { + Location loc = findLocation(findReferenceType("RedefineSubTarg"), line); + final BreakpointRequest request = + eventRequestManager().createBreakpointRequest(loc); + request.enable(); + } catch (Exception exc) { + failure("FAIL: Attempt to set BP at line " + line + " threw " + exc); + } + } + + /********** test core **********/ + + protected void runTests() throws Exception { + + startToMain("RedefineTarg"); + + ThreadReference thread = toTop(); + + println("------ Before Redefine ------"); + checkFrames(thread, before); + + println("------ After Redefine ------"); + doRedefine("Different_RedefineSubTarg.class"); + checkFrames(thread, after); + + println("------ Static 2 ------"); + toTop(); + checkFrames(thread, shorter); + + println("------ Instance ------"); + toTop(); + checkFrames(thread, shorter); + + println("------ Re-entered ------"); + toTop(); + checkFrames(thread, refresh); + + println("------ Breakpoints ------"); + doRedefine("RedefineSubTarg.class"); + for (int i = 0; i < bps.length; ++i) { + setBP(bps[i]); + } + + /* + * resume the target listening for events + */ + listenUntilVMDisconnect(); + + if (bpCnt != bpPlaces.length) { + failure("FAIL: Wrong number of breakpoints encountered: " + bpCnt); + } + + /* + * deal with results of test + * if anything has called failure("foo") testFailed will be true + */ + if (!testFailed) { + println("RedefineTest(method): passed"); + } else { + throw new Exception("RedefineTest(method): failed"); + } + } +}