| /* |
| * Copyright (c) 2007, 2018, 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. |
| */ |
| |
| /* |
| * @test |
| * |
| * @summary converted from VM Testbase nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn001. |
| * VM Testbase keywords: [jpda, jdwp, feature_jdk6_jpda, vm6, monitoring, quarantine] |
| * VM Testbase comments: 7199837 |
| * VM Testbase readme: |
| * DESCRIPTION |
| * This test performs checking for |
| * command set: ThreadReference |
| * command: ForceEarlyReturn |
| * Test checks that debuggee accept the command packet and |
| * replies with correct reply packet. |
| * Test consists of two compoments: |
| * debugger: forceEarlyReturn001 |
| * debuggee: forceEarlyReturn001a |
| * Debugger uses nsk.share support classes to launch debuggee |
| * and obtain Transport object, that represents JDWP transport channel. |
| * Also communication channel (IOPipe) is established between |
| * debugger and debuggee to exchange with execution commands. |
| * Debuggee VM create thread(class nsk.share.jpda.ForceEarlyReturnTestThread is used) which sequentially call |
| * test methods with different return value's type: |
| * - void |
| * - all primitive types |
| * - all wrappers of primitive types |
| * - String |
| * - Object |
| * - array of java.lang.Object |
| * - Thread |
| * - ThreadGroup |
| * - Class object |
| * - ClassLoader |
| * Also test thread class contains static fields with predefined values which should be returned through |
| * ForceEarlyReturn('expectedXXXValue') and fields with values which can be used to check is ForceEarlyReturn returns |
| * TYPE_MISMATCH error if value's type in command doesn't match method's return type('invalidXXXValue'). |
| * Debugger set breakpoints in test thread's methods and create instances of 'nsk.share.jdwp.JDWP.Value' |
| * based on values predefined in ForceEarlyReturnTestThread (both valid and invalid values are created). |
| * Debugger obtains threadID for test thread. |
| * Debugger force debugee start test thread and wait while BreakpointEvents occurs. When debuggee's |
| * test thread stop at breakpoint debugger first creates command packet for ForceEarlyReturn command with the |
| * found threadID and corresponding instance of invalid 'nsk.share.jdwp.JDWP.Value', writes |
| * packet to the transport channel, and waits for a reply packet. When reply packet is received, debugger |
| * parses the packet structure and checks that reply contain TYPE_MISMATCH error. Then debugger send command |
| * with correct value, checks that reply is empty and resume debuggee VM. |
| * Test thread in debuggee VM checks that value returned from test methods equals predefined value and no |
| * instructions was executed in called method after force return (finally blocks are not executed too). |
| * When all breakpoint events occured debugger sends debuggee signal to finish test thread execution. |
| * Debuggee waits when test thread finish execution and checks is any errors occured during test. |
| * Finally, debugger sends debuggee signal to quit, waits for it exits |
| * and exits too with the proper exit code. |
| * |
| * @library /vmTestbase /test/hotspot/jtreg/vmTestbase |
| * /test/lib |
| * @run driver jdk.test.lib.FileInstaller . . |
| * @build nsk.jdwp.ThreadReference.ForceEarlyReturn.forceEarlyReturn001.forceEarlyReturn001 |
| * @run main/othervm PropertyResolvingWrapper |
| * nsk.jdwp.ThreadReference.ForceEarlyReturn.forceEarlyReturn001.forceEarlyReturn001 |
| * -arch=${os.family}-${os.simpleArch} |
| * -verbose |
| * -waittime=5 |
| * -debugee.vmkind=java |
| * -transport.address=dynamic |
| * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}" |
| */ |
| |
| package nsk.jdwp.ThreadReference.ForceEarlyReturn.forceEarlyReturn001; |
| |
| import java.io.*; |
| import nsk.share.Consts; |
| import nsk.share.jdwp.*; |
| import nsk.share.jdwp.JDWP.Value; |
| import nsk.share.jpda.ForceEarlyReturnTestThread; |
| |
| public class forceEarlyReturn001 |
| extends TestDebuggerType1 |
| { |
| // data needed to create JDWP command, |
| // also this class create breakpoint in method which should be forced to return |
| class TestData |
| { |
| public TestData(long classID, String methodName, int lineNumber, long threadID, Value value, Value invalidValue) |
| { |
| breakpointID = debuggee.requestBreakpointEvent( |
| JDWP.TypeTag.CLASS, |
| classID, |
| debuggee.getMethodID(classID, methodName, true), |
| lineNumber, |
| JDWP.SuspendPolicy.EVENT_THREAD); |
| |
| this.value = value; |
| this.invalidValue = invalidValue; |
| this.threadID = threadID; |
| } |
| |
| public int breakpointID; |
| public Value value; |
| public Value invalidValue; |
| public long threadID; |
| } |
| |
| protected String getDebugeeClassName() |
| { |
| return "nsk.jdwp.ThreadReference.ForceEarlyReturn.forceEarlyReturn001.forceEarlyReturn001a"; |
| } |
| |
| public static void main (String argv[]) |
| { |
| System.exit(run(argv,System.out) + Consts.JCK_STATUS_BASE); |
| } |
| |
| public static int run(String argv[], PrintStream out) |
| { |
| return new forceEarlyReturn001().runIt(argv, out); |
| } |
| |
| // send command and receive empty reply |
| // all asserts should be done in debuggee |
| private void sendCommand(long threadID, Value value, boolean expectError, int errorCode) |
| { |
| try |
| { |
| int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.ForceEarlyReturn; |
| |
| log.display("Create command: " + JDWP.commandNames.get(JDWP_COMMAND_ID)); |
| log.display("threadID = " + threadID); |
| log.display("Value = " + value); |
| |
| CommandPacket command = new CommandPacket(JDWP_COMMAND_ID); |
| command.addObjectID(threadID); |
| command.addValue(value); |
| command.setLength(); |
| |
| log.display("Sending command packet:\n" + command); |
| transport.write(command); |
| |
| ReplyPacket reply; |
| |
| reply = getReply(command, expectError, errorCode); |
| |
| if(expectError) |
| return; |
| |
| log.display("Empty reply"); |
| |
| if(!reply.isParsed()) |
| { |
| setSuccess(false); |
| log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition()); |
| } |
| } |
| catch(Exception e) |
| { |
| setSuccess(false); |
| log.complain("Caught exception while testing JDWP command: " + e); |
| e.printStackTrace(log.getOutStream()); |
| } |
| } |
| |
| private TestData[] testData; |
| |
| // create Value objects which should be send in command packet and |
| // initialize breapoints in tested methods |
| private void initTestData() |
| { |
| long classID = debuggee.getReferenceTypeID(createTypeSignature(ForceEarlyReturnTestThread.class.getName())); |
| |
| Value testValues[] = new Value[ForceEarlyReturnTestThread.testedTypesNames.length + 1]; |
| Value testInvalidValues[] = new Value[ForceEarlyReturnTestThread.testedTypesNames.length + 1]; |
| |
| testValues[0] = new JDWP.Value(JDWP.Tag.VOID, new Long(0)); |
| |
| for(int i = 1; i < ForceEarlyReturnTestThread.testedTypesNames.length; i++) |
| { |
| testValues[i] = debuggee.getStaticFieldValue( |
| classID, |
| debuggee.getClassFieldID(classID, "expected" + ForceEarlyReturnTestThread.testedTypesNames[i] + "Value", true)); |
| } |
| |
| for(int i = 0; i < ForceEarlyReturnTestThread.testedTypesNames.length; i++) |
| { |
| testInvalidValues[i] = debuggee.getStaticFieldValue( |
| classID, |
| debuggee.getClassFieldID(classID, "invalid" + ForceEarlyReturnTestThread.testedTypesNames[i] + "Value", true)); |
| } |
| |
| long threadID = debuggee.getThreadID(forceEarlyReturn001a.testThreadName); |
| |
| testData = new TestData[ForceEarlyReturnTestThread.testedTypesNames.length]; |
| |
| for(int i = 0; i < ForceEarlyReturnTestThread.testedTypesNames.length; i++) |
| { |
| testData[i] = new TestData(classID, |
| ForceEarlyReturnTestThread.testedTypesNames[i] + "Method", |
| ForceEarlyReturnTestThread.breakpointLines[i], |
| threadID, |
| testValues[i], |
| testInvalidValues[i]); |
| } |
| } |
| |
| public void doTest() |
| { |
| initTestData(); |
| |
| pipe.println(forceEarlyReturn001a.COMMAND_START_EXECUTION); |
| |
| if(!isDebuggeeReady()) |
| return; |
| |
| for(int i = 0; i < testData.length; i++) |
| { |
| // wait when tested thread call method with breapoint |
| debuggee.waitForBreakpointEvent(testData[i].breakpointID); |
| |
| log.display("Send invalid command: valid value: " + testData[i].value + " invalid value: " + testData[i].invalidValue); |
| // send ForceEarlyReturn command with invalid value |
| sendCommand(testData[i].threadID, testData[i].invalidValue, true, JDWP.Error.TYPE_MISMATCH); |
| |
| log.display("Send valid command: valid value: " + testData[i].value); |
| // send ForceEarlyReturn command |
| sendCommand(testData[i].threadID, testData[i].value, false, 0); |
| |
| // resume debuggee |
| debuggee.resume(); |
| } |
| |
| pipe.println(forceEarlyReturn001a.COMMAND_END_EXECUTION); |
| |
| if(!isDebuggeeReady()) |
| return; |
| } |
| } |