提交 2b4d1b78 编写于 作者: J jbachorik

8004926: sun/management/jmxremote/bootstrap/CustomLauncherTest.sh oftenly times out

Summary: Improve reliability by converting the test to Java
Reviewed-by: dsamersoff, dholmes
上级 4380c88c
......@@ -325,7 +325,8 @@ needs_jdk = \
jdk/lambda/separate/Compiler.java \
sun/management/jdp/JdpTest.sh \
sun/management/jmxremote/bootstrap/JvmstatCountersTest.java \
sun/management/jmxremote/bootstrap/LocalManagementTest.sh \
sun/management/jmxremote/bootstrap/LocalManagementTest.java \
sun/management/jmxremote/bootstrap/CustomLauncherTest.java \
sun/misc/JarIndex/metaInfFilenames/Basic.java \
sun/misc/JarIndex/JarIndexMergeForClassLoaderTest.java \
sun/reflect/CallerSensitive/CallerSensitiveFinder.java \
......
......@@ -25,24 +25,127 @@ package jdk.testlibrary;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.Phaser;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Predicate;
import sun.management.VMManagement;
public final class ProcessTools {
private static final class LineForwarder extends StreamPumper.LinePump {
private final PrintStream ps;
private final String prefix;
LineForwarder(String prefix, PrintStream os) {
this.ps = os;
this.prefix = prefix;
}
@Override
protected void processLine(String line) {
ps.println("[" + prefix + "] " + line);
}
}
private ProcessTools() {
}
/**
* <p>Starts a process from its builder.</p>
* <span>The default redirects of STDOUT and STDERR are started</span>
* @param name The process name
* @param processBuilder The process builder
* @return Returns the initialized process
* @throws IOException
*/
public static Process startProcess(String name,
ProcessBuilder processBuilder)
throws IOException {
Process p = null;
try {
p = startProcess(name, processBuilder, null, -1, TimeUnit.NANOSECONDS);
} catch (InterruptedException | TimeoutException e) {
// can't ever happen
}
return p;
}
/**
* <p>Starts a process from its builder.</p>
* <span>The default redirects of STDOUT and STDERR are started</span>
* <p>
* It is possible to wait for the process to get to a warmed-up state
* via {@linkplain Predicate} condition on the STDOUT
* </p>
* @param name The process name
* @param processBuilder The process builder
* @param linePredicate The {@linkplain Predicate} to use on the STDOUT
* Used to determine the moment the target app is
* properly warmed-up.
* It can be null - in that case the warmup is skipped.
* @param timeout The timeout for the warmup waiting
* @param unit The timeout {@linkplain TimeUnit}
* @return Returns the initialized {@linkplain Process}
* @throws IOException
* @throws InterruptedException
* @throws TimeoutException
*/
public static Process startProcess(String name,
ProcessBuilder processBuilder,
final Predicate<String> linePredicate,
long timeout,
TimeUnit unit)
throws IOException, InterruptedException, TimeoutException {
Process p = processBuilder.start();
StreamPumper stdout = new StreamPumper(p.getInputStream());
StreamPumper stderr = new StreamPumper(p.getErrorStream());
stdout.addPump(new LineForwarder(name, System.out));
stderr.addPump(new LineForwarder(name, System.err));
final Phaser phs = new Phaser(1);
if (linePredicate != null) {
stdout.addPump(new StreamPumper.LinePump() {
@Override
protected void processLine(String line) {
if (linePredicate.test(line)) {
if (phs.getRegisteredParties() > 0) {
phs.arriveAndDeregister();
}
}
}
});
}
Future<Void> stdoutTask = stdout.process();
Future<Void> stderrTask = stderr.process();
try {
if (timeout > -1) {
phs.awaitAdvanceInterruptibly(0, timeout, unit);
}
} catch (TimeoutException | InterruptedException e) {
stdoutTask.cancel(true);
stderrTask.cancel(true);
throw e;
}
return p;
}
/**
* Pumps stdout and stderr from running the process into a String.
*
* @param processHandler
* @param processBuilder
* ProcessHandler to run.
* @return Output from process.
* @throws IOException
......@@ -69,22 +172,19 @@ public final class ProcessTools {
stdoutBuffer);
StreamPumper errPumper = new StreamPumper(process.getErrorStream(),
stderrBuffer);
Thread outPumperThread = new Thread(outPumper);
Thread errPumperThread = new Thread(errPumper);
outPumperThread.setDaemon(true);
errPumperThread.setDaemon(true);
outPumperThread.start();
errPumperThread.start();
Future<Void> outTask = outPumper.process();
Future<Void> errTask = errPumper.process();
try {
process.waitFor();
outPumperThread.join();
errPumperThread.join();
outTask.get();
errTask.get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return null;
} catch (ExecutionException e) {
throw new IOException(e);
}
return new OutputBuffer(stdoutBuffer.toString(),
......
......@@ -23,16 +23,65 @@
package jdk.testlibrary;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicBoolean;
public final class StreamPumper implements Runnable {
private static final int BUF_SIZE = 256;
private final OutputStream out;
/**
* Pump will be called by the StreamPumper to process the incoming data
*/
abstract public static class Pump {
abstract void register(StreamPumper d);
}
/**
* OutputStream -> Pump adapter
*/
final public static class StreamPump extends Pump {
private final OutputStream out;
public StreamPump(OutputStream out) {
this.out = out;
}
@Override
void register(StreamPumper sp) {
sp.addOutputStream(out);
}
}
/**
* Used to process the incoming data line-by-line
*/
abstract public static class LinePump extends Pump {
@Override
final void register(StreamPumper sp) {
sp.addLineProcessor(this);
}
abstract protected void processLine(String line);
}
private final InputStream in;
private final Set<OutputStream> outStreams = new HashSet<>();
private final Set<LinePump> linePumps = new HashSet<>();
private final AtomicBoolean processing = new AtomicBoolean(false);
private final FutureTask<Void> processingTask = new FutureTask(this, null);
public StreamPumper(InputStream in) {
this.in = in;
}
/**
* Create a StreamPumper that reads from in and writes to out.
......@@ -43,8 +92,8 @@ public final class StreamPumper implements Runnable {
* The stream to write to.
*/
public StreamPumper(InputStream in, OutputStream out) {
this.in = in;
this.out = out;
this(in);
this.addOutputStream(out);
}
/**
......@@ -54,25 +103,97 @@ public final class StreamPumper implements Runnable {
*/
@Override
public void run() {
int length;
InputStream localIn = in;
OutputStream localOut = out;
byte[] buffer = new byte[BUF_SIZE];
try {
while ((length = localIn.read(buffer)) > 0 && !Thread.interrupted()) {
localOut.write(buffer, 0, length);
try (BufferedInputStream is = new BufferedInputStream(in)) {
ByteArrayOutputStream lineBos = new ByteArrayOutputStream();
byte[] buf = new byte[BUF_SIZE];
int len = 0;
int linelen = 0;
while ((len = is.read(buf)) > 0 && !Thread.interrupted()) {
for(OutputStream out : outStreams) {
out.write(buf, 0, len);
}
if (!linePumps.isEmpty()) {
int i = 0;
int lastcrlf = -1;
while (i < len) {
if (buf[i] == '\n' || buf[i] == '\r') {
int bufLinelen = i - lastcrlf - 1;
if (bufLinelen > 0) {
lineBos.write(buf, lastcrlf + 1, bufLinelen);
}
linelen += bufLinelen;
if (linelen > 0) {
lineBos.flush();
final String line = lineBos.toString();
linePumps.stream().forEach((lp) -> {
lp.processLine(line);
});
lineBos.reset();
linelen = 0;
}
lastcrlf = i;
}
i++;
}
if (lastcrlf == -1) {
lineBos.write(buf, 0, len);
linelen += len;
} else if (lastcrlf < len - 1) {
lineBos.write(buf, lastcrlf + 1, len - lastcrlf - 1);
linelen += len - lastcrlf - 1;
}
}
}
} catch (IOException e) {
// Just abort if something like this happens.
e.printStackTrace();
} finally {
for(OutputStream out : outStreams) {
try {
out.flush();
} catch (IOException e) {}
}
try {
localOut.flush();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {}
}
}
final void addOutputStream(OutputStream out) {
outStreams.add(out);
}
final void addLineProcessor(LinePump lp) {
linePumps.add(lp);
}
final public StreamPumper addPump(Pump ... pump) {
if (processing.get()) {
throw new IllegalStateException("Can not modify pumper while " +
"processing is in progress");
}
for(Pump p : pump) {
p.register(this);
}
return this;
}
final public Future<Void> process() {
if (!processing.compareAndSet(false, true)) {
throw new IllegalStateException("Can not re-run the processing");
}
Thread t = new Thread(new Runnable() {
@Override
public void run() {
processingTask.run();
}
});
t.setDaemon(true);
t.start();
return processingTask;
}
}
/*
* 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.File;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import jdk.testlibrary.JdkFinder;
import jdk.testlibrary.ProcessTools;
/**
* @test
* @bug 6434402 8004926
* @library ../../../../lib/testlibrary
* @build TestManager TestApplication CustomLauncherTest
* @run main CustomLauncherTest
* @author Jaroslav Bachorik
*/
public class CustomLauncherTest {
private static final String TEST_CLASSES = System.getProperty("test.classes");
private static final String TEST_JDK = System.getProperty("test.jdk");
private static final String TEST_SRC = System.getProperty("test.src");
private static final String OSNAME = System.getProperty("os.name");
private static final String ARCH;
private static final String LIBARCH;
static {
// magic with os.arch
String osarch = System.getProperty("os.arch");
switch (osarch) {
case "i386":
case "i486":
case "i586":
case "i686":
case "i786":
case "i886":
case "i986": {
ARCH = "i586";
break;
}
case "x86_64":
case "amd64": {
ARCH = "amd64";
break;
}
default: {
ARCH = osarch;
}
}
LIBARCH = ARCH.equals("i586") ? "i386" : ARCH;
}
public static void main(String[] args) throws Exception {
if (TEST_CLASSES == null || TEST_CLASSES.isEmpty()) {
System.out.println("Test is designed to be run from jtreg only");
return;
}
String PLATFORM = "";
switch (OSNAME.toLowerCase()) {
case "linux": {
PLATFORM = "linux";
break;
}
case "sunos": {
PLATFORM = "solaris";
break;
}
default: {
System.out.println("Test not designed to run on this operating " +
"system (" + OSNAME + "), skipping...");
return;
}
}
String LAUNCHER = TEST_SRC + File.separator + PLATFORM + "-" + ARCH +
File.separator + "launcher";
final FileSystem FS = FileSystems.getDefault();
final boolean hasLauncher = Files.isExecutable(FS.getPath(LAUNCHER));
if (!hasLauncher) {
System.out.println("Launcher [" + LAUNCHER + "] does not exist. Skipping the test.");
return;
}
Path libjvmPath = findLibjvm(FS);
if (libjvmPath == null) {
throw new Error("Unable to locate 'libjvm.so' in " + TEST_JDK);
}
Process serverPrc = null, clientPrc = null;
try {
System.out.println("Starting custom launcher:");
System.out.println("=========================");
System.out.println(" launcher : " + LAUNCHER);
System.out.println(" libjvm : " + libjvmPath.toString());
System.out.println(" classpath : " + TEST_CLASSES);
ProcessBuilder server = new ProcessBuilder(LAUNCHER, libjvmPath.toString(), TEST_CLASSES, "TestApplication");
final AtomicReference<String> port = new AtomicReference<>();
final AtomicReference<String> pid = new AtomicReference<>();
serverPrc = ProcessTools.startProcess(
"Launcher",
server,
(String line) -> {
if (line.startsWith("port:")) {
port.set(line.split("\\:")[1]);
} else if (line.startsWith("pid:")) {
pid.set(line.split("\\:")[1]);
} else if (line.startsWith("waiting")) {
return true;
}
return false;
},
5,
TimeUnit.SECONDS
);
System.out.println("Attaching test manager:");
System.out.println("=========================");
System.out.println(" PID : " + pid.get());
System.out.println(" shutdown port : " + port.get());
ProcessBuilder client = ProcessTools.createJavaProcessBuilder(
"-cp",
TEST_CLASSES +
File.pathSeparator +
TEST_JDK +
File.separator +
"lib" +
File.separator +
"tools.jar",
"TestManager",
pid.get(),
port.get(),
"true"
);
clientPrc = ProcessTools.startProcess(
"TestManager",
client,
(String line) -> line.startsWith("Starting TestManager for PID"),
10,
TimeUnit.SECONDS
);
int clientExitCode = clientPrc.waitFor();
int serverExitCode = serverPrc.waitFor();
if (clientExitCode != 0 || serverExitCode != 0) {
throw new Error("Test failed");
}
} finally {
if (clientPrc != null) {
clientPrc.destroy();
clientPrc.waitFor();
}
if (serverPrc != null) {
serverPrc.destroy();
serverPrc.waitFor();
}
}
}
private static Path findLibjvm(FileSystem FS) {
Path libjvmPath = findLibjvm(FS.getPath(TEST_JDK, "jre", "lib", LIBARCH));
if (libjvmPath == null) {
libjvmPath = findLibjvm(FS.getPath(TEST_JDK, "lib", LIBARCH));
}
return libjvmPath;
}
private static Path findLibjvm(Path libPath) {
// ARCH/libjvm.so -> ARCH/server/libjvm.so -> ARCH/client/libjvm.so
Path libjvmPath = libPath.resolve("libjvm.so");
if (isFileOk(libjvmPath)) {
return libjvmPath;
}
libjvmPath = libPath.resolve("server/libjvm.so");
if (isFileOk(libjvmPath)) {
return libjvmPath;
}
libjvmPath = libPath.resolve("client/libjvm.so");
if (isFileOk(libPath)) {
return libjvmPath;
}
return null;
}
private static boolean isFileOk(Path path) {
return Files.isRegularFile(path) && Files.isReadable(path);
}
}
#!/bin/sh
#
# Copyright (c) 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.
#
# @test
# @bug 6434402
# @summary Start an application using a custom launcher and check that
# a management tool can connect.
#
# @build TestManager TestApplication
# @run shell CustomLauncherTest.sh
#
# Check we are run from jtreg
#
if [ -z "${TESTCLASSES}" ]; then
echo "Test is designed to be run from jtreg only"
exit 0
fi
#
# For now this test passes silently on Windows - this means the test only
# has to locate libjvm.so. Also $! is not reliable on some releases of MKS.
#{
OS=`uname -s`
if [ "$OS" != "Linux" -a "$OS" != "SunOS" ]; then
echo "Test not designed to run on this operating system, skipping..."
exit 0
fi
#
# Locate the custom launcher for this platform
#
PLATFORM=unknown
ARCH=unknown
if [ "$OS" = "SunOS" ]; then
PLATFORM=solaris
case "`uname -p`" in
i[3-9]86)
ARCH=i586
;;
sparc)
ARCH=sparc
;;
esac
else
PLATFORM=linux
case "`uname -m`" in
i[3-6]86)
ARCH=i586
;;
x86_64)
ARCH=amd64
;;
esac
fi
#
# On x86 the native libraries are in lib/i386 for
# compatability reasons
#
if [ "$ARCH" = "i586" ]; then
LIBARCH="i386"
else
LIBARCH=$ARCH
fi
#
# Check that a custom launcher exists for this platform
#
LAUNCHER="${TESTSRC}/${PLATFORM}-${ARCH}/launcher"
if [ ! -x "${LAUNCHER}" ]; then
echo "${LAUNCHER} not found"
exit 0
fi
#
# Locate the libjvm.so library
#
JVMLIB="${TESTJAVA}/jre/lib/${LIBARCH}/client/libjvm.so"
if [ ! -f "${JVMLIB}" ]; then
JVMLIB="${TESTJAVA}/jre/lib/${LIBARCH}/server/libjvm.so"
if [ ! -f "${JVMLIB}" ]; then
JVMLIB="${TESTJAVA}/lib/${LIBARCH}/client/libjvm.so"
if [ ! -f "${JVMLIB}" ]; then
JVMLIB="${TESTJAVA}/lib/${LIBARCH}/serevr/libjvm.so"
if [ ! -f "${JVMLIB}" ]; then
echo "Unable to locate libjvm.so in ${TESTJAVA}"
exit 1
fi
fi
fi
fi
#
# Start the VM
#
outputfile=${TESTCLASSES}/Test.out
rm -f ${outputfile}
echo ''
echo "Starting custom launcher..."
echo " launcher: ${LAUNCHER}"
echo " libjvm: ${JVMLIB}"
echo "classpath: ${TESTCLASSES}"
${LAUNCHER} ${JVMLIB} ${TESTCLASSES} TestApplication > ${outputfile} &
pid=$!
# Wait for managed VM to startup (although this looks like a potentially
# infinate loop, the framework will eventually kill it)
echo "Waiting for TestAppication to test..."
attempts=0
while true; do
sleep 1
port=`tail -1 ${outputfile}`
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
# Start the manager - this should connect to VM
${TESTJAVA}/bin/java ${TESTVMOPTS} -classpath ${TESTCLASSES}:${TESTJAVA}/lib/tools.jar \
TestManager $pid $port true
if [ $? != 0 ]; then
echo "Test failed"
exit 1
fi
exit 0
/*
* 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.File;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
/**
* @test
* @library ../../../../lib/testlibrary
* @bug 5016507 6173612 6319776 6342019 6484550 8004926
* @summary Start a managed VM and test that a management tool can connect
* without connection or username/password details.
* TestManager will attempt a connection to the address obtained from
* both agent properties and jvmstat buffer.
* @build TestManager TestApplication
* @run main/timeout=300 LocalManagementTest
*/
import jdk.testlibrary.ProcessTools;
public class LocalManagementTest {
private static final String TEST_CLASSES = System.getProperty("test.classes");
private static final String TEST_JDK = System.getProperty("test.jdk");
public static void main(String[] args) throws Exception {
int failures = 0;
for(Method m : LocalManagementTest.class.getDeclaredMethods()) {
if (Modifier.isStatic(m.getModifiers()) &&
m.getName().startsWith("test")) {
m.setAccessible(true);
try {
System.out.println(m.getName());
System.out.println("==========");
Boolean rslt = (Boolean)m.invoke(null);
if (!rslt) {
System.err.println(m.getName() + " failed");
failures++;
}
} catch (Exception e) {
e.printStackTrace();
failures++;
}
}
}
if (failures > 0) {
throw new Error("Test failed");
}
}
private static boolean test1() throws Exception {
return doTest("-Dcom.sun.management.jmxremote");
}
private static boolean test2() throws Exception {
Path agentPath = findAgent();
if (agentPath != null) {
String agent = agentPath.toString();
return doTest("-javaagent:" + agent);
} else {
return false;
}
}
/**
* no args (blank) - manager should attach and start agent
*/
private static boolean test3() throws Exception {
return doTest(null);
}
/**
* sanity check arguments to management-agent.jar
*/
private static boolean test4() throws Exception {
Path agentPath = findAgent();
if (agentPath != null) {
ProcessBuilder builder = ProcessTools.createJavaProcessBuilder(
"-javaagent:" + agentPath.toString() +
"=com.sun.management.jmxremote.port=7775," +
"com.sun.management.jmxremote.authenticate=false," +
"com.sun.management.jmxremote.ssl=false",
"TestApplication",
"-exit"
);
Process prc = null;
try {
prc = ProcessTools.startProcess(
"TestApplication",
builder
);
int exitCode = prc.waitFor();
return exitCode == 0;
} finally {
if (prc != null) {
prc.destroy();
prc.waitFor();
}
}
}
return false;
}
/**
* use DNS-only name service
*/
private static boolean test5() throws Exception {
return doTest("-Dsun.net.spi.namservice.provider.1=\"dns,sun\"");
}
private static Path findAgent() {
FileSystem FS = FileSystems.getDefault();
Path agentPath = FS.getPath(
TEST_JDK, "jre", "lib", "management-agent.jar"
);
if (!isFileOk(agentPath)) {
agentPath = FS.getPath(
TEST_JDK, "lib", "management-agent.jar"
);
}
if (!isFileOk(agentPath)) {
System.err.println("Can not locate management-agent.jar");
return null;
}
return agentPath;
}
private static boolean isFileOk(Path path) {
return Files.isRegularFile(path) && Files.isReadable(path);
}
private static boolean doTest(String arg) throws Exception {
List<String> args = new ArrayList<>();
if (arg != null) {
args.add(arg);
}
args.add("TestApplication");
ProcessBuilder server = ProcessTools.createJavaProcessBuilder(
args.toArray(new String[args.size()])
);
Process serverPrc = null, clientPrc = null;
try {
final AtomicReference<String> port = new AtomicReference<>();
final AtomicReference<String> pid = new AtomicReference<>();
serverPrc = ProcessTools.startProcess(
"TestApplication",
server,
(String line) -> {
if (line.startsWith("port:")) {
port.set(line.split("\\:")[1]);
} else if (line.startsWith("pid:")) {
pid.set(line.split("\\:")[1]);
} else if (line.startsWith("waiting")) {
return true;
}
return false;
},
5,
TimeUnit.SECONDS
);
System.out.println("Attaching test manager:");
System.out.println("=========================");
System.out.println(" PID : " + pid.get());
System.out.println(" shutdown port : " + port.get());
ProcessBuilder client = ProcessTools.createJavaProcessBuilder(
"-cp",
TEST_CLASSES +
File.pathSeparator +
TEST_JDK +
File.separator +
"lib" +
File.separator +
"tools.jar",
"TestManager",
pid.get(),
port.get(),
"true"
);
clientPrc = ProcessTools.startProcess(
"TestManager",
client,
(String line) -> line.startsWith("Starting TestManager for PID"),
10,
TimeUnit.SECONDS
);
int clientExitCode = clientPrc.waitFor();
int serverExitCode = serverPrc.waitFor();
return clientExitCode == 0 && serverExitCode == 0;
} finally {
if (clientPrc != null) {
System.out.println("Stopping process " + clientPrc);
clientPrc.destroy();
clientPrc.waitFor();
}
if (serverPrc != null) {
System.out.println("Stopping process " + serverPrc);
serverPrc.destroy();
serverPrc.waitFor();
}
}
}
}
\ No newline at end of file
#!/bin/sh
#
# Copyright (c) 2004, 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.
#
# @test
# @bug 5016507 6173612 6319776 6342019 6484550
# @summary Start a managed VM and test that a management tool can connect
# without connection or username/password details.
# TestManager will attempt a connection to the address obtained from
# both agent properties and jvmstat buffer.
#
# @build TestManager TestApplication
# @run shell/timeout=300 LocalManagementTest.sh
doTest()
{
echo ''
outputfile=${TESTCLASSES}/Test.out
rm -f ${outputfile}
# Start VM with given options
echo "+ $JAVA ${TESTVMOPTS} $1 Test"
$JAVA ${TESTVMOPTS} $1 TestApplication > ${outputfile}&
pid=$!
# Wait for managed VM to startup
echo "Waiting for VM to startup..."
attempts=0
while true; do
sleep 1
port=`tail -1 ${outputfile}`
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
# Start the manager - this should connect to VM
sh -xc "$JAVA ${TESTVMOPTS} -classpath ${TESTCLASSES}:${TESTJAVA}/lib/tools.jar \
TestManager $pid $port" 2>&1
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
}
# Check we are run from jtreg
if [ -z "${TESTCLASSES}" ]; then
echo "Test is designed to be run from jtreg only"
exit 0
fi
# For now this test passes silently on Windows - there are 2 reasons
# to skip it :-
#
# 1. No jstat instrumentation buffers if FAT32 so need
# -XX:+PerfBypassFileSystemCheck
# 2. $! is used to get the pid of the created process but it's not
# reliable on older versions of MKS. Also negative pids are returned
# on Windows 98.
os=`uname -s`
if [ "$os" != "Linux" -a "$os" != "SunOS" ]; then
echo "Test not designed to run on this operating system, skipping..."
exit 0
fi
JAVA=${TESTJAVA}/bin/java
CLASSPATH=${TESTCLASSES}
export CLASSPATH
failures=0
# Test 1
doTest "-Dcom.sun.management.jmxremote"
# Test 2
AGENT="${TESTJAVA}/jre/lib/management-agent.jar"
if [ ! -f ${AGENT} ]; then
AGENT="${TESTJAVA}/lib/management-agent.jar"
fi
doTest "-javaagent:${AGENT}"
# Test 3 - no args (blank) - manager should attach and start agent
doTest " "
# Test 4 - sanity check arguments to management-agent.jar
echo ' '
sh -xc "${JAVA} ${TESTVMOPTS} -javaagent:${AGENT}=com.sun.management.jmxremote.port=7775,\
com.sun.management.jmxremote.authenticate=false,com.sun.management.jmxremote.ssl=false \
TestApplication -exit" 2>&1
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
# Test 5 - use DNS-only name service
doTest "-Dsun.net.spi.namservice.provider.1=\"dns,sun\""
#
# Results
#
echo ''
if [ $failures -gt 0 ];
then echo "$failures test(s) failed";
else echo "All test(s) passed"; 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
......@@ -24,14 +24,18 @@
/*
*
*
* A test "application" used by unit test LocalManagementTest.sh. This
* application binds to some random port, prints the port number to
* standard output, waits for somebody to connect, and then shuts down.
* A test "application" used by unit tests -
* LocalManagementTest.java, CustomLauncherTest.java.
* This application binds to some random port, prints its pid and
* the port number to standard output, waits for somebody to connect,
* and then shuts down.
*/
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import jdk.testlibrary.ProcessTools;
public class TestApplication {
public static void main(String[] args) throws IOException {
// Some tests require the application to exit immediately
......@@ -43,8 +47,17 @@ public class TestApplication {
ServerSocket ss = new ServerSocket(0);
int port = ss.getLocalPort();
// signal test that we are started - do not remove this line!!
System.out.println(port);
int pid = -1;
try {
pid = ProcessTools.getProcessId();
} catch (Exception e) {
e.printStackTrace();
}
// signal test that we are started - do not remove these lines!!
System.out.println("port:" + port);
System.out.println("pid:" + pid);
System.out.println("waiting for the manager ...");
System.out.flush();
// wait for manager to connect
......
/*
* Copyright (c) 2005, 2006, 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
......@@ -24,7 +24,8 @@
/*
*
*
* A test "management tool" used by unit test LocalManagementTest.sh.
* A test "management tool" used by unit tests -
* LocalManagementTest.java, CustomLauncherTest.java
*
* Usage: java TestManager <pid> <port>
*
......@@ -32,8 +33,6 @@
* TCP port is used to shutdown the application.
*/
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerInvocationHandler;
import javax.management.ObjectName;
import javax.management.remote.JMXServiceURL;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnector;
......@@ -43,7 +42,6 @@ import java.net.Socket;
import java.net.InetSocketAddress;
import java.io.File;
import java.io.IOException;
import java.util.Properties;
// Sun specific
import com.sun.tools.attach.VirtualMachine;
......@@ -111,6 +109,8 @@ public class TestManager {
"com.sun.management.jmxremote.localConnectorAddress";
public static void main(String[] args) throws Exception {
String pid = args[0]; // pid as a string
System.out.println("Starting TestManager for PID = " + pid);
System.out.flush();
VirtualMachine vm = VirtualMachine.attach(pid);
String agentPropLocalConnectorAddress = (String)
......@@ -140,7 +140,6 @@ public class TestManager {
System.out.println("Testing the connector address from jvmstat buffer");
connect(pid, jvmstatLocalConnectorAddress);
// Shutdown application
int port = Integer.parseInt(args[1]);
System.out.println("Shutdown process via TCP port: " + port);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册