< prev index next >
test/hotspot/jtreg/containers/docker/TestJcmdWithSideCar.java
Print this page
*** 35,44 ****
--- 35,45 ----
* java.management
* jdk.jartool/sun.tools.jar
* @build EventGeneratorLoop
* @run driver TestJcmdWithSideCar
*/
+ import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
*** 53,62 ****
--- 54,64 ----
public class TestJcmdWithSideCar {
private static final String IMAGE_NAME = Common.imageName("jfr-jcmd");
private static final int TIME_TO_RUN_MAIN_PROCESS = (int) (30 * Utils.TIMEOUT_FACTOR); // seconds
private static final String MAIN_CONTAINER_NAME = "test-container-main";
+ private static final String MAIN_METHOD_STARTED_SIGNAL_FILE = "mainMethodStarted.signal";
public static void main(String[] args) throws Exception {
if (!DockerTestUtils.canTestDocker()) {
return;
}
*** 68,83 ****
// using a sidecar container.
DockerThread t = startMainContainer();
waitForMainContainerToStart(500, 10);
t.checkForErrors();
! OutputAnalyzer jcmdOut = testCase01();
! long mainProcPid = findProcess(jcmdOut, "EventGeneratorLoop");
! t.assertIsAlive();
! testCase02(mainProcPid);
// JCMD does not work in sidecar configuration, except for "jcmd -l".
// Including this test case to assist in reproduction of the problem.
// t.assertIsAlive();
// testCase03(mainProcPid);
--- 70,88 ----
// using a sidecar container.
DockerThread t = startMainContainer();
waitForMainContainerToStart(500, 10);
t.checkForErrors();
+ waitForContainerMainMethod();
! long mainProcPid = testCase01();
! // Excluding the test case below until JDK-8228850 is fixed
! // JDK-8228850: jhsdb jinfo fails with ClassCastException:
! // s.j.h.oops.TypeArray cannot be cast to s.j.h.oops.Instance
! // t.assertIsAlive();
! // testCase02(mainProcPid);
// JCMD does not work in sidecar configuration, except for "jcmd -l".
// Including this test case to assist in reproduction of the problem.
// t.assertIsAlive();
// testCase03(mainProcPid);
*** 88,103 ****
DockerTestUtils.removeDockerImage(IMAGE_NAME);
}
}
! // Run "jcmd -l" in a sidecar container and find a process that runs EventGeneratorLoop
! private static OutputAnalyzer testCase01() throws Exception {
! return runSideCar(MAIN_CONTAINER_NAME, "/jdk/bin/jcmd", "-l")
.shouldHaveExitValue(0)
! .shouldContain("sun.tools.jcmd.JCmd")
! .shouldContain("EventGeneratorLoop");
}
// run jhsdb jinfo <PID> (jhsdb uses PTRACE)
private static void testCase02(long pid) throws Exception {
runSideCar(MAIN_CONTAINER_NAME, "/jdk/bin/jhsdb", "jinfo", "--pid", "" + pid)
--- 93,113 ----
DockerTestUtils.removeDockerImage(IMAGE_NAME);
}
}
! // Run "jcmd -l" in a sidecar container, find a target process.
! private static long testCase01() throws Exception {
! OutputAnalyzer out = runSideCar(MAIN_CONTAINER_NAME, "/jdk/bin/jcmd", "-l")
.shouldHaveExitValue(0)
! .shouldContain("sun.tools.jcmd.JCmd");
! long pid = findProcess(out, "EventGeneratorLoop");
! if (pid == -1) {
! throw new RuntimeException("Could not find specified process");
! }
!
! return pid;
}
// run jhsdb jinfo <PID> (jhsdb uses PTRACE)
private static void testCase02(long pid) throws Exception {
runSideCar(MAIN_CONTAINER_NAME, "/jdk/bin/jhsdb", "jinfo", "--pid", "" + pid)
*** 120,144 ****
private static DockerThread startMainContainer() throws Exception {
// start "main" container (the observee)
DockerRunOptions opts = commonDockerOpts("EventGeneratorLoop");
opts.addDockerOpts("--cap-add=SYS_PTRACE")
.addDockerOpts("--name", MAIN_CONTAINER_NAME)
! .addDockerOpts("-v", "/tmp")
.addJavaOpts("-XX:+UsePerfData")
! .addClassOptions("" + TIME_TO_RUN_MAIN_PROCESS);
DockerThread t = new DockerThread(opts);
t.start();
return t;
}
private static void waitForMainContainerToStart(int delayMillis, int count) throws Exception {
boolean started = false;
for(int i=0; i < count; i++) {
! try {
! Thread.sleep(delayMillis);
! } catch (InterruptedException e) {}
if (isMainContainerRunning()) {
started = true;
break;
}
}
--- 130,154 ----
private static DockerThread startMainContainer() throws Exception {
// start "main" container (the observee)
DockerRunOptions opts = commonDockerOpts("EventGeneratorLoop");
opts.addDockerOpts("--cap-add=SYS_PTRACE")
.addDockerOpts("--name", MAIN_CONTAINER_NAME)
! .addDockerOpts("--volume", "/tmp")
! .addDockerOpts("--volume", Paths.get(".").toAbsolutePath() + ":/workdir/")
.addJavaOpts("-XX:+UsePerfData")
! .addClassOptions("" + TIME_TO_RUN_MAIN_PROCESS)
! .addClassOptions("/workdir/" + MAIN_METHOD_STARTED_SIGNAL_FILE);
DockerThread t = new DockerThread(opts);
t.start();
return t;
}
private static void waitForMainContainerToStart(int delayMillis, int count) throws Exception {
boolean started = false;
for(int i=0; i < count; i++) {
! sleep(delayMillis);
if (isMainContainerRunning()) {
started = true;
break;
}
}
*** 174,190 ****
cmd.addAll(Arrays.asList(command));
cmd.addAll(Arrays.asList(args));
return DockerTestUtils.execute(cmd);
}
private static long findProcess(OutputAnalyzer out, String name) throws Exception {
List<String> l = out.asLines()
.stream()
.filter(s -> s.contains(name))
.collect(Collectors.toList());
if (l.isEmpty()) {
! throw new RuntimeException("Could not find matching process");
}
String psInfo = l.get(0);
System.out.println("findProcess(): psInfo: " + psInfo);
String pid = psInfo.substring(0, psInfo.indexOf(' '));
System.out.println("findProcess(): pid: " + pid);
--- 184,201 ----
cmd.addAll(Arrays.asList(command));
cmd.addAll(Arrays.asList(args));
return DockerTestUtils.execute(cmd);
}
+ // Returns PID if a matching process, or -1 if not found.
private static long findProcess(OutputAnalyzer out, String name) throws Exception {
List<String> l = out.asLines()
.stream()
.filter(s -> s.contains(name))
.collect(Collectors.toList());
if (l.isEmpty()) {
! return -1;
}
String psInfo = l.get(0);
System.out.println("findProcess(): psInfo: " + psInfo);
String pid = psInfo.substring(0, psInfo.indexOf(' '));
System.out.println("findProcess(): pid: " + pid);
*** 195,204 ****
--- 206,246 ----
return new DockerRunOptions(IMAGE_NAME, "/jdk/bin/java", className)
.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/")
.addJavaOpts("-cp", "/test-classes/");
}
+ // Wait for the "main()" method in the container to start.
+ private static void waitForContainerMainMethod() {
+ waitForSignalFile(MAIN_METHOD_STARTED_SIGNAL_FILE, 10*1000, 500);
+ }
+
+ // Wait for a file in a specified location (aka signal file) to be created.
+ // fn - file name to wait for
+ // howLong - howLong (milliseconds)
+ // delay - delay between the attempts (milliseconds)
+ private static void waitForSignalFile(String fn, long howLong, long delay) {
+ long expiration = System.currentTimeMillis() + howLong;
+ File f = Paths.get(".", fn).toFile();
+
+ do {
+ if (f.exists()) {
+ return;
+ }
+ sleep(delay);
+ } while (System.currentTimeMillis() < expiration);
+
+ String msg = "Timed out while waiting for a signal file " + fn;
+ throw new RuntimeException(msg);
+ }
+
+ private static void sleep(long delay) {
+ try {
+ Thread.sleep(delay);
+ } catch (InterruptedException e) {
+ System.out.println("InterruptedException" + e.getMessage());
+ }
+ }
static class DockerThread extends Thread {
DockerRunOptions runOpts;
Exception exception;
< prev index next >