blob: 3e1fec40cd0f75b25caec80021db540336e50870 [file] [log] [blame]
/*
* 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;
}
}