27
27
* 5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313
28
28
* 6464154 6523983 6206031 4960438 6631352 6631966 6850957 6850958
29
29
* 4947220 7018606 7034570 4244896 5049299 8003488 8054494 8058464
30
- * 8067796 8224905 8263729 8265173
30
+ * 8067796 8224905 8263729 8265173 8272600 8231297
31
31
* @key intermittent
32
32
* @summary Basic tests for Process and Environment Variable code
33
33
* @modules java.base/java.lang:open
34
34
* @library /test/lib
35
- * @run main/othervm/timeout=300 -Djava.security.manager=allow Basic
36
- * @run main/othervm/timeout=300 -Djava.security.manager=allow -Djdk.lang.Process.launchMechanism=fork Basic
35
+ * @run main/othervm/native/ timeout=300 -Djava.security.manager=allow Basic
36
+ * @run main/othervm/native/ timeout=300 -Djava.security.manager=allow -Djdk.lang.Process.launchMechanism=fork Basic
37
37
* @author Martin Buchholz
38
38
*/
39
39
50
50
import static java .lang .ProcessBuilder .Redirect .*;
51
51
52
52
import java .io .*;
53
- import java .lang .reflect .Field ;
54
53
import java .nio .file .Files ;
54
+ import java .nio .file .Path ;
55
55
import java .nio .file .Paths ;
56
56
import java .nio .file .StandardCopyOption ;
57
57
import java .util .*;
@@ -85,7 +85,7 @@ public class Basic {
85
85
/**
86
86
* Returns the number of milliseconds since time given by
87
87
* startNanoTime, which must have been previously returned from a
88
- * call to {@link System. nanoTime()}.
88
+ * call to {@link System# nanoTime()}.
89
89
*/
90
90
private static long millisElapsedSince (long startNanoTime ) {
91
91
return TimeUnit .NANOSECONDS .toMillis (System .nanoTime () - startNanoTime );
@@ -2137,34 +2137,8 @@ public void doIt(Map<String,String> environ) {
2137
2137
final int cases = 4 ;
2138
2138
for (int i = 0 ; i < cases ; i ++) {
2139
2139
final int action = i ;
2140
- List <String > childArgs = new ArrayList <>( javaChildArgs );
2140
+ List <String > childArgs = getSleepArgs ( );
2141
2141
final ProcessBuilder pb = new ProcessBuilder (childArgs );
2142
- {
2143
- // Redirect any child VM error output away from the stream being tested
2144
- // and to the log file. For background see:
2145
- // 8231297: java/lang/ProcessBuilder/Basic.java test fails intermittently
2146
- // Destroying the process may, depending on the timing, cause some output
2147
- // from the child VM.
2148
- // This test requires the thread reading from the subprocess be blocked
2149
- // in the read from the subprocess; there should be no bytes to read.
2150
- // Modify the argument list shared with ProcessBuilder to redirect VM output.
2151
- assert (childArgs .get (1 ).equals ("-XX:+DisplayVMOutputToStderr" )) : "Expected arg 1 to be \" -XX:+DisplayVMOutputToStderr\" " ;
2152
- switch (action & 0x1 ) {
2153
- case 0 :
2154
- childArgs .set (1 , "-XX:+DisplayVMOutputToStderr" );
2155
- childArgs .add (2 , "-Xlog:all=warning:stderr" );
2156
- pb .redirectError (INHERIT );
2157
- break ;
2158
- case 1 :
2159
- childArgs .set (1 , "-XX:+DisplayVMOutputToStdout" );
2160
- childArgs .add (2 , "-Xlog:all=warning:stdout" );
2161
- pb .redirectOutput (INHERIT );
2162
- break ;
2163
- default :
2164
- throw new Error ();
2165
- }
2166
- }
2167
- childArgs .add ("sleep" );
2168
2142
final byte [] bytes = new byte [10 ];
2169
2143
final Process p = pb .start ();
2170
2144
final CountDownLatch latch = new CountDownLatch (1 );
@@ -2237,9 +2211,10 @@ && new File("/bin/sleep").exists()) {
2237
2211
// our child) but not our grandchild (i.e. '/bin/sleep'). So
2238
2212
// pay attention that the grandchild doesn't run too long to
2239
2213
// avoid polluting the process space with useless processes.
2240
- // Running the grandchild for 60s should be more than enough.
2241
- final String [] cmd = { "/bin/bash" , "-c" , "(/bin/sleep 60)" };
2242
- final String [] cmdkill = { "/bin/bash" , "-c" , "(/usr/bin/pkill -f \" sleep 60\" )" };
2214
+ // Running the grandchild for 59s should be more than enough.
2215
+ // A unique (59s) time is needed to avoid killing other sleep processes.
2216
+ final String [] cmd = { "/bin/bash" , "-c" , "(/bin/sleep 59)" };
2217
+ final String [] cmdkill = { "/bin/bash" , "-c" , "(/usr/bin/pkill -f \" sleep 59\" )" };
2243
2218
final ProcessBuilder pb = new ProcessBuilder (cmd );
2244
2219
final Process p = pb .start ();
2245
2220
final InputStream stdout = p .getInputStream ();
@@ -2441,8 +2416,7 @@ public void run() {
2441
2416
// Process.waitFor(0, TimeUnit.MILLISECONDS) work as expected.
2442
2417
//----------------------------------------------------------------
2443
2418
try {
2444
- List <String > childArgs = new ArrayList <String >(javaChildArgs );
2445
- childArgs .add ("sleep" );
2419
+ List <String > childArgs = getSleepArgs ();
2446
2420
final Process p = new ProcessBuilder (childArgs ).start ();
2447
2421
long start = System .nanoTime ();
2448
2422
if (!p .isAlive () || p .waitFor (0 , TimeUnit .MILLISECONDS )) {
@@ -2471,17 +2445,19 @@ public void run() {
2471
2445
// works as expected.
2472
2446
//----------------------------------------------------------------
2473
2447
try {
2474
- List <String > childArgs = new ArrayList <String >(javaChildArgs );
2475
- childArgs .add ("sleep" );
2448
+ List <String > childArgs = getSleepArgs ();
2476
2449
final Process p = new ProcessBuilder (childArgs ).start ();
2477
2450
long start = System .nanoTime ();
2478
2451
2479
- p .waitFor (10 , TimeUnit .MILLISECONDS );
2480
-
2481
- long end = System .nanoTime ();
2482
- if ((end - start ) < TimeUnit .MILLISECONDS .toNanos (10 ))
2483
- fail ("Test failed: waitFor didn't take long enough (" + (end - start ) + "ns)" );
2484
-
2452
+ if (p .waitFor (10 , TimeUnit .MILLISECONDS )) {
2453
+ var msg = "External sleep process terminated early: exitValue: %d, (%dns)%n"
2454
+ .formatted (p .exitValue (), (System .nanoTime () - start ));
2455
+ fail (msg );
2456
+ } else {
2457
+ long end = System .nanoTime ();
2458
+ if ((end - start ) < TimeUnit .MILLISECONDS .toNanos (10 ))
2459
+ fail ("Test failed: waitFor didn't take long enough (" + (end - start ) + "ns)" );
2460
+ }
2485
2461
p .destroy ();
2486
2462
} catch (Throwable t ) { unexpected (t ); }
2487
2463
@@ -2490,8 +2466,7 @@ public void run() {
2490
2466
// interrupt works as expected, if interrupted while waiting.
2491
2467
//----------------------------------------------------------------
2492
2468
try {
2493
- List <String > childArgs = new ArrayList <String >(javaChildArgs );
2494
- childArgs .add ("sleep" );
2469
+ List <String > childArgs = getSleepArgs ();
2495
2470
final Process p = new ProcessBuilder (childArgs ).start ();
2496
2471
final long start = System .nanoTime ();
2497
2472
final CountDownLatch aboutToWaitFor = new CountDownLatch (1 );
@@ -2522,8 +2497,7 @@ public void run() {
2522
2497
// interrupt works as expected, if interrupted while waiting.
2523
2498
//----------------------------------------------------------------
2524
2499
try {
2525
- List <String > childArgs = new ArrayList <String >(javaChildArgs );
2526
- childArgs .add ("sleep" );
2500
+ List <String > childArgs = getSleepArgs ();
2527
2501
final Process p = new ProcessBuilder (childArgs ).start ();
2528
2502
final long start = System .nanoTime ();
2529
2503
final CountDownLatch aboutToWaitFor = new CountDownLatch (1 );
@@ -2554,8 +2528,7 @@ public void run() {
2554
2528
// interrupt works as expected, if interrupted before waiting.
2555
2529
//----------------------------------------------------------------
2556
2530
try {
2557
- List <String > childArgs = new ArrayList <String >(javaChildArgs );
2558
- childArgs .add ("sleep" );
2531
+ List <String > childArgs = getSleepArgs ();
2559
2532
final Process p = new ProcessBuilder (childArgs ).start ();
2560
2533
final long start = System .nanoTime ();
2561
2534
final CountDownLatch threadStarted = new CountDownLatch (1 );
@@ -2586,8 +2559,7 @@ public void run() {
2586
2559
// Check that Process.waitFor(timeout, null) throws NPE.
2587
2560
//----------------------------------------------------------------
2588
2561
try {
2589
- List <String > childArgs = new ArrayList <String >(javaChildArgs );
2590
- childArgs .add ("sleep" );
2562
+ List <String > childArgs = getSleepArgs ();
2591
2563
final Process p = new ProcessBuilder (childArgs ).start ();
2592
2564
THROWS (NullPointerException .class ,
2593
2565
() -> p .waitFor (10L , null ));
@@ -2610,8 +2582,7 @@ public void run() {
2610
2582
// Check that default implementation of Process.waitFor(timeout, null) throws NPE.
2611
2583
//----------------------------------------------------------------
2612
2584
try {
2613
- List <String > childArgs = new ArrayList <String >(javaChildArgs );
2614
- childArgs .add ("sleep" );
2585
+ List <String > childArgs = getSleepArgs ();
2615
2586
final Process proc = new ProcessBuilder (childArgs ).start ();
2616
2587
final DelegatingProcess p = new DelegatingProcess (proc );
2617
2588
@@ -2637,24 +2608,75 @@ public void run() {
2637
2608
// Process.waitFor(long, TimeUnit)
2638
2609
//----------------------------------------------------------------
2639
2610
try {
2640
- List <String > childArgs = new ArrayList <String >(javaChildArgs );
2641
- childArgs .add ("sleep" );
2611
+ List <String > childArgs = getSleepArgs ();
2642
2612
final Process proc = new ProcessBuilder (childArgs ).start ();
2643
2613
DelegatingProcess p = new DelegatingProcess (proc );
2644
2614
long start = System .nanoTime ();
2645
2615
2646
- p .waitFor (1000 , TimeUnit .MILLISECONDS );
2647
-
2648
- long end = System .nanoTime ();
2649
- if ((end - start ) < 500000000 )
2650
- fail ("Test failed: waitFor didn't take long enough" );
2651
-
2616
+ if (p .waitFor (1000 , TimeUnit .MILLISECONDS )) {
2617
+ var msg = "External sleep process terminated early: exitValue: %02x, (%dns)"
2618
+ .formatted (p .exitValue (), (System .nanoTime () - start ));
2619
+ fail (msg );
2620
+ } else {
2621
+ long end = System .nanoTime ();
2622
+ if ((end - start ) < 500000000 )
2623
+ fail ("Test failed: waitFor didn't take long enough (" + (end - start ) + "ns)" );
2624
+ }
2652
2625
p .destroy ();
2653
2626
2654
2627
p .waitFor (1000 , TimeUnit .MILLISECONDS );
2655
2628
} catch (Throwable t ) { unexpected (t ); }
2656
2629
}
2657
2630
2631
+ // Path to native executables, if any
2632
+ private static final String TEST_NATIVEPATH = System .getProperty ("test.nativepath" );
2633
+
2634
+ // Path where "sleep" program may be found" or null
2635
+ private static final Path SLEEP_PATH = initSleepPath ();
2636
+
2637
+ /**
2638
+ * Compute the Path to a sleep executable.
2639
+ * @return a Path to sleep or BasicSleep(.exe) or null if none
2640
+ */
2641
+ private static Path initSleepPath () {
2642
+ if (Windows .is () && TEST_NATIVEPATH != null ) {
2643
+ // exeBasicSleep is equivalent to sleep on Unix
2644
+ Path exePath = Path .of (TEST_NATIVEPATH ).resolve ("BasicSleep.exe" );
2645
+ if (Files .isExecutable (exePath )) {
2646
+ return exePath ;
2647
+ }
2648
+ }
2649
+
2650
+ List <String > binPaths = List .of ("/bin" , "/usr/bin" );
2651
+ for (String dir : binPaths ) {
2652
+ Path exePath = Path .of (dir ).resolve ("sleep" );
2653
+ if (Files .isExecutable (exePath )) {
2654
+ return exePath ;
2655
+ }
2656
+ }
2657
+ return null ;
2658
+ }
2659
+
2660
+ /**
2661
+ * Return the list of process arguments for a child to sleep 10 minutes (600 seconds).
2662
+ *
2663
+ * @return A list of process arguments to sleep 10 minutes.
2664
+ */
2665
+ private static List <String > getSleepArgs () {
2666
+ List <String > childArgs = null ;
2667
+ if (SLEEP_PATH != null ) {
2668
+ childArgs = List .of (SLEEP_PATH .toString (), "600" );
2669
+ } else {
2670
+ // Fallback to the JavaChild ; its 'sleep' command is for 10 minutes.
2671
+ // The fallback the Java$Child is used if the test is run without building
2672
+ // the BasicSleep native executable (for Windows).
2673
+ childArgs = new ArrayList <>(javaChildArgs );
2674
+ childArgs .add ("sleep" );
2675
+ System .out .println ("Sleep not found, fallback to JavaChild: " + childArgs );
2676
+ }
2677
+ return childArgs ;
2678
+ }
2679
+
2658
2680
static void closeStreams (Process p ) {
2659
2681
try {
2660
2682
p .getOutputStream ().close ();
0 commit comments