提交 09a1f7fc 编写于 作者: S sla

6461635: [TESTBUG] BasicTests.sh test fails intermittently

Summary: Transform dummy class instead of BigInteger to avoid complication by -Xshare. Ported from script to java.
Reviewed-by: alanb
Contributed-by: mattias.tobiasson@oracle.com
上级 02808aba
......@@ -266,9 +266,6 @@ sun/security/krb5/auto/BadKdc4.java solaris-sparcv9
# jdk_tools
# 6461635
com/sun/tools/attach/BasicTests.sh generic-all
# 7132203
sun/jvmstat/monitor/MonitoredVm/CR6672135.java generic-all
......
#!/bin/sh
#
# Copyright (c) 2005, 2006, 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.
#
#
#
# Agent set - creates Agent.jar, BadAgent.jar and RedefineAgent.jar in ${TESTCLASSES}
$JAVAC -d "${TESTCLASSES}" "${TESTSRC}"/Agent.java "${TESTSRC}"/BadAgent.java "${TESTSRC}"/RedefineAgent.java
$JAR -cfm "${TESTCLASSES}"/Agent.jar "${TESTSRC}"/agent.mf \
-C "${TESTCLASSES}" Agent.class
$JAR -cfm "${TESTCLASSES}"/BadAgent.jar "${TESTSRC}"/badagent.mf \
-C "${TESTCLASSES}" BadAgent.class
$JAR -cfm "${TESTCLASSES}"/RedefineAgent.jar "${TESTSRC}"/redefineagent.mf \
-C "${TESTCLASSES}" RedefineAgent.class
agent="${TESTCLASSES}${FS}Agent.jar"
badagent="${TESTCLASSES}${FS}BadAgent.jar"
redefineagent="${TESTCLASSES}${FS}RedefineAgent.jar"
......@@ -22,25 +22,39 @@
*/
/*
*
*
* A simple "Application" used by the Attach API unit tests. This application is
* launched by the test. It binds to a random port and shuts down when somebody
* connects to that port.
* Used port and pid are written both to stdout and to a specified file.
*/
import java.net.Socket;
import java.net.ServerSocket;
import java.io.PrintWriter;
import jdk.testlibrary.ProcessTools;
public class Application {
public static void main(String args[]) throws Exception {
// bind to a random port
if (args.length < 1) {
System.err.println("First argument should be path to output file.");
}
String outFileName = args[0];
ServerSocket ss = new ServerSocket(0);
int port = ss.getLocalPort();
int pid = ProcessTools.getProcessId();
// signal test that we are started - do not remove this line!!
System.out.println(port);
System.out.println("shutdownPort=" + port);
System.out.println("pid=" + pid);
System.out.flush();
try (PrintWriter writer = new PrintWriter(outFileName)) {
writer.println("shutdownPort=" + port);
writer.println("pid=" + pid);
writer.println("done");
writer.flush();
}
// wait for test harness to connect
Socket s = ss.accept();
s.close();
......
#!/bin/sh
#
# Copyright (c) 2005, 2011, 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.
#
#
#
# Application Setup - creates ${TESTCLASSES}/Application.jar and the following
# procedures:
# startApplication - starts target application
# stopApplication $1 - stops application via TCP shutdown port $1
$JAVAC -d "${TESTCLASSES}" "${TESTSRC}"/Application.java "${TESTSRC}"/Shutdown.java
$JAR -cfm "${TESTCLASSES}"/Application.jar "${TESTSRC}"/application.mf \
-C "${TESTCLASSES}" Application.class
OUTPUTFILE=${TESTCLASSES}/Application.out
rm -f ${OUTPUTFILE}
startApplication()
{
# put all output from the app into ${OUTPUTFILE}
${JAVA} ${TESTVMOPTS} $1 $2 $3 -jar "${TESTCLASSES}"/Application.jar > ${OUTPUTFILE} 2>&1 &
pid="$!"
# MKS creates an intermediate shell to launch ${JAVA} so
# ${pid} is not the actual pid. We have put in a small sleep
# to give the intermediate shell process time to launch the
# "java" process.
if [ "$OS" = "Windows" ]; then
sleep 2
if [ "${isCygwin}" = "true" ] ; then
realpid=`ps -p ${pid} | tail -1 | awk '{print $4;}'`
else
realpid=`ps -o pid,ppid,comm|grep ${pid}|grep "java"|cut -c1-6`
fi
pid=${realpid}
fi
echo "Waiting for Application to initialize..."
attempts=0
while true; do
sleep 1
port=`tail -1 ${OUTPUTFILE} | sed -e 's@\\r@@g' `
if [ ! -z "$port" ]; then
# In case of errors wait time for output to be flushed
sleep 1
cat ${OUTPUTFILE}
break
fi
attempts=`expr $attempts + 1`
echo "Waiting $attempts second(s) ..."
done
echo "Application is process $pid, shutdown port is $port"
return $port
}
stopApplication()
{
$JAVA ${TESTVMOPTS} -classpath "${TESTCLASSES}" Shutdown $1
}
/*
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2011, 2013 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
......@@ -21,160 +21,257 @@
* questions.
*/
/*
*
*
* Unit test for Attach API. Attaches to the given VM and performs a number
* unit tests.
*/
import com.sun.tools.attach.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;
import java.util.Properties;
import java.util.List;
import java.io.File;
import jdk.testlibrary.OutputAnalyzer;
import jdk.testlibrary.JDKToolLauncher;
import jdk.testlibrary.ProcessTools;
import jdk.testlibrary.ProcessThread;
/*
* @test
* @bug 6173612 6273707 6277253 6335921 6348630 6342019 6381757
* @summary Basic unit tests for the VM attach mechanism.
* @library /lib/testlibrary
* @run build Agent BadAgent RedefineAgent Application Shutdown RedefineDummy
* @run main BasicTests
*
* This test will perform a number of basic attach tests.
*/
public class BasicTests {
public static void main(String args[]) throws Exception {
String pid = args[0];
String agent = args[1];
String badagent = args[2];
String redefineagent = args[3];
System.out.println(" - Attaching to application ...");
VirtualMachine vm = VirtualMachine.attach(pid);
// Test 1 - read the system properties from the target VM and
// check that property is set
System.out.println(" - Test: system properties in target VM");
Properties props = vm.getSystemProperties();
String value = props.getProperty("attach.test");
if (value == null || !value.equals("true")) {
throw new RuntimeException("attach.test property not set");
}
System.out.println(" - attach.test property set as expected");
// Test 1a - read the agent properties from the target VM.
// By default, the agent property contains "sun.java.command",
// "sun.jvm.flags", and "sun.jvm.args".
// Just sanity check - make sure not empty.
System.out.println(" - Test: agent properties in target VM");
props = vm.getAgentProperties();
if (props == null || props.size() == 0) {
throw new RuntimeException("Agent properties is empty");
}
System.out.println(" - agent properties non-empty as expected");
// Test 2 - attempt to load an agent that does not exist
System.out.println(" - Test: Load an agent that does not exist");
/*
* The actual test is in the nested class TestMain.
* The responsibility of this class is to:
* 1. Build all needed jars.
* 2. Start the Application class in a separate process.
* 3. Find the pid and shutdown port of the running Application.
* 4. Launches the tests in nested class TestMain that will attach to the Application.
* 5. Shut down the Application.
*/
public static void main(String args[]) throws Throwable {
final String pidFile = "TestsBasic.Application.pid";
ProcessThread processThread = null;
RunnerUtil.ProcessInfo info = null;
try {
vm.loadAgent("SilverBullet.jar");
} catch (AgentLoadException x) {
System.out.println(" - AgentLoadException thrown as expected!");
buildJars();
processThread = RunnerUtil.startApplication(pidFile);
info = RunnerUtil.readProcessInfo(pidFile);
runTests(info.pid);
} catch (Throwable t) {
System.out.println("TestBasic got unexpected exception: " + t);
t.printStackTrace();
throw t;
} finally {
// Make sure the Application process is stopped.
RunnerUtil.stopApplication(info.shutdownPort, processThread);
}
}
// Test 3 - load an "bad" agent (agentmain throws an exception)
System.out.println(" - Test: Load a bad agent");
System.out.println("INFO: This test will cause error messages "
+ "to appear in the application log about SilverBullet.jar "
+ "not being found and an agent failing to start.");
try {
vm.loadAgent(badagent);
throw new RuntimeException(
"AgentInitializationException not thrown as expected!");
} catch (AgentInitializationException x) {
System.out.println(
" - AgentInitializationException thrown as expected!");
}
/**
* Runs the actual tests in nested class TestMain.
* The reason for running the tests in a separate process
* is that we need to modify the class path.
*/
private static void runTests(int pid) throws Throwable {
final String sep = File.separator;
// Test 4 - detach from the VM and attempt a load (should throw IOE)
System.out.println(" - Test: Detach from VM");
System.out.println("INFO: This test will cause error messages "
+ "to appear in the application log about a BadAgent including "
+ "a RuntimeException and an InvocationTargetException.");
vm.detach();
try {
vm.loadAgent(agent);
throw new RuntimeException("loadAgent did not throw an exception!!");
} catch (IOException ioe) {
System.out.println(" - IOException as expected");
// Need to add jdk/lib/tools.jar to classpath.
String classpath =
System.getProperty("test.class.path", "") + File.pathSeparator +
System.getProperty("test.jdk", ".") + sep + "lib" + sep + "tools.jar";
String testClassDir = System.getProperty("test.classes", "") + sep;
// Argumenta : -classpath cp BasicTests$TestMain pid agent badagent redefineagent
String[] args = {
"-classpath",
classpath,
"BasicTests$TestMain",
Integer.toString(pid),
testClassDir + "Agent.jar",
testClassDir + "BadAgent.jar",
testClassDir + "RedefineAgent.jar" };
OutputAnalyzer output = ProcessTools.executeTestJvm(args);
output.shouldHaveExitValue(0);
}
/**
* Will build all jars needed by the tests.
*/
private static void buildJars() throws Throwable {
String[] jars = {"Agent", "BadAgent", "RedefineAgent", "Application" };
for (String jar : jars) {
buildJar(jar);
}
}
// Test 5 - functional "end-to-end" test.
// Create a listener socket. Load Agent.jar into the target VM passing
// it the port number of our listener. When agent loads it should connect
// back to the tool.
/**
* Will build a jar with the given name.
* Class file and manifest must already exist.
* @param jarName Name of the jar.
*/
private static void buildJar(String jarName) throws Throwable {
String testClasses = System.getProperty("test.classes", "?");
String testSrc = System.getProperty("test.src", "?");
String jar = String.format("%s/%s.jar", testClasses, jarName);
String manifest = String.format("%s/%s.mf", testSrc, jarName.toLowerCase());
String clazz = String.format("%s.class", jarName);
System.out.println(" - Re-attaching to application ...");
vm = VirtualMachine.attach(pid);
// Arguments to the jar command has this format:
// "-cfm TESTCLASSES/Agent.jar TESTSRC/agent.mf -C TESTCLASSES Agent.class"
RunnerUtil.createJar("-cfm", jar, manifest, "-C", testClasses, clazz);
}
System.out.println(" - Test: End-to-end connection with agent");
/**
* This is the actual test. It will attach to the running Application
* and perform a number of basic attach tests.
*/
public static class TestMain {
public static void main(String args[]) throws Exception {
String pid = args[0];
String agent = args[1];
String badagent = args[2];
String redefineagent = args[3];
ServerSocket ss = new ServerSocket(0);
int port = ss.getLocalPort();
System.out.println(" - Attaching to application ...");
VirtualMachine vm = VirtualMachine.attach(pid);
System.out.println(" - Loading Agent.jar into target VM ...");
vm.loadAgent(agent, Integer.toString(port));
// Test 1 - read the system properties from the target VM and
// check that property is set
System.out.println(" - Test: system properties in target VM");
Properties props = vm.getSystemProperties();
String value = props.getProperty("attach.test");
if (value == null || !value.equals("true")) {
throw new RuntimeException("attach.test property not set");
}
System.out.println(" - attach.test property set as expected");
System.out.println(" - Waiting for agent to connect back to tool ...");
Socket s = ss.accept();
System.out.println(" - Connected to agent.");
// Test 1a - read the agent properties from the target VM.
// By default, the agent property contains "sun.java.command",
// "sun.jvm.flags", and "sun.jvm.args".
// Just sanity check - make sure not empty.
System.out.println(" - Test: agent properties in target VM");
props = vm.getAgentProperties();
if (props == null || props.size() == 0) {
throw new RuntimeException("Agent properties is empty");
}
System.out.println(" - agent properties non-empty as expected");
// Test 5b - functional "end-to-end" test.
// Now with an agent that does redefine.
// Test 2 - attempt to load an agent that does not exist
System.out.println(" - Test: Load an agent that does not exist");
try {
vm.loadAgent("SilverBullet.jar");
} catch (AgentLoadException x) {
System.out.println(" - AgentLoadException thrown as expected!");
}
System.out.println(" - Re-attaching to application ...");
vm = VirtualMachine.attach(pid);
// Test 3 - load an "bad" agent (agentmain throws an exception)
System.out.println(" - Test: Load a bad agent");
System.out.println("INFO: This test will cause error messages "
+ "to appear in the application log about SilverBullet.jar "
+ "not being found and an agent failing to start.");
try {
vm.loadAgent(badagent);
throw new RuntimeException(
"AgentInitializationException not thrown as expected!");
} catch (AgentInitializationException x) {
System.out.println(
" - AgentInitializationException thrown as expected!");
}
// Test 4 - detach from the VM and attempt a load (should throw IOE)
System.out.println(" - Test: Detach from VM");
System.out.println("INFO: This test will cause error messages "
+ "to appear in the application log about a BadAgent including "
+ "a RuntimeException and an InvocationTargetException.");
vm.detach();
try {
vm.loadAgent(agent);
throw new RuntimeException("loadAgent did not throw an exception!!");
} catch (IOException ioe) {
System.out.println(" - IOException as expected");
}
// Test 5 - functional "end-to-end" test.
// Create a listener socket. Load Agent.jar into the target VM passing
// it the port number of our listener. When agent loads it should connect
// back to the tool.
System.out.println(" - Re-attaching to application ...");
vm = VirtualMachine.attach(pid);
System.out.println(" - Test: End-to-end connection with agent");
ServerSocket ss = new ServerSocket(0);
int port = ss.getLocalPort();
System.out.println(" - Loading Agent.jar into target VM ...");
vm.loadAgent(agent, Integer.toString(port));
System.out.println(" - Waiting for agent to connect back to tool ...");
Socket s = ss.accept();
System.out.println(" - Connected to agent.");
// Test 5b - functional "end-to-end" test.
// Now with an agent that does redefine.
System.out.println(" - Test: End-to-end connection with RedefineAgent");
System.out.println(" - Re-attaching to application ...");
vm = VirtualMachine.attach(pid);
ServerSocket ss2 = new ServerSocket(0);
int port2 = ss2.getLocalPort();
System.out.println(" - Test: End-to-end connection with RedefineAgent");
System.out.println(" - Loading RedefineAgent.jar into target VM ...");
vm.loadAgent(redefineagent, Integer.toString(port2));
ServerSocket ss2 = new ServerSocket(0);
int port2 = ss2.getLocalPort();
System.out.println(" - Waiting for RedefineAgent to connect back to tool ...");
Socket s2 = ss2.accept();
System.out.println(" - Connected to RedefineAgent.");
System.out.println(" - Loading RedefineAgent.jar into target VM ...");
vm.loadAgent(redefineagent, Integer.toString(port2));
// Test 6 - list method should list the target VM
System.out.println(" - Test: VirtualMachine.list");
List<VirtualMachineDescriptor> l = VirtualMachine.list();
if (!l.isEmpty()) {
boolean found = false;
for (VirtualMachineDescriptor vmd: l) {
if (vmd.id().equals(pid)) {
found = true;
break;
System.out.println(" - Waiting for RedefineAgent to connect back to tool ...");
Socket s2 = ss2.accept();
System.out.println(" - Connected to RedefineAgent.");
// Test 6 - list method should list the target VM
System.out.println(" - Test: VirtualMachine.list");
List<VirtualMachineDescriptor> l = VirtualMachine.list();
if (!l.isEmpty()) {
boolean found = false;
for (VirtualMachineDescriptor vmd: l) {
if (vmd.id().equals(pid)) {
found = true;
break;
}
}
if (found) {
System.out.println(" - " + pid + " found.");
} else {
throw new RuntimeException(pid + " not found in VM list");
}
}
if (found) {
System.out.println(" - " + pid + " found.");
} else {
throw new RuntimeException(pid + " not found in VM list");
}
}
// test 7 - basic hashCode/equals tests
System.out.println(" - Test: hashCode/equals");
VirtualMachine vm1 = VirtualMachine.attach(pid);
VirtualMachine vm2 = VirtualMachine.attach(pid);
if (!vm1.equals(vm2)) {
throw new RuntimeException("virtual machines are not equal");
}
if (vm.hashCode() != vm.hashCode()) {
throw new RuntimeException("virtual machine hashCodes not equal");
}
System.out.println(" - hashCode/equals okay");
// test 7 - basic hashCode/equals tests
System.out.println(" - Test: hashCode/equals");
VirtualMachine vm1 = VirtualMachine.attach(pid);
VirtualMachine vm2 = VirtualMachine.attach(pid);
if (!vm1.equals(vm2)) {
throw new RuntimeException("virtual machines are not equal");
}
if (vm.hashCode() != vm.hashCode()) {
throw new RuntimeException("virtual machine hashCodes not equal");
}
System.out.println(" - hashCode/equals okay");
// ---
System.out.println(" - Cleaning up...");
s.close();
ss.close();
s2.close();
ss2.close();
// ---
System.out.println(" - Cleaning up...");
s.close();
ss.close();
s2.close();
ss2.close();
}
}
}
#!/bin/sh
#
# Copyright (c) 2005, 2011, 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
# @bug 6173612 6273707 6277253 6335921 6348630 6342019 6381757
# @summary Basic unit tests for the VM attach mechanism.
#
# @build BasicTests
# @run shell BasicTests.sh
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
# Windows 2000 is a problem here, so we skip it, see 6962615
osrev=`uname -a`
if [ "`echo ${osrev} | grep 'CYGWIN[^ ]*-5\.0'`" != "" ] ; then
echo "Treating as a pass, not testing Windows 2000"
exit 0
fi
if [ "`echo ${osrev} | grep 'Windows'`" != "" ] ; then
if [ "`echo ${osrev} | grep '5 00'`" != "" ] ; then
echo "Treating as a pass, not testing Windows 2000"
exit 0
fi
fi
. ${TESTSRC}/CommonSetup.sh
. ${TESTSRC}/ApplicationSetup.sh
. ${TESTSRC}/AgentSetup.sh
startApplication -Dattach.test=true
# pid = process-id, port = shutdown port
failures=0
echo "Running tests ..."
$JAVA ${TESTVMOPTS} -classpath "${TESTCLASSES}${PS}${TESTJAVA}/lib/tools.jar" \
BasicTests $pid $agent $badagent $redefineagent 2>&1
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
stopApplication $port
# Add these info messages to $OUTPUTFILE just in case someone
# looks at it and wonders about the failures. We have to do
# this after the application is stopped because it is writing
# to $OUTPUTFILE.
(
echo ""
echo "INFO: Test 2 will cause error messages about SilverBullet.jar" \
"and an agent failing to start."
echo "INFO: Test 3 will cause error messages about BadAgent" \
"including a RuntimeException and an InvocationTargetException."
) >> ${OUTPUTFILE}
if [ $failures = 0 ];
then echo "All tests passed.";
else echo "$failures test(s) failed:"; cat ${OUTPUTFILE};
fi
exit $failures
#!/bin/sh
#
# Copyright (c) 2005, 2012, 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.
#
#
#
# Common setup for the Attach API unit tests. Setups up the following variables:
#
# PS - path sep.
# FS - file sep.
# JAVA - java cmd.
# JAVAC - javac cmd.
# JAR - jar cmd.
OS=`uname -s`
case "$OS" in
SunOS | Linux | Darwin )
PS=":"
FS="/"
;;
Windows* )
PS=";"
OS="Windows"
FS="\\"
;;
CYGWIN* )
PS=";"
OS="Windows"
FS="\\"
isCygwin=true
;;
* )
echo "Unrecognized system!"
exit 1;
;;
esac
if [ "${TESTJAVA}" = "" ]
then
echo "TESTJAVA not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTCLASSES}" = "" ]
then
echo "TESTCLASSES not set. Test cannot execute. Failed."
exit 1
fi
JAVA="${TESTJAVA}/bin/java"
JAVAC="${TESTJAVA}/bin/javac"
JAR="${TESTJAVA}/bin/jar"
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2013 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
......@@ -21,39 +21,119 @@
* questions.
*/
/*
*
*
* Unit test for Attach API - this checks that a SecurityException is thrown as
* expected.
*/
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.AttachNotSupportedException;
import java.util.Properties;
import java.io.File;
import jdk.testlibrary.OutputAnalyzer;
import jdk.testlibrary.ProcessTools;
import jdk.testlibrary.ProcessThread;
/*
* @test
* @bug 6173612 6273707 6277253 6335921 6348630 6342019 6381757
* @summary Basic unit tests for the VM attach mechanism.
* @library /lib/testlibrary
* @run build Application Shutdown
* @run main PermissionTest
*
* Unit test for Attach API -
* this checks that a SecurityException is thrown as expected.
*/
public class PermissionTest {
public static void main(String args[]) throws Exception {
SecurityManager sm = System.getSecurityManager();
if (sm == null) {
throw new RuntimeException("Test configuration error - no security manager set");
/*
* The actual test is in the nested class TestMain.
* The responsibility of this class is to:
* 1. Start the Application class in a separate process.
* 2. Find the pid and shutdown port of the running Application.
* 3. Run the tests in TstMain that will attach to the Application.
* 4. Shut down the Application.
*/
public static void main(String args[]) throws Throwable {
final String pidFile ="TestPermission.Application.pid";
ProcessThread processThread = null;
RunnerUtil.ProcessInfo info = null;
try {
processThread = RunnerUtil.startApplication(pidFile);
info = RunnerUtil.readProcessInfo(pidFile);
runTests(info.pid);
} catch (Throwable t) {
System.out.println("TestPermission got unexpected exception: " + t);
t.printStackTrace();
throw t;
} finally {
// Make sure the Application process is stopped.
RunnerUtil.stopApplication(info.shutdownPort, processThread);
}
}
String pid = args[0];
boolean shouldFail = Boolean.parseBoolean(args[1]);
/**
* Runs the actual test the nested class TestMain.
* The test is run in a separate process because we need to add to the classpath.
*/
private static void runTests(int pid) throws Throwable {
final String sep = File.separator;
try {
VirtualMachine.attach(pid).detach();
if (shouldFail) {
throw new RuntimeException("SecurityException should be thrown");
// Need to add jdk/lib/tools.jar to classpath.
String classpath =
System.getProperty("test.class.path", "") + File.pathSeparator +
System.getProperty("test.jdk", ".") + sep + "lib" + sep + "tools.jar";
String testSrc = System.getProperty("test.src", "") + sep;
// Use a policy that will NOT allow attach. Test will verify exception.
String[] args = {
"-classpath",
classpath,
"-Djava.security.manager",
String.format("-Djava.security.policy=%sjava.policy.deny", testSrc),
"PermissionTest$TestMain",
Integer.toString(pid),
"true" };
OutputAnalyzer output = ProcessTools.executeTestJvm(args);
output.shouldHaveExitValue(0);
// Use a policy that will allow attach.
args = new String[] {
"-classpath",
classpath,
"-Djava.security.manager",
String.format("-Djava.security.policy=%sjava.policy.allow", testSrc),
"PermissionTest$TestMain",
Integer.toString(pid),
"false" };
output = ProcessTools.executeTestJvm(args);
output.shouldHaveExitValue(0);
}
/**
* This is the actual test code. It will attach to the Application and verify
* that we get a SecurityException when that is expected.
*/
public static class TestMain {
public static void main(String args[]) throws Exception {
SecurityManager sm = System.getSecurityManager();
if (sm == null) {
throw new RuntimeException("Test configuration error - no security manager set");
}
System.out.println(" - attached to target VM as expected.");
} catch (Exception x) {
// AttachNotSupportedException thrown when no providers can be loaded
if (shouldFail && ((x instanceof AttachNotSupportedException) ||
(x instanceof SecurityException))) {
System.out.println(" - exception thrown as expected.");
} else {
throw x;
String pid = args[0];
boolean shouldFail = Boolean.parseBoolean(args[1]);
try {
VirtualMachine.attach(pid).detach();
if (shouldFail) {
throw new RuntimeException("SecurityException should be thrown");
}
System.out.println(" - attached to target VM as expected.");
} catch (Exception x) {
// AttachNotSupportedException thrown when no providers can be loaded
if (shouldFail && ((x instanceof AttachNotSupportedException) ||
(x instanceof SecurityException))) {
System.out.println(" - exception thrown as expected.");
} else {
throw x;
}
}
}
}
......
#!/bin/sh
#
# Copyright (c) 2005, 2010, 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
# @bug 6173612
# @summary Security manager and permission tests for Attach API
#
# @build PermissionTest
# @run shell PermissionTests.sh
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
. ${TESTSRC}/CommonSetup.sh
. ${TESTSRC}/ApplicationSetup.sh
failures=0
# Start target VM
startApplication
# pid = process-id, port = shutdown port
echo "Deny test"
# deny
$JAVA ${TESTVMOPTS} -classpath "${TESTCLASSES}${PS}${TESTJAVA}/lib/tools.jar" \
-Djava.security.manager \
-Djava.security.policy=${TESTSRC}/java.policy.deny \
PermissionTest $pid true 2>&1
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
# allow
echo "Allow test"
$JAVA ${TESTVMOPTS} -classpath "${TESTCLASSES}${PS}${TESTJAVA}/lib/tools.jar" \
-Djava.security.manager \
-Djava.security.policy=${TESTSRC}/java.policy.allow \
PermissionTest $pid false 2>&1
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
# Stop target VM
stopApplication $port
if [ $failures = 0 ];
then echo "All tests passed.";
else echo "$failures test(s) failed:"; cat ${OUTPUTFILE};
fi
exit $failures
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2013 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
......@@ -21,24 +21,98 @@
* questions.
*/
/*
*
*
* Unit test for Attach API. Attaches to the given VM and performs a number
* unit tests.
*/
import java.io.File;
import jdk.testlibrary.OutputAnalyzer;
import jdk.testlibrary.JDKToolLauncher;
import jdk.testlibrary.ProcessTools;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.spi.AttachProvider;
/*
* @test
* @bug 6173612 6273707 6277253 6335921 6348630 6342019 6381757
* @summary Basic unit tests for the VM attach mechanism.
* @library /lib/testlibrary
* @run build SimpleProvider
* @run main ProviderTest
*
* The test will attach and detach to/from the running Application.
*/
public class ProviderTest {
public static void main(String args[]) throws Exception {
// deal with internal builds where classes are loaded from the
// 'classes' directory rather than rt.jar
ClassLoader cl = AttachProvider.class.getClassLoader();
if (cl != ClassLoader.getSystemClassLoader()) {
System.out.println("Attach API not loaded by system class loader - test skipped");
return;
/*
* The actual tests are in the nested class TestMain below.
* The responsibility of this class is to:
* 1. Build the needed jar.
* 2. Run tests in ProviderTest.TestMain.
*/
public static void main(String args[]) throws Throwable {
try {
buildJar();
runTests();
} catch (Throwable t) {
System.out.println("TestProvider got unexpected exception: " + t);
t.printStackTrace();
throw t;
}
}
/**
* Runs the actual tests in the nested class TestMain.
* We need to run the tests in a separate process,
* because we need to add to the classpath.
*/
private static void runTests() throws Throwable {
final String sep = File.separator;
String testClassPath = System.getProperty("test.class.path", "");
String testClasses = System.getProperty("test.classes", "") + sep;
String jdkLib = System.getProperty("test.jdk", ".") + sep + "lib" + sep;
// Need to add SimpleProvider.jar and tools.jar to classpath.
String classpath =
testClassPath + File.pathSeparator +
testClasses + "SimpleProvider.jar" + File.pathSeparator +
jdkLib + "tools.jar";
String[] args = {
"-classpath",
classpath,
"ProviderTest$TestMain" };
OutputAnalyzer output = ProcessTools.executeTestJvm(args);
output.shouldHaveExitValue(0);
}
/**
* Will build the SimpleProvider.jar.
*/
private static void buildJar() throws Throwable {
final String sep = File.separator;
String testClasses = System.getProperty("test.classes", "?") + sep;
String testSrc = System.getProperty("test.src", "?") + sep;
String serviceDir = "META-INF" + sep + "services" + sep;
RunnerUtil.createJar(
"-cf", testClasses + "SimpleProvider.jar",
"-C", testClasses, "SimpleProvider.class",
"-C", testClasses, "SimpleVirtualMachine.class",
"-C", testSrc,
serviceDir + "com.sun.tools.attach.spi.AttachProvider");
}
/**
* This is the actual test code that attaches to the running Application.
* This class is run in a separate process.
*/
public static class TestMain {
public static void main(String args[]) throws Exception {
// deal with internal builds where classes are loaded from the
// 'classes' directory rather than rt.jar
ClassLoader cl = AttachProvider.class.getClassLoader();
if (cl != ClassLoader.getSystemClassLoader()) {
System.out.println("Attach API not loaded by system class loader - test skipped");
return;
}
VirtualMachine.attach("simple:1234").detach();
}
VirtualMachine.attach("simple:1234").detach();
}
}
#
# Copyright (c) 2005, 2010, 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
# @bug 6173612
# @summary AttachProvider unit tests
#
# @build ProviderTest SimpleProvider
# @run shell ProviderTests.sh
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
. ${TESTSRC}/CommonSetup.sh
echo "Creating JAR file ..."
$JAR -cf ${TESTCLASSES}/SimpleProvider.jar \
-C ${TESTCLASSES} SimpleProvider.class \
-C ${TESTCLASSES} SimpleVirtualMachine.class \
-C "${TESTSRC}" META-INF/services/com.sun.tools.attach.spi.AttachProvider
echo "Running test ..."
$JAVA ${TESTVMOPTS} -classpath \
"${TESTCLASSES}${PS}${TESTCLASSES}/SimpleProvider.jar${PS}${TESTJAVA}/lib/tools.jar" \
ProviderTest
......@@ -43,15 +43,15 @@ import java.lang.instrument.ClassDefinition;
public class RedefineAgent implements ClassFileTransformer {
static byte[] classfilebytes;
static final String targetName = "java.math.BigInteger";
static final String targetNameSlashes = "java/math/BigInteger";
static final String targetName = "RedefineDummy";
static final String targetNameSlashes = "RedefineDummy";
static boolean gotRedefineTransform = false;
// test transform and capture class bytes for redefine
public byte[] transform(ClassLoader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
ProtectionDomain protectionDomain,
byte[] classfileBuffer) {
if (className.equals(targetNameSlashes)) {
if (classBeingRedefined == null) {
......
/*
* Copyright (c) 2013, 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.
*/
/*
* Simple dummy class used to test class retransform.
*/
public class RedefineDummy {
public String toString() {
return "RedefineDummy";
}
}
/*
* Copyright (c) 2013, 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.
*/
import java.io.IOException;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import jdk.testlibrary.OutputAnalyzer;
import jdk.testlibrary.JDKToolLauncher;
import jdk.testlibrary.ProcessTools;
import jdk.testlibrary.Utils;
import jdk.testlibrary.ProcessThread;
/*
* Utility functions for test runners.
* (Test runner = class that launch a test)
*/
public class RunnerUtil {
/**
* The Application process must be run concurrently with our tests since
* the tests will attach to the Application.
* We will run the Application process in a separate thread.
*
* The Application must be started with flag "-Xshare:off" for the Retransform
* test in TestBasics to pass on all platforms.
*
* The Application will write its pid and shutdownPort in the given outFile.
*/
public static ProcessThread startApplication(String outFile) throws Throwable {
String classpath = System.getProperty("test.class.path", ".");
String[] args = Utils.addTestJavaOpts(
"-Dattach.test=true", "-classpath", classpath, "Application", outFile);
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
ProcessThread pt = new ProcessThread("runApplication", pb);
pt.start();
return pt;
}
/**
* Will stop the running Application.
* First tries to shutdown nicely by connecting to the shut down port.
* If that fails, the process will be killed hard with stopProcess().
*
* If the nice shutdown fails, then an Exception is thrown and the test should fail.
*
* @param port The shut down port.
* @param processThread The process to stop.
*/
public static void stopApplication(int port, ProcessThread processThread) throws Throwable {
if (processThread == null) {
System.out.println("RunnerUtil.stopApplication ignored since proc is null");
return;
}
try {
System.out.println("RunnerUtil.stopApplication waiting to for shutdown");
OutputAnalyzer output = ProcessTools.executeTestJvm(
"-classpath",
System.getProperty("test.class.path", "."),
"Shutdown",
Integer.toString(port));
// Verify that both the Shutdown command and the Application finished ok.
output.shouldHaveExitValue(0);
processThread.joinAndThrow();
processThread.getOutput().shouldHaveExitValue(0);
} catch (Throwable t) {
System.out.println("RunnerUtil.stopApplication failed. Will kill it hard: " + t);
processThread.stopProcess();
throw t;
}
}
/**
* Creates a jar file.
* @param args Command to the jar tool.
*/
public static void createJar(String... args) {
System.out.println("Running: jar " + Arrays.toString(args));
sun.tools.jar.Main jar = new sun.tools.jar.Main(System.out, System.err, "jar");
if (!jar.run(args)) {
throw new RuntimeException("jar failed: args=" + Arrays.toString(args));
}
}
/**
* Read process info for the running Application.
* The Application writes its info to a file with this format:
* shutdownPort=42994
* pid=19597
* done
*
* The final "done" is used to make sure the complete file has been written
* before we try to read it.
* This function will wait until the file is available.
*
* @param filename Path to file to read.
* @return The ProcessInfo containing pid and shutdownPort.
*/
public static ProcessInfo readProcessInfo(String filename) throws Throwable {
System.out.println("Reading port and pid from file: " + filename);
File file = new File(filename);
String content = null;
// Read file or wait for it to be created.
while (true) {
content = readFile(file);
if (content != null && content.indexOf("done") >= 0) {
break;
}
Thread.sleep(100);
}
ProcessInfo info = new ProcessInfo();
// search for a line with format: key=nnn
Pattern pattern = Pattern.compile("(\\w*)=([0-9]+)\\r?\\n");
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
String key = matcher.group(1);
int value = Integer.parseInt(matcher.group(2));
if ("pid".equals(key)) {
info.pid = value;
} else if ("shutdownPort".equals(key)) {
info.shutdownPort = value;
}
}
System.out.println("processInfo.pid:" + info.pid);
System.out.println("processInfo.shutdownPort:" + info.shutdownPort);
return info;
}
/**
* Read the content of a file.
* @param file The file to read.
* @return The file content or null if file does not exists.
*/
public static String readFile(File file) throws IOException {
if (!file.exists()) {
return null;
}
try {
byte[] bytes = Files.readAllBytes(file.toPath());
String content = new String(bytes);
return content;
} catch (IOException e) {
e.printStackTrace();
throw e;
}
}
/**
* Helper class with info of the running Application.
*/
public static class ProcessInfo {
public int pid = -1;
public int shutdownPort = -1;
}
}
......@@ -34,42 +34,24 @@ import java.util.concurrent.CountDownLatch;
*/
public class ProcessThread extends TestThread {
/**
* Creates a new {@code ProcessThread} object.
*
* @param cmd The list of program and its arguments to pass to {@link ProcessBuilder}
*/
public ProcessThread(List<String> cmd) {
super(new ProcessRunnable(cmd));
}
/**
* Creates a new {@code ProcessThread} object.
*
* @param cmd The string array of program and its arguments to pass to {@link ProcessBuilder}
*/
public ProcessThread(String... cmd) {
super(new ProcessRunnable(cmd));
}
/**
* Creates a new {@code ProcessThread} object.
*
* @param threadName The name of thread
* @param cmd The list of program and its arguments to pass to {@link ProcessBuilder}
* @param cmd The string array of program and its arguments to pass to {@link ProcessBuilder}
*/
public ProcessThread(String threadName, List<String> cmd) {
super(new ProcessRunnable(cmd), threadName);
public ProcessThread(String threadName, String... cmd) {
super(new ProcessRunnable(new ProcessBuilder(cmd)), threadName);
}
/**
* Creates a new {@code ProcessThread} object.
*
* @param threadName The name of thread
* @param cmd The string array of program and its arguments to pass to {@link ProcessBuilder}
* @param threadName The name of thread.
* @param pb The ProcessBuilder to execute.
*/
public ProcessThread(String threadName, String... cmd) {
super(new ProcessRunnable(cmd), threadName);
public ProcessThread(String threadName, ProcessBuilder pb) {
super(new ProcessRunnable(pb), threadName);
}
/**
......@@ -81,6 +63,13 @@ public class ProcessThread extends TestThread {
((ProcessRunnable) getRunnable()).stopProcess();
}
/**
* @return The process output, or null if the process has not yet completed.
*/
public OutputAnalyzer getOutput() {
return ((ProcessRunnable) getRunnable()).getOutput();
}
/**
* {@link Runnable} interface for starting and stopping {@link Process}.
*/
......@@ -89,26 +78,16 @@ public class ProcessThread extends TestThread {
private final ProcessBuilder processBuilder;
private final CountDownLatch latch;
private volatile Process process;
private volatile OutputAnalyzer output;
/**
* Creates a new {@code ProcessRunnable} object.
*
* @param cmd The list of program and its arguments to to pass to {@link ProcessBuilder}
*/
public ProcessRunnable(List<String> cmd) {
super();
this.processBuilder = new ProcessBuilder(cmd);
this.latch = new CountDownLatch(1);
}
/**
* Creates a new {@code ProcessRunnable} object.
*
* @param cmd The string array of program and its arguments to to pass to {@link ProcessBuilder}
* @param pb The {@link ProcessBuilder} to run.
*/
public ProcessRunnable(String... cmd) {
public ProcessRunnable(ProcessBuilder pb) {
super();
this.processBuilder = new ProcessBuilder(cmd);
this.processBuilder = pb;
this.latch = new CountDownLatch(1);
}
......@@ -125,12 +104,16 @@ public class ProcessThread extends TestThread {
latch.countDown();
// Will block...
OutputAnalyzer output = new OutputAnalyzer(this.process);
assertTrue(output.getOutput().isEmpty(), "Should get an empty output, got: "
+ Utils.NEW_LINE + output.getOutput());
assertNotEquals(output.getExitValue(), 0,
"Process exited with unexpected exit code");
try {
output = new OutputAnalyzer(this.process);
} catch (Throwable t) {
String name = Thread.currentThread().getName();
System.out.println(String.format("ProcessThread[%s] failed: %s", name, t.toString()));
throw t;
} finally {
String logMsg = ProcessTools.getProcessLog(processBuilder, output);
System.out.println(logMsg);
}
}
/**
......@@ -142,10 +125,19 @@ public class ProcessThread extends TestThread {
// Wait until process is started
latch.await();
if (this.process != null) {
System.out.println("ProcessThread.stopProcess() will kill process");
this.process.destroy();
}
}
/**
* Returns the OutputAnalyzer with stdout/stderr from the process.
* @return The process output, or null if process not completed.
* @throws InterruptedException
*/
public OutputAnalyzer getOutput() {
return output;
}
}
}
......@@ -266,4 +266,79 @@ public final class ProcessTools {
}
}
/**
* Executes a test jvm process, waits for it to finish and returns the process output.
* The default jvm options from jtreg, test.vm.opts and test.java.opts, are added.
* The java from the test.jdk is used to execute the command.
*
* The command line will be like:
* {test.jdk}/bin/java {test.vm.opts} {test.java.opts} cmds
*
* @param cmds User specifed arguments.
* @return The output from the process.
*/
public static OutputAnalyzer executeTestJvm(String... cmds) throws Throwable {
ProcessBuilder pb = createJavaProcessBuilder(Utils.addTestJavaOpts(cmds));
return executeProcess(pb);
}
/**
* Executes a process, waits for it to finish and returns the process output.
* @param pb The ProcessBuilder to execute.
* @return The output from the process.
*/
public static OutputAnalyzer executeProcess(ProcessBuilder pb) throws Throwable {
OutputAnalyzer output = null;
try {
output = new OutputAnalyzer(pb.start());
return output;
} catch (Throwable t) {
System.out.println("executeProcess() failed: " + t);
throw t;
} finally {
System.out.println(getProcessLog(pb, output));
}
}
/**
* Executes a process, waits for it to finish and returns the process output.
* @param cmds The command line to execute.
* @return The output from the process.
*/
public static OutputAnalyzer executeProcess(String... cmds) throws Throwable {
return executeProcess(new ProcessBuilder(cmds));
}
/**
* Used to log command line, stdout, stderr and exit code from an executed process.
* @param pb The executed process.
* @param output The output from the process.
*/
public static String getProcessLog(ProcessBuilder pb, OutputAnalyzer output) {
String stderr = output == null ? "null" : output.getStderr();
String stdout = output == null ? "null" : output.getStdout();
String exitValue = output == null ? "null": Integer.toString(output.getExitValue());
StringBuilder logMsg = new StringBuilder();
final String nl = System.getProperty("line.separator");
logMsg.append("--- ProcessLog ---" + nl);
logMsg.append("cmd: " + getCommandLine(pb) + nl);
logMsg.append("exitvalue: " + exitValue + nl);
logMsg.append("stderr: " + stderr + nl);
logMsg.append("stdout: " + stdout + nl);
return logMsg.toString();
}
/**
* @return The full command line for the ProcessBuilder.
*/
public static String getCommandLine(ProcessBuilder pb) {
if (pb == null) {
return "null";
}
StringBuilder cmd = new StringBuilder();
for (String s : pb.command()) {
cmd.append(s).append(" ");
}
return cmd.toString().trim();
}
}
......@@ -33,6 +33,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
import java.util.Collections;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
* Common library for various test helper functions.
......@@ -170,4 +172,61 @@ public final class Utils {
return hostName;
}
/**
* Uses "jcmd -l" to search for a jvm pid. This function will wait
* forever (until jtreg timeout) for the pid to be found.
* @param key Regular expression to search for
* @return The found pid.
*/
public static int waitForJvmPid(String key) throws Throwable {
final long iterationSleepMillis = 250;
System.out.println("waitForJvmPid: Waiting for key '" + key + "'");
System.out.flush();
while (true) {
int pid = tryFindJvmPid(key);
if (pid >= 0) {
return pid;
}
Thread.sleep(iterationSleepMillis);
}
}
/**
* Searches for a jvm pid in the output from "jcmd -l".
*
* Example output from jcmd is:
* 12498 sun.tools.jcmd.JCmd -l
* 12254 /tmp/jdk8/tl/jdk/JTwork/classes/com/sun/tools/attach/Application.jar
*
* @param key A regular expression to search for.
* @return The found pid, or -1 if Enot found.
* @throws Exception If multiple matching jvms are found.
*/
public static int tryFindJvmPid(String key) throws Throwable {
ProcessBuilder pb = null;
OutputAnalyzer output = null;
try {
JDKToolLauncher jcmdLauncher = JDKToolLauncher.create("jcmd");
jcmdLauncher.addToolArg("-l");
output = ProcessTools.executeProcess(jcmdLauncher.getCommand());
output.shouldHaveExitValue(0);
// Search for a line starting with numbers (pid), follwed by the key.
Pattern pattern = Pattern.compile("([0-9]+)\\s.*(" + key + ").*\\r?\\n");
Matcher matcher = pattern.matcher(output.getStdout());
int pid = -1;
if (matcher.find()) {
pid = Integer.parseInt(matcher.group(1));
System.out.println("findJvmPid.pid: " + pid);
if (matcher.find()) {
throw new Exception("Found multiple JVM pids for key: " + key);
}
}
return pid;
} catch (Throwable t) {
System.out.println(String.format("Utils.findJvmPid(%s) failed: %s", key, t));
throw t;
}
}
}
......@@ -353,6 +353,14 @@ public final class JstatdTest {
} finally {
cleanUpThread(jstatdThread);
}
// Verify output from jstatd
OutputAnalyzer output = jstatdThread.getOutput();
assertTrue(output.getOutput().isEmpty(),
"jstatd should get an empty output, got: "
+ Utils.NEW_LINE + output.getOutput());
assertNotEquals(output.getExitValue(), 0,
"jstatd process exited with unexpected exit code");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册