Skip to content

Commit da4b7a8

Browse files
slovdahlkevinjwalls
authored andcommitted
8341436: containers/docker/TestJcmdWithSideCar.java takes needlessly long to run
Reviewed-by: kevinw, lmesnik
1 parent 333a997 commit da4b7a8

File tree

3 files changed

+45
-39
lines changed

3 files changed

+45
-39
lines changed

test/hotspot/jtreg/containers/docker/EventGeneratorLoop.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import jdk.jfr.Description;
2525
import jdk.jfr.Label;
2626

27+
import java.util.concurrent.TimeUnit;
28+
2729

2830
// This class generates simple event in a loop for a specified time.
2931
public class EventGeneratorLoop {
@@ -44,16 +46,21 @@ public static void main(String[] args) throws Exception {
4446
throw new IllegalArgumentException("Expecting one argument: time to run (seconds)");
4547
}
4648
int howLong = Integer.parseInt(args[0]);
49+
long endTime = System.nanoTime() + TimeUnit.SECONDS.toNanos(howLong);
4750

4851
System.out.println(MAIN_METHOD_STARTED + ", argument is " + howLong);
4952

50-
for (int i=0; i < howLong; i++) {
53+
int count = 0;
54+
while (System.nanoTime() < endTime) {
5155
SimpleEvent ev = new SimpleEvent();
5256
ev.msg = "Hello";
53-
ev.count = i;
57+
ev.count = count++;
5458
ev.commit();
5559

56-
try { Thread.sleep(1000); } catch (InterruptedException e) {}
60+
try {
61+
Thread.sleep(1000);
62+
} catch (InterruptedException ignore) {
63+
}
5764
System.out.print(".");
5865
}
5966

test/hotspot/jtreg/containers/docker/TestJcmdWithSideCar.java

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@
4848
import java.util.EnumSet;
4949
import java.util.List;
5050
import java.util.Optional;
51+
import java.util.Random;
5152
import java.util.concurrent.TimeUnit;
5253
import java.util.function.Consumer;
5354
import java.util.regex.Pattern;
54-
import java.util.stream.Collectors;
5555

5656
import jdk.test.lib.Container;
5757
import jdk.test.lib.Platform;
@@ -67,7 +67,6 @@ public class TestJcmdWithSideCar {
6767
private static final String IMAGE_NAME = Common.imageName("jfr-jcmd");
6868
private static final int TIME_TO_RUN_MAIN_PROCESS = (int) (30 * Utils.TIMEOUT_FACTOR); // seconds
6969
private static final long TIME_TO_WAIT_FOR_MAIN_METHOD_START = 50 * 1000; // milliseconds
70-
private static final String MAIN_CONTAINER_NAME = "test-container-main";
7170

7271
private static final String UID = "uid";
7372
private static final String GID = "gid";
@@ -115,19 +114,19 @@ public static void main(String[] args) throws Exception {
115114
// Elevated attach via proc/root not yet supported.
116115
continue;
117116
}
118-
long mainProcPid = testCase01(attachStrategy, elevated);
117+
long mainProcPid = testCase01(mainContainer, attachStrategy, elevated);
119118

120119
// Excluding the test case below until JDK-8228850 is fixed
121120
// JDK-8228850: jhsdb jinfo fails with ClassCastException:
122121
// s.j.h.oops.TypeArray cannot be cast to s.j.h.oops.Instance
123122
// mainContainer.assertIsAlive();
124-
// testCase02(mainProcPid, attachStrategy, elevated);
123+
// testCase02(mainContainer, mainProcPid, attachStrategy, elevated);
125124

126125
mainContainer.assertIsAlive();
127-
testCase03(mainProcPid, attachStrategy, elevated);
126+
testCase03(mainContainer, mainProcPid, attachStrategy, elevated);
128127
}
129128

130-
mainContainer.waitForAndCheck(TIME_TO_RUN_MAIN_PROCESS * 1000);
129+
mainContainer.stop();
131130
}
132131
} finally {
133132
DockerTestUtils.removeDockerImage(IMAGE_NAME);
@@ -136,8 +135,8 @@ public static void main(String[] args) throws Exception {
136135

137136

138137
// Run "jcmd -l" in a sidecar container, find a target process.
139-
private static long testCase01(AttachStrategy attachStrategy, boolean elevated) throws Exception {
140-
OutputAnalyzer out = runSideCar(MAIN_CONTAINER_NAME, attachStrategy, elevated, "/jdk/bin/jcmd", "-l")
138+
private static long testCase01(MainContainer mainContainer, AttachStrategy attachStrategy, boolean elevated) throws Exception {
139+
OutputAnalyzer out = runSideCar(mainContainer, attachStrategy, elevated, "/jdk/bin/jcmd", "-l")
141140
.shouldHaveExitValue(0)
142141
.shouldContain("sun.tools.jcmd.JCmd");
143142
long pid = findProcess(out, "EventGeneratorLoop");
@@ -149,20 +148,20 @@ private static long testCase01(AttachStrategy attachStrategy, boolean elevated)
149148
}
150149

151150
// run jhsdb jinfo <PID> (jhsdb uses PTRACE)
152-
private static void testCase02(long pid, AttachStrategy attachStrategy, boolean elevated) throws Exception {
153-
runSideCar(MAIN_CONTAINER_NAME, attachStrategy, elevated, "/jdk/bin/jhsdb", "jinfo", "--pid", "" + pid)
151+
private static void testCase02(MainContainer mainContainer, long pid, AttachStrategy attachStrategy, boolean elevated) throws Exception {
152+
runSideCar(mainContainer, attachStrategy, elevated, "/jdk/bin/jhsdb", "jinfo", "--pid", "" + pid)
154153
.shouldHaveExitValue(0)
155154
.shouldContain("Java System Properties")
156155
.shouldContain("VM Flags");
157156
}
158157

159158
// test jcmd with some commands (help, start JFR recording)
160159
// JCMD will use signal mechanism and Unix Socket
161-
private static void testCase03(long pid, AttachStrategy attachStrategy, boolean elevated) throws Exception {
162-
runSideCar(MAIN_CONTAINER_NAME, attachStrategy, elevated, "/jdk/bin/jcmd", "" + pid, "help")
160+
private static void testCase03(MainContainer mainContainer, long pid, AttachStrategy attachStrategy, boolean elevated) throws Exception {
161+
runSideCar(mainContainer, attachStrategy, elevated, "/jdk/bin/jcmd", "" + pid, "help")
163162
.shouldHaveExitValue(0)
164163
.shouldContain("VM.version");
165-
runSideCar(MAIN_CONTAINER_NAME, attachStrategy, elevated, "/jdk/bin/jcmd", "" + pid, "JFR.start")
164+
runSideCar(mainContainer, attachStrategy, elevated, "/jdk/bin/jcmd", "" + pid, "JFR.start")
166165
.shouldHaveExitValue(0)
167166
.shouldContain("Started recording");
168167
}
@@ -174,18 +173,18 @@ private static void testCase03(long pid, AttachStrategy attachStrategy, boolean
174173
// we have two options:
175174
// 1. mount /tmp from the main container using --volumes-from.
176175
// 2. access /tmp from the main container via /proc/<pid>/root/tmp.
177-
private static OutputAnalyzer runSideCar(String mainContainerName, AttachStrategy attachStrategy, boolean elevated, String whatToRun, String... args) throws Exception {
176+
private static OutputAnalyzer runSideCar(MainContainer mainContainer, AttachStrategy attachStrategy, boolean elevated, String whatToRun, String... args) throws Exception {
178177
System.out.println("Attach strategy " + attachStrategy);
179178

180179
List<String> initialCommands = List.of(
181180
Container.ENGINE_COMMAND, "run",
182181
"--tty=true", "--rm",
183182
"--cap-add=SYS_PTRACE", "--sig-proxy=true",
184-
"--pid=container:" + mainContainerName
183+
"--pid=container:" + mainContainer.name()
185184
);
186185

187186
List<String> attachStrategyCommands = switch (attachStrategy) {
188-
case TMP_MOUNTED_INTO_SIDECAR -> List.of("--volumes-from", mainContainerName);
187+
case TMP_MOUNTED_INTO_SIDECAR -> List.of("--volumes-from", mainContainer.name());
189188
case ACCESS_TMP_VIA_PROC_ROOT -> List.of();
190189
};
191190

@@ -209,11 +208,11 @@ private static long findProcess(OutputAnalyzer out, String name) throws Exceptio
209208
List<String> l = out.asLines()
210209
.stream()
211210
.filter(s -> s.contains(name))
212-
.collect(Collectors.toList());
211+
.toList();
213212
if (l.isEmpty()) {
214213
return -1;
215214
}
216-
String psInfo = l.get(0);
215+
String psInfo = l.getFirst();
217216
System.out.println("findProcess(): psInfo: " + psInfo);
218217
String pid = psInfo.substring(0, psInfo.indexOf(' '));
219218
System.out.println("findProcess(): pid: " + pid);
@@ -236,6 +235,10 @@ private static void sleep(long delay) {
236235

237236

238237
static class MainContainer {
238+
private static final String MAIN_CONTAINER_NAME_PREFIX = "test-container-main";
239+
private static final Random RANDOM = Utils.getRandomInstance();
240+
241+
String name;
239242
boolean mainMethodStarted;
240243
Process p;
241244

@@ -255,8 +258,11 @@ public Process start(final boolean elevated) throws Exception {
255258
opts.addDockerOpts(NET_BIND_SERVICE);
256259
}
257260

261+
name = MAIN_CONTAINER_NAME_PREFIX + "-elevated-" + elevated + "-" + RANDOM.nextInt();
262+
258263
opts.addDockerOpts("--cap-add=SYS_PTRACE")
259-
.addDockerOpts("--name", MAIN_CONTAINER_NAME)
264+
.addDockerOpts("--init")
265+
.addDockerOpts("--name", name)
260266
.addDockerOpts("--volume", "/tmp")
261267
.addDockerOpts("--volume", Paths.get(".").toAbsolutePath() + ":/workdir/")
262268
.addJavaOpts("-XX:+UsePerfData")
@@ -296,25 +302,18 @@ public void waitFor(long timeout) throws Exception {
296302
p.waitFor(timeout, TimeUnit.MILLISECONDS);
297303
}
298304

299-
public void waitForAndCheck(long timeout) throws Exception {
300-
int exitValue = -1;
301-
int retryCount = 3;
302-
303-
do {
304-
waitFor(timeout);
305-
try {
306-
exitValue = p.exitValue();
307-
} catch(IllegalThreadStateException ex) {
308-
System.out.println("IllegalThreadStateException occurred when calling exitValue()");
309-
retryCount--;
310-
}
311-
} while (exitValue == -1 && retryCount > 0);
312-
313-
if (exitValue != 0) {
314-
throw new RuntimeException("DockerThread stopped unexpectedly, non-zero exit value is " + exitValue);
305+
public void stop() throws Exception {
306+
OutputAnalyzer out = DockerTestUtils.execute(Container.ENGINE_COMMAND, "ps")
307+
.shouldHaveExitValue(0);
308+
if (out.contains(name)) {
309+
DockerTestUtils.execute(Container.ENGINE_COMMAND, "stop", name)
310+
.shouldHaveExitValue(0);
315311
}
316312
}
317313

314+
public String name() {
315+
return name;
316+
}
318317
}
319318

320319
private enum AttachStrategy {

test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ public static OutputAnalyzer execute(String... command) throws Exception {
289289
System.out.println("[ELAPSED: " + (System.currentTimeMillis() - started) + " ms]");
290290
System.out.println("[STDERR]\n" + output.getStderr());
291291
System.out.println("[STDOUT]\n" + stdoutLimited);
292-
if (stdout != stdoutLimited) {
292+
if (!stdout.equals(stdoutLimited)) {
293293
System.out.printf("Child process STDOUT is limited to %d lines\n",
294294
max);
295295
}

0 commit comments

Comments
 (0)