48
48
import java .util .EnumSet ;
49
49
import java .util .List ;
50
50
import java .util .Optional ;
51
+ import java .util .Random ;
51
52
import java .util .concurrent .TimeUnit ;
52
53
import java .util .function .Consumer ;
53
54
import java .util .regex .Pattern ;
54
- import java .util .stream .Collectors ;
55
55
56
56
import jdk .test .lib .Container ;
57
57
import jdk .test .lib .Platform ;
@@ -67,7 +67,6 @@ public class TestJcmdWithSideCar {
67
67
private static final String IMAGE_NAME = Common .imageName ("jfr-jcmd" );
68
68
private static final int TIME_TO_RUN_MAIN_PROCESS = (int ) (30 * Utils .TIMEOUT_FACTOR ); // seconds
69
69
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" ;
71
70
72
71
private static final String UID = "uid" ;
73
72
private static final String GID = "gid" ;
@@ -115,19 +114,19 @@ public static void main(String[] args) throws Exception {
115
114
// Elevated attach via proc/root not yet supported.
116
115
continue ;
117
116
}
118
- long mainProcPid = testCase01 (attachStrategy , elevated );
117
+ long mainProcPid = testCase01 (mainContainer , attachStrategy , elevated );
119
118
120
119
// Excluding the test case below until JDK-8228850 is fixed
121
120
// JDK-8228850: jhsdb jinfo fails with ClassCastException:
122
121
// s.j.h.oops.TypeArray cannot be cast to s.j.h.oops.Instance
123
122
// mainContainer.assertIsAlive();
124
- // testCase02(mainProcPid, attachStrategy, elevated);
123
+ // testCase02(mainContainer, mainProcPid, attachStrategy, elevated);
125
124
126
125
mainContainer .assertIsAlive ();
127
- testCase03 (mainProcPid , attachStrategy , elevated );
126
+ testCase03 (mainContainer , mainProcPid , attachStrategy , elevated );
128
127
}
129
128
130
- mainContainer .waitForAndCheck ( TIME_TO_RUN_MAIN_PROCESS * 1000 );
129
+ mainContainer .stop ( );
131
130
}
132
131
} finally {
133
132
DockerTestUtils .removeDockerImage (IMAGE_NAME );
@@ -136,8 +135,8 @@ public static void main(String[] args) throws Exception {
136
135
137
136
138
137
// 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" )
141
140
.shouldHaveExitValue (0 )
142
141
.shouldContain ("sun.tools.jcmd.JCmd" );
143
142
long pid = findProcess (out , "EventGeneratorLoop" );
@@ -149,20 +148,20 @@ private static long testCase01(AttachStrategy attachStrategy, boolean elevated)
149
148
}
150
149
151
150
// 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 )
154
153
.shouldHaveExitValue (0 )
155
154
.shouldContain ("Java System Properties" )
156
155
.shouldContain ("VM Flags" );
157
156
}
158
157
159
158
// test jcmd with some commands (help, start JFR recording)
160
159
// 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" )
163
162
.shouldHaveExitValue (0 )
164
163
.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" )
166
165
.shouldHaveExitValue (0 )
167
166
.shouldContain ("Started recording" );
168
167
}
@@ -174,18 +173,18 @@ private static void testCase03(long pid, AttachStrategy attachStrategy, boolean
174
173
// we have two options:
175
174
// 1. mount /tmp from the main container using --volumes-from.
176
175
// 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 {
178
177
System .out .println ("Attach strategy " + attachStrategy );
179
178
180
179
List <String > initialCommands = List .of (
181
180
Container .ENGINE_COMMAND , "run" ,
182
181
"--tty=true" , "--rm" ,
183
182
"--cap-add=SYS_PTRACE" , "--sig-proxy=true" ,
184
- "--pid=container:" + mainContainerName
183
+ "--pid=container:" + mainContainer . name ()
185
184
);
186
185
187
186
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 () );
189
188
case ACCESS_TMP_VIA_PROC_ROOT -> List .of ();
190
189
};
191
190
@@ -209,11 +208,11 @@ private static long findProcess(OutputAnalyzer out, String name) throws Exceptio
209
208
List <String > l = out .asLines ()
210
209
.stream ()
211
210
.filter (s -> s .contains (name ))
212
- .collect ( Collectors . toList () );
211
+ .toList ();
213
212
if (l .isEmpty ()) {
214
213
return -1 ;
215
214
}
216
- String psInfo = l .get ( 0 );
215
+ String psInfo = l .getFirst ( );
217
216
System .out .println ("findProcess(): psInfo: " + psInfo );
218
217
String pid = psInfo .substring (0 , psInfo .indexOf (' ' ));
219
218
System .out .println ("findProcess(): pid: " + pid );
@@ -236,6 +235,10 @@ private static void sleep(long delay) {
236
235
237
236
238
237
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 ;
239
242
boolean mainMethodStarted ;
240
243
Process p ;
241
244
@@ -255,8 +258,11 @@ public Process start(final boolean elevated) throws Exception {
255
258
opts .addDockerOpts (NET_BIND_SERVICE );
256
259
}
257
260
261
+ name = MAIN_CONTAINER_NAME_PREFIX + "-elevated-" + elevated + "-" + RANDOM .nextInt ();
262
+
258
263
opts .addDockerOpts ("--cap-add=SYS_PTRACE" )
259
- .addDockerOpts ("--name" , MAIN_CONTAINER_NAME )
264
+ .addDockerOpts ("--init" )
265
+ .addDockerOpts ("--name" , name )
260
266
.addDockerOpts ("--volume" , "/tmp" )
261
267
.addDockerOpts ("--volume" , Paths .get ("." ).toAbsolutePath () + ":/workdir/" )
262
268
.addJavaOpts ("-XX:+UsePerfData" )
@@ -296,25 +302,18 @@ public void waitFor(long timeout) throws Exception {
296
302
p .waitFor (timeout , TimeUnit .MILLISECONDS );
297
303
}
298
304
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 );
315
311
}
316
312
}
317
313
314
+ public String name () {
315
+ return name ;
316
+ }
318
317
}
319
318
320
319
private enum AttachStrategy {
0 commit comments