mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-13 17:33:10 +00:00
8379437: Refactor ProcessBuilder and ProcessHandle tests to JUnit
Reviewed-by: jpai
This commit is contained in:
parent
f95e8136b1
commit
bad59c55d9
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2026, 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
|
||||
@ -23,21 +23,22 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8023130 8166026
|
||||
* @summary Unit test for java.lang.ProcessBuilder inheritance of standard output and standard error streams
|
||||
* @bug 8023130 8166026
|
||||
* @requires vm.flagless
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.process.*
|
||||
* @run testng InheritIOTest
|
||||
* @run junit InheritIOTest
|
||||
*/
|
||||
|
||||
import java.util.List;
|
||||
import static java.lang.ProcessBuilder.Redirect.INHERIT;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
public class InheritIOTest {
|
||||
|
||||
@ -45,25 +46,25 @@ public class InheritIOTest {
|
||||
private static final String EXPECTED_RESULT_STDOUT = "message";
|
||||
private static final String EXPECTED_RESULT_STDERR = EXIT_VALUE_TEMPLATE.formatted(0);
|
||||
|
||||
@DataProvider
|
||||
public Object[][] testCases() {
|
||||
return new Object[][]{
|
||||
new Object[] { List.of("InheritIOTest$TestInheritIO", "printf", EXPECTED_RESULT_STDOUT) },
|
||||
new Object[] { List.of("InheritIOTest$TestRedirectInherit", "printf", EXPECTED_RESULT_STDOUT) }
|
||||
};
|
||||
public static List<Arguments> testCases() {
|
||||
return List.of(
|
||||
Arguments.of(List.of("InheritIOTest$TestInheritIO", "printf", EXPECTED_RESULT_STDOUT)),
|
||||
Arguments.of(List.of("InheritIOTest$TestRedirectInherit", "printf", EXPECTED_RESULT_STDOUT))
|
||||
);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "testCases")
|
||||
@ParameterizedTest
|
||||
@MethodSource("testCases")
|
||||
public void testInheritWithoutRedirect(List<String> arguments) throws Throwable {
|
||||
ProcessBuilder processBuilder = ProcessTools.createLimitedTestJavaProcessBuilder(arguments);
|
||||
OutputAnalyzer outputAnalyzer = ProcessTools.executeCommand(processBuilder);
|
||||
outputAnalyzer.shouldHaveExitValue(0);
|
||||
assertEquals(outputAnalyzer.getStdout(), EXPECTED_RESULT_STDOUT);
|
||||
assertEquals(outputAnalyzer.getStderr(), EXPECTED_RESULT_STDERR);
|
||||
assertEquals(EXPECTED_RESULT_STDOUT, outputAnalyzer.getStdout());
|
||||
assertEquals(EXPECTED_RESULT_STDERR, outputAnalyzer.getStderr());
|
||||
}
|
||||
|
||||
public static class TestInheritIO {
|
||||
public static void main(String args[]) throws Throwable {
|
||||
public static void main(String[] args) throws Throwable {
|
||||
int err = new ProcessBuilder(args).inheritIO().start().waitFor();
|
||||
System.err.printf(EXIT_VALUE_TEMPLATE, err);
|
||||
System.exit(err);
|
||||
@ -71,7 +72,7 @@ public class InheritIOTest {
|
||||
}
|
||||
|
||||
public static class TestRedirectInherit {
|
||||
public static void main(String args[]) throws Throwable {
|
||||
public static void main(String[] args) throws Throwable {
|
||||
int err = new ProcessBuilder(args)
|
||||
.redirectInput(INHERIT)
|
||||
.redirectOutput(INHERIT)
|
||||
@ -81,5 +82,4 @@ public class InheritIOTest {
|
||||
System.exit(err);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2026, 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
|
||||
@ -23,9 +23,9 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8269488
|
||||
* @summary verify that Process Reaper threads have a null CCL
|
||||
* @run testng ProcessReaperCCL
|
||||
* @bug 8269488
|
||||
* @run junit ProcessReaperCCL
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
@ -34,14 +34,13 @@ import java.net.URLClassLoader;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class ProcessReaperCCL {
|
||||
|
||||
@Test
|
||||
static void test() throws Exception {
|
||||
void test() throws Exception {
|
||||
// create a class loader
|
||||
File dir = new File(".");
|
||||
URL[] urls = new URL[] {dir.toURI().toURL()};
|
||||
@ -53,12 +52,12 @@ public class ProcessReaperCCL {
|
||||
Process p = pb.start();
|
||||
CompletableFuture<Process> cf = p.onExit();
|
||||
int exitValue = cf.get().exitValue();
|
||||
Assert.assertEquals(exitValue, 0, "error exit value");
|
||||
Assertions.assertEquals(0, exitValue, "error exit value");
|
||||
|
||||
// Verify all "Process Reaper" threads have a null CCL
|
||||
for (Thread th : Thread.getAllStackTraces().keySet()) {
|
||||
if (th.getName().startsWith("process reaper")) {
|
||||
Assert.assertEquals(th.getContextClassLoader(), null, "CCL not null");
|
||||
Assertions.assertNull(th.getContextClassLoader(), "CCL not null");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2026, 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
|
||||
@ -34,8 +34,7 @@ import java.util.stream.Stream;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2026, 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
|
||||
@ -21,17 +21,10 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
|
||||
import jdk.test.lib.hexdump.HexPrinter;
|
||||
import jdk.test.lib.hexdump.HexPrinter.Formatters;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
@ -42,20 +35,23 @@ import java.nio.file.Files;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jtreg.SkippedException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @requires vm.flagless
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.process.ProcessTools jdk.test.lib.hexdump.HexPrinter
|
||||
* @run testng ReaderWriterTest
|
||||
* @build jdk.test.lib.process.ProcessTools
|
||||
* @run junit ReaderWriterTest
|
||||
*/
|
||||
|
||||
@Test
|
||||
public class ReaderWriterTest {
|
||||
|
||||
static final String ASCII = "ASCII: \u0000_A-Z_a-Z_\u007C_\u007D_\u007E_\u007F_;";
|
||||
@ -65,13 +61,12 @@ public class ReaderWriterTest {
|
||||
public static final String TESTCHARS = "OneWay: " + ASCII + ISO_8859_1 + FRACTIONS;
|
||||
public static final String ROUND_TRIP_TESTCHARS = "RoundTrip: " + ASCII + ISO_8859_1 + FRACTIONS;
|
||||
|
||||
@DataProvider(name="CharsetCases")
|
||||
static Object[][] charsetCases() {
|
||||
return new Object[][] {
|
||||
{"UTF-8"},
|
||||
{"ISO8859-1"},
|
||||
{"US-ASCII"},
|
||||
};
|
||||
static Stream<Arguments> charsetCases() {
|
||||
return Stream.of(
|
||||
Arguments.of("UTF-8"),
|
||||
Arguments.of("ISO8859-1"),
|
||||
Arguments.of("US-ASCII")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -93,7 +88,7 @@ public class ReaderWriterTest {
|
||||
if (exitValue != 0)
|
||||
System.out.println("exitValue: " + exitValue);
|
||||
} catch (InterruptedException ie) {
|
||||
Assert.fail("waitFor interrupted");
|
||||
fail("waitFor interrupted");
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,32 +126,28 @@ public class ReaderWriterTest {
|
||||
if (errType == 2 || errType == 3) {
|
||||
pb.redirectErrorStream(true);
|
||||
}
|
||||
Process p = pb.start();
|
||||
// Output has been redirected to a null stream; success is IOException on the write
|
||||
try {
|
||||
try (Process p = pb.start()) {
|
||||
// Output has been redirected to a null stream; success is IOException on the write
|
||||
BufferedWriter wr = p.outputWriter();
|
||||
wr.write("X");
|
||||
wr.flush();
|
||||
Assert.fail("writing to null stream should throw IOException");
|
||||
} catch (IOException ioe) {
|
||||
// Normal, A Null output stream is closed when created.
|
||||
}
|
||||
assertThrows(IOException.class, () -> {
|
||||
wr.write("X");
|
||||
wr.flush();
|
||||
});
|
||||
|
||||
// InputReader should be empty; and at EOF
|
||||
BufferedReader inputReader = p.inputReader();
|
||||
int ch = inputReader.read();
|
||||
Assert.assertEquals(ch, -1, "inputReader not at EOF: ch: " + (char)ch);
|
||||
// InputReader should be empty; and at EOF
|
||||
BufferedReader inputReader = p.inputReader();
|
||||
int ch = inputReader.read();
|
||||
assertEquals(-1, ch, "inputReader not at EOF: ch: " + (char) ch);
|
||||
|
||||
// InputReader should be empty; and at EOF
|
||||
BufferedReader errorReader = p.errorReader();
|
||||
ch = errorReader.read();
|
||||
Assert.assertEquals(ch, -1, "errorReader not at EOF: ch: " + (char)ch);
|
||||
// InputReader should be empty; and at EOF
|
||||
BufferedReader errorReader = p.errorReader();
|
||||
ch = errorReader.read();
|
||||
assertEquals(-1, ch, "errorReader not at EOF: ch: " + (char) ch);
|
||||
|
||||
try {
|
||||
int exitValue = p.waitFor();
|
||||
if (exitValue != 0) System.out.println("exitValue: " + exitValue);
|
||||
} catch (InterruptedException ie) {
|
||||
Assert.fail("waitFor interrupted");
|
||||
fail("waitFor interrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -181,7 +172,8 @@ public class ReaderWriterTest {
|
||||
*
|
||||
* @param encoding a charset name
|
||||
*/
|
||||
@Test(dataProvider = "CharsetCases", enabled = true)
|
||||
@ParameterizedTest
|
||||
@MethodSource("charsetCases")
|
||||
void testCase(String encoding) throws IOException {
|
||||
Charset cs = null;
|
||||
try {
|
||||
@ -221,32 +213,10 @@ public class ReaderWriterTest {
|
||||
ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(
|
||||
"ReaderWriterTest$ChildWithCharset");
|
||||
|
||||
Process p = pb.start();
|
||||
try {
|
||||
writeTestChars(p.outputWriter(null));
|
||||
Assert.fail("Process.outputWriter(null) did not throw NPE");
|
||||
} catch (NullPointerException npe) {
|
||||
// expected, ignore
|
||||
}
|
||||
try {
|
||||
checkReader(p.inputReader(null), null, "Out");
|
||||
Assert.fail("Process.inputReader(null) did not throw NPE");
|
||||
} catch (NullPointerException npe) {
|
||||
// expected, ignore
|
||||
}
|
||||
try {
|
||||
checkReader(p.errorReader(null), null, "Err");
|
||||
Assert.fail("Process.errorReader(null) did not throw NPE");
|
||||
} catch (NullPointerException npe) {
|
||||
// expected, ignore
|
||||
}
|
||||
|
||||
p.destroyForcibly();
|
||||
try {
|
||||
// Collect the exit status to cleanup after the process; but ignore it
|
||||
p.waitFor();
|
||||
} catch (InterruptedException ie) {
|
||||
// Ignored
|
||||
try (Process p = pb.start()) {
|
||||
assertThrows(NullPointerException.class, () -> writeTestChars(p.outputWriter(null)));
|
||||
assertThrows(NullPointerException.class, () -> checkReader(p.inputReader(null), null, "Out"));
|
||||
assertThrows(NullPointerException.class, () -> checkReader(p.errorReader(null), null, "Err"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,7 +242,7 @@ public class ReaderWriterTest {
|
||||
var writer = p.outputWriter(cs);
|
||||
writer = p.outputWriter(cs); // try again with same
|
||||
writer = p.outputWriter(otherCharset); // this should throw
|
||||
Assert.fail("Process.outputWriter(otherCharset) did not throw IllegalStateException");
|
||||
fail("Process.outputWriter(otherCharset) did not throw IllegalStateException");
|
||||
} catch (IllegalStateException ile) {
|
||||
// expected, ignore
|
||||
System.out.println(ile);
|
||||
@ -281,7 +251,7 @@ public class ReaderWriterTest {
|
||||
var reader = p.inputReader(cs);
|
||||
reader = p.inputReader(cs); // try again with same
|
||||
reader = p.inputReader(otherCharset); // this should throw
|
||||
Assert.fail("Process.inputReader(otherCharset) did not throw IllegalStateException");
|
||||
fail("Process.inputReader(otherCharset) did not throw IllegalStateException");
|
||||
} catch (IllegalStateException ile) {
|
||||
// expected, ignore
|
||||
System.out.println(ile);
|
||||
@ -290,7 +260,7 @@ public class ReaderWriterTest {
|
||||
var reader = p.errorReader(cs);
|
||||
reader = p.errorReader(cs); // try again with same
|
||||
reader = p.errorReader(otherCharset); // this should throw
|
||||
Assert.fail("Process.errorReader(otherCharset) did not throw IllegalStateException");
|
||||
fail("Process.errorReader(otherCharset) did not throw IllegalStateException");
|
||||
} catch (IllegalStateException ile) {
|
||||
// expected, ignore
|
||||
System.out.println(ile);
|
||||
@ -320,13 +290,13 @@ public class ReaderWriterTest {
|
||||
String reencoded = cs.decode(bb).toString();
|
||||
if (!firstline.equals(reencoded))
|
||||
diffStrings(firstline, reencoded);
|
||||
assertEquals(firstline, reencoded, label + " Test Chars");
|
||||
assertEquals(reencoded, firstline, label + " Test Chars");
|
||||
|
||||
bb = cs.encode(ROUND_TRIP_TESTCHARS);
|
||||
reencoded = cs.decode(bb).toString();
|
||||
if (!secondline.equals(reencoded))
|
||||
diffStrings(secondline, reencoded);
|
||||
assertEquals(secondline, reencoded, label + " Round Trip Test Chars");
|
||||
assertEquals(reencoded, secondline, label + " Round Trip Test Chars");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2026, 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
|
||||
@ -21,21 +21,22 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.fail;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.testng.TestNG;
|
||||
import org.testng.annotations.Test;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Basic tests for ProcessHandler
|
||||
* @library /test/lib
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* jdk.management
|
||||
@ -45,20 +46,18 @@ import org.testng.annotations.Test;
|
||||
* jdk.test.lib.JDKToolLauncher
|
||||
* jdk.test.lib.Platform
|
||||
* jdk.test.lib.process.*
|
||||
* @run testng Basic
|
||||
* @summary Basic tests for ProcessHandler
|
||||
* @author Roger Riggs
|
||||
* @run junit Basic
|
||||
*/
|
||||
public class Basic {
|
||||
/**
|
||||
* Tests of ProcessHandle.current.
|
||||
*/
|
||||
@Test
|
||||
public static void test1() {
|
||||
public void test1() {
|
||||
try {
|
||||
ProcessHandle self = ProcessHandle.current();
|
||||
ProcessHandle self1 = ProcessHandle.current();
|
||||
assertEquals(self, self1); //, "get pid twice should be same %d: %d");
|
||||
assertEquals(self1, self); //, "get pid twice should be same %d: %d");
|
||||
} finally {
|
||||
// Cleanup any left over processes
|
||||
ProcessHandle.current().children().forEach(ProcessHandle::destroy);
|
||||
@ -69,16 +68,16 @@ public class Basic {
|
||||
* Tests of ProcessHandle.get.
|
||||
*/
|
||||
@Test
|
||||
public static void test2() {
|
||||
public void test2() {
|
||||
try {
|
||||
ProcessHandle self = ProcessHandle.current();
|
||||
long pid = self.pid(); // known native process id
|
||||
Optional<ProcessHandle> self1 = ProcessHandle.of(pid);
|
||||
assertEquals(self1.get(), self,
|
||||
assertEquals(self, self1.get(),
|
||||
"ProcessHandle.of(x.pid()) should be equal pid() %d: %d");
|
||||
|
||||
Optional<ProcessHandle> ph = ProcessHandle.of(pid);
|
||||
assertEquals(pid, ph.get().pid());
|
||||
assertEquals(ph.get().pid(), pid);
|
||||
} finally {
|
||||
// Cleanup any left over processes
|
||||
ProcessHandle.current().children().forEach(ProcessHandle::destroy);
|
||||
@ -86,7 +85,7 @@ public class Basic {
|
||||
}
|
||||
|
||||
@Test
|
||||
public static void test3() {
|
||||
public void test3() {
|
||||
// Test can get parent of current
|
||||
ProcessHandle ph = ProcessHandle.current();
|
||||
try {
|
||||
@ -99,7 +98,7 @@ public class Basic {
|
||||
}
|
||||
|
||||
@Test
|
||||
public static void test4() {
|
||||
public void test4() {
|
||||
try {
|
||||
Process p = new ProcessBuilder("sleep", "0").start();
|
||||
p.waitFor();
|
||||
@ -118,7 +117,7 @@ public class Basic {
|
||||
}
|
||||
|
||||
@Test
|
||||
public static void test5() {
|
||||
public void test5() {
|
||||
// Always contains itself.
|
||||
ProcessHandle current = ProcessHandle.current();
|
||||
List<ProcessHandle> list = ProcessHandle.allProcesses().collect(Collectors.toList());
|
||||
@ -131,23 +130,17 @@ public class Basic {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalStateException.class)
|
||||
public static void test6() {
|
||||
ProcessHandle.current().onExit();
|
||||
@Test
|
||||
public void test6() {
|
||||
Assertions.assertThrows(IllegalStateException.class, () -> {
|
||||
ProcessHandle.current().onExit();
|
||||
});
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalStateException.class)
|
||||
public static void test7() {
|
||||
ProcessHandle.current().destroyForcibly();
|
||||
@Test
|
||||
public void test7() {
|
||||
Assertions.assertThrows(IllegalStateException.class, () -> {
|
||||
ProcessHandle.current().destroyForcibly();
|
||||
});
|
||||
}
|
||||
|
||||
// Main can be used to run the tests from the command line with only testng.jar.
|
||||
@SuppressWarnings("raw_types")
|
||||
public static void main(String[] args) {
|
||||
Class<?>[] testclass = {TreeTest.class};
|
||||
TestNG testng = new TestNG();
|
||||
testng.setTestClasses(testclass);
|
||||
testng.run();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2026, 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
|
||||
@ -39,15 +39,15 @@ import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.TestNG;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import jdk.test.lib.Platform;
|
||||
import jdk.test.lib.Utils;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Functions of ProcessHandle.Info
|
||||
* @bug 8077350 8081566 8081567 8098852 8136597
|
||||
* @requires os.arch != "riscv64" | !(vm.cpu.features ~= ".*qemu.*")
|
||||
* @library /test/lib
|
||||
@ -59,8 +59,7 @@ import jdk.test.lib.Utils;
|
||||
* jdk.test.lib.JDKToolLauncher
|
||||
* jdk.test.lib.Platform
|
||||
* jdk.test.lib.process.*
|
||||
* @run testng InfoTest
|
||||
* @summary Functions of ProcessHandle.Info
|
||||
* @run junit InfoTest
|
||||
* @author Roger Riggs
|
||||
*/
|
||||
|
||||
@ -82,19 +81,11 @@ public class InfoTest {
|
||||
}
|
||||
}
|
||||
|
||||
// Main can be used to run the tests from the command line with only testng.jar.
|
||||
public static void main(String[] args) {
|
||||
Class<?>[] testclass = {InfoTest.class};
|
||||
TestNG testng = new TestNG();
|
||||
testng.setTestClasses(testclass);
|
||||
testng.run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that cputime used shows up in ProcessHandle.info
|
||||
*/
|
||||
@Test
|
||||
public static void test1() {
|
||||
public void test1() {
|
||||
System.out.println("Note: when run in samevm mode the cputime of the " +
|
||||
"test runner is included.");
|
||||
ProcessHandle self = ProcessHandle.current();
|
||||
@ -108,7 +99,7 @@ public class InfoTest {
|
||||
System.out.printf(" info: %s%n", info);
|
||||
Optional<Duration> totalCpu = info.totalCpuDuration();
|
||||
if (totalCpu.isPresent() && (totalCpu.get().compareTo(someCPU) < 0)) {
|
||||
Assert.fail("reported cputime less than expected: " + someCPU + ", " +
|
||||
Assertions.fail("reported cputime less than expected: " + someCPU + ", " +
|
||||
"actual: " + info.totalCpuDuration());
|
||||
}
|
||||
}
|
||||
@ -117,7 +108,7 @@ public class InfoTest {
|
||||
* Spawn a child with arguments and check they are visible via the ProcessHandle.
|
||||
*/
|
||||
@Test
|
||||
public static void test2() {
|
||||
public void test2() {
|
||||
try {
|
||||
long cpuLoopTime = 100; // 100 ms
|
||||
String[] extraArgs = {"pid", "parent", "stdin"};
|
||||
@ -170,7 +161,7 @@ public class InfoTest {
|
||||
String expected = Platform.isWindows() ? javaExe + ".exe" : javaExe;
|
||||
Path expectedPath = Paths.get(expected);
|
||||
Path actualPath = Paths.get(command.get());
|
||||
Assert.assertTrue(Files.isSameFile(expectedPath, actualPath),
|
||||
Assertions.assertTrue(Files.isSameFile(expectedPath, actualPath),
|
||||
"Command: expected: " + javaExe + ", actual: " + command.get());
|
||||
}
|
||||
|
||||
@ -179,22 +170,20 @@ public class InfoTest {
|
||||
|
||||
int offset = args.length - extraArgs.length;
|
||||
for (int i = 0; i < extraArgs.length; i++) {
|
||||
Assert.assertEquals(args[offset + i], extraArgs[i],
|
||||
Assertions.assertEquals(extraArgs[i], args[offset + i],
|
||||
"Actual argument mismatch, index: " + i);
|
||||
}
|
||||
|
||||
// Now check that the first argument is not the same as the executed command
|
||||
if (args.length > 0) {
|
||||
Assert.assertNotEquals(args[0], command,
|
||||
"First argument should not be the executable: args[0]: "
|
||||
+ args[0] + ", command: " + command);
|
||||
}
|
||||
Assertions.assertNotEquals(command, args[0],
|
||||
"First argument should not be the executable: args[0]: "
|
||||
+ args[0] + ", command: " + command);
|
||||
}
|
||||
|
||||
if (command.isPresent() && info.arguments().isPresent()) {
|
||||
// If both, 'command' and 'arguments' are present,
|
||||
// 'commandLine' is just the concatenation of the two.
|
||||
Assert.assertTrue(info.commandLine().isPresent(),
|
||||
Assertions.assertTrue(info.commandLine().isPresent(),
|
||||
"commandLine() must be available");
|
||||
|
||||
String javaExe = System.getProperty("test.jdk") +
|
||||
@ -204,15 +193,15 @@ public class InfoTest {
|
||||
String commandLine = info.commandLine().get();
|
||||
String commandLineCmd = commandLine.split(" ")[0];
|
||||
Path commandLineCmdPath = Paths.get(commandLineCmd);
|
||||
Assert.assertTrue(Files.isSameFile(commandLineCmdPath, expectedPath),
|
||||
Assertions.assertTrue(Files.isSameFile(commandLineCmdPath, expectedPath),
|
||||
"commandLine() should start with: " + expectedPath +
|
||||
" but starts with " + commandLineCmdPath);
|
||||
|
||||
Assert.assertTrue(commandLine.contains(command.get()),
|
||||
Assertions.assertTrue(commandLine.contains(command.get()),
|
||||
"commandLine() must contain the command: " + command.get());
|
||||
List<String> allArgs = p1.getArgs();
|
||||
for (int i = 1; i < allArgs.size(); i++) {
|
||||
Assert.assertTrue(commandLine.contains(allArgs.get(i)),
|
||||
Assertions.assertTrue(commandLine.contains(allArgs.get(i)),
|
||||
"commandLine() must contain argument: " + allArgs.get(i));
|
||||
}
|
||||
} else if (info.commandLine().isPresent() &&
|
||||
@ -222,14 +211,14 @@ public class InfoTest {
|
||||
String commandLine = info.commandLine().get();
|
||||
String javaExe = "java" + (Platform.isWindows() ? ".exe" : "");
|
||||
int pos = commandLine.indexOf(javaExe);
|
||||
Assert.assertTrue(pos > 0, "commandLine() should at least contain 'java'");
|
||||
Assertions.assertTrue(pos > 0, "commandLine() should at least contain 'java'");
|
||||
|
||||
pos += javaExe.length() + 1; // +1 for the space after the command
|
||||
List<String> allArgs = p1.getArgs();
|
||||
// First argument is the command - skip it here as we've already checked that.
|
||||
for (int i = 1; (i < allArgs.size()) &&
|
||||
(pos + allArgs.get(i).length() < commandLine.length()); i++) {
|
||||
Assert.assertTrue(commandLine.contains(allArgs.get(i)),
|
||||
Assertions.assertTrue(commandLine.contains(allArgs.get(i)),
|
||||
"commandLine() must contain argument: " + allArgs.get(i));
|
||||
pos += allArgs.get(i).length() + 1;
|
||||
}
|
||||
@ -242,14 +231,14 @@ public class InfoTest {
|
||||
System.out.printf(" info.totalCPU: %s, childCpuTime: %s, diff: %s%n",
|
||||
totalCPU.toNanos(), childCpuTime.toNanos(),
|
||||
childCpuTime.toNanos() - totalCPU.toNanos());
|
||||
Assert.assertTrue(checkEpsilon(childCpuTime, totalCPU, epsilon),
|
||||
Assertions.assertTrue(checkEpsilon(childCpuTime, totalCPU, epsilon),
|
||||
childCpuTime + " should be within " +
|
||||
epsilon + " of " + totalCPU);
|
||||
}
|
||||
Assert.assertTrue(totalCPU.toNanos() > 0L,
|
||||
Assertions.assertTrue(totalCPU.toNanos() > 0L,
|
||||
"total cpu time expected > 0ms, actual: " + totalCPU);
|
||||
long t = Utils.adjustTimeout(10L); // Adjusted timeout seconds
|
||||
Assert.assertTrue(totalCPU.toNanos() < lastCpu.toNanos() + t * 1_000_000_000L,
|
||||
Assertions.assertTrue(totalCPU.toNanos() < lastCpu.toNanos() + t * 1_000_000_000L,
|
||||
"total cpu time expected < " + t
|
||||
+ " seconds more than previous iteration, actual: "
|
||||
+ (totalCPU.toNanos() - lastCpu.toNanos()));
|
||||
@ -258,18 +247,18 @@ public class InfoTest {
|
||||
|
||||
if (info.startInstant().isPresent()) {
|
||||
Instant startTime = info.startInstant().get();
|
||||
Assert.assertTrue(startTime.isBefore(afterStart),
|
||||
Assertions.assertTrue(startTime.isBefore(afterStart),
|
||||
"startTime after process spawn completed"
|
||||
+ startTime + " + > " + afterStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
p1.sendAction("exit");
|
||||
Assert.assertTrue(p1.waitFor(Utils.adjustTimeout(30L), TimeUnit.SECONDS),
|
||||
Assertions.assertTrue(p1.waitFor(Utils.adjustTimeout(30L), TimeUnit.SECONDS),
|
||||
"timeout waiting for process to terminate");
|
||||
} catch (IOException | InterruptedException ie) {
|
||||
ie.printStackTrace(System.out);
|
||||
Assert.fail("unexpected exception", ie);
|
||||
Assertions.fail("unexpected exception", ie);
|
||||
} finally {
|
||||
// Destroy any children that still exist
|
||||
ProcessUtil.destroyProcessTree(ProcessHandle.current());
|
||||
@ -280,7 +269,7 @@ public class InfoTest {
|
||||
* Spawn a child with arguments and check they are visible via the ProcessHandle.
|
||||
*/
|
||||
@Test
|
||||
public static void test3() {
|
||||
public void test3() {
|
||||
try {
|
||||
for (long sleepTime : Arrays.asList(Utils.adjustTimeout(30), Utils.adjustTimeout(32))) {
|
||||
Process p = spawn("sleep", String.valueOf(sleepTime));
|
||||
@ -302,22 +291,22 @@ public class InfoTest {
|
||||
Path executable = Files.readSymbolicLink(Paths.get("/bin/sleep"));
|
||||
expected = executable.getFileName().toString();
|
||||
}
|
||||
Assert.assertTrue(command.endsWith(expected), "Command: expected: \'" +
|
||||
Assertions.assertTrue(command.endsWith(expected), "Command: expected: \'" +
|
||||
expected + "\', actual: " + command);
|
||||
|
||||
// Verify the command exists and is executable
|
||||
File exe = new File(command);
|
||||
Assert.assertTrue(exe.exists(), "command must exist: " + exe);
|
||||
Assert.assertTrue(exe.canExecute(), "command must be executable: " + exe);
|
||||
Assertions.assertTrue(exe.exists(), "command must exist: " + exe);
|
||||
Assertions.assertTrue(exe.canExecute(), "command must be executable: " + exe);
|
||||
}
|
||||
if (info.arguments().isPresent()) {
|
||||
String[] args = info.arguments().get();
|
||||
if (args.length > 0) {
|
||||
Assert.assertEquals(args[0], String.valueOf(sleepTime));
|
||||
Assertions.assertEquals(String.valueOf(sleepTime), args[0]);
|
||||
}
|
||||
}
|
||||
p.destroy();
|
||||
Assert.assertTrue(p.waitFor(Utils.adjustTimeout(30), TimeUnit.SECONDS),
|
||||
Assertions.assertTrue(p.waitFor(Utils.adjustTimeout(30), TimeUnit.SECONDS),
|
||||
"timeout waiting for process to terminate");
|
||||
}
|
||||
} catch (IOException | InterruptedException ex) {
|
||||
@ -332,7 +321,7 @@ public class InfoTest {
|
||||
* Cross check the cputime reported from java.management with that for the current process.
|
||||
*/
|
||||
@Test
|
||||
public static void test4() {
|
||||
public void test4() {
|
||||
Duration myCputime1 = ProcessUtil.MXBeanCpuTime();
|
||||
|
||||
if (Platform.isAix()) {
|
||||
@ -367,26 +356,26 @@ public class InfoTest {
|
||||
Objects.toString(total2), myCputime2, myCputime2.minus(total2));
|
||||
|
||||
Duration epsilon = Duration.ofMillis(200L); // Epsilon is 200ms.
|
||||
Assert.assertTrue(checkEpsilon(myCputime1, myCputime2, epsilon),
|
||||
Assertions.assertTrue(checkEpsilon(myCputime1, myCputime2, epsilon),
|
||||
myCputime1.toNanos() + " should be within " + epsilon
|
||||
+ " of " + myCputime2.toNanos());
|
||||
Assert.assertTrue(checkEpsilon(total1, total2, epsilon),
|
||||
Assertions.assertTrue(checkEpsilon(total1, total2, epsilon),
|
||||
total1.toNanos() + " should be within " + epsilon
|
||||
+ " of " + total2.toNanos());
|
||||
Assert.assertTrue(checkEpsilon(myCputime1, total1, epsilon),
|
||||
Assertions.assertTrue(checkEpsilon(myCputime1, total1, epsilon),
|
||||
myCputime1.toNanos() + " should be within " + epsilon
|
||||
+ " of " + total1.toNanos());
|
||||
Assert.assertTrue(checkEpsilon(total1, myCputime2, epsilon),
|
||||
Assertions.assertTrue(checkEpsilon(total1, myCputime2, epsilon),
|
||||
total1.toNanos() + " should be within " + epsilon
|
||||
+ " of " + myCputime2.toNanos());
|
||||
Assert.assertTrue(checkEpsilon(myCputime2, total2, epsilon),
|
||||
Assertions.assertTrue(checkEpsilon(myCputime2, total2, epsilon),
|
||||
myCputime2.toNanos() + " should be within " + epsilon
|
||||
+ " of " + total2.toNanos());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public static void test5() {
|
||||
public void test5() {
|
||||
ProcessHandle self = ProcessHandle.current();
|
||||
Random r = new Random();
|
||||
for (int i = 0; i < 30; i++) {
|
||||
@ -458,13 +447,12 @@ public class InfoTest {
|
||||
return;
|
||||
}
|
||||
String user = info.user().get();
|
||||
Assert.assertNotNull(user, "User name");
|
||||
Assertions.assertNotNull(user, "User name");
|
||||
if (Platform.isWindows() && "BUILTIN\\Administrators".equals(whoami)) {
|
||||
int bsi = user.lastIndexOf("\\");
|
||||
Assert.assertEquals(bsi == -1 ? user : user.substring(bsi + 1),
|
||||
System.getProperty("user.name"), "User name");
|
||||
Assertions.assertEquals(System.getProperty("user.name"), bsi == -1 ? user : user.substring(bsi + 1), "User name");
|
||||
} else {
|
||||
Assert.assertEquals(user, whoami, "User name");
|
||||
Assertions.assertEquals(whoami, user, "User name");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2026, 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
|
||||
@ -35,37 +35,27 @@ import java.util.concurrent.TimeUnit;
|
||||
import jdk.test.lib.Platform;
|
||||
import jdk.test.lib.Utils;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import org.testng.Assert;
|
||||
import org.testng.TestNG;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Functions of Process.onExit and ProcessHandle.onExit
|
||||
* @bug 8333742
|
||||
* @requires vm.flagless
|
||||
* @library /test/lib
|
||||
* @modules jdk.management
|
||||
* @build jdk.test.lib.Utils
|
||||
* @run testng OnExitTest
|
||||
* @summary Functions of Process.onExit and ProcessHandle.onExit
|
||||
* @author Roger Riggs
|
||||
* @run junit OnExitTest
|
||||
*/
|
||||
|
||||
public class OnExitTest extends ProcessUtil {
|
||||
|
||||
@SuppressWarnings("raw_types")
|
||||
public static void main(String[] args) {
|
||||
Class<?>[] testclass = { OnExitTest.class};
|
||||
TestNG testng = new TestNG();
|
||||
testng.setTestClasses(testclass);
|
||||
testng.run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic test of exitValue and onExit.
|
||||
*/
|
||||
@Test
|
||||
public static void test1() {
|
||||
public void test1() {
|
||||
try {
|
||||
int[] exitValues = {0, 1, 10, 259};
|
||||
for (int value : exitValues) {
|
||||
@ -73,24 +63,24 @@ public class OnExitTest extends ProcessUtil {
|
||||
if (value == 259 && !Platform.isWindows()) continue;
|
||||
Process p = JavaChild.spawn("exit", Integer.toString(value));
|
||||
CompletableFuture<Process> future = p.onExit();
|
||||
future.thenAccept( (ph) -> {
|
||||
future.thenAccept((ph) -> {
|
||||
int actualExitValue = ph.exitValue();
|
||||
printf(" javaChild done: %s, exitStatus: %d%n",
|
||||
ph, actualExitValue);
|
||||
Assert.assertEquals(actualExitValue, value, "actualExitValue incorrect");
|
||||
Assert.assertEquals(ph, p, "Different Process passed to thenAccept");
|
||||
Assertions.assertEquals(value, actualExitValue, "actualExitValue incorrect");
|
||||
Assertions.assertEquals(p, ph, "Different Process passed to thenAccept");
|
||||
});
|
||||
|
||||
Process h = future.get();
|
||||
Assert.assertEquals(h, p);
|
||||
Assert.assertEquals(p.exitValue(), value);
|
||||
Assert.assertFalse(p.isAlive(), "Process should not be alive");
|
||||
Assert.assertEquals(p.waitFor(), value);
|
||||
Assert.assertTrue(p.waitFor(1, TimeUnit.MILLISECONDS),
|
||||
Assertions.assertEquals(p, h);
|
||||
Assertions.assertEquals(value, p.exitValue());
|
||||
Assertions.assertFalse(p.isAlive(), "Process should not be alive");
|
||||
Assertions.assertEquals(value, p.waitFor());
|
||||
Assertions.assertTrue(p.waitFor(1, TimeUnit.MILLISECONDS),
|
||||
"waitFor should return true");
|
||||
}
|
||||
} catch (IOException | InterruptedException | ExecutionException ex) {
|
||||
Assert.fail(ex.getMessage(), ex);
|
||||
Assertions.fail(ex.getMessage(), ex);
|
||||
} finally {
|
||||
destroyProcessTree(ProcessHandle.current());
|
||||
}
|
||||
@ -101,7 +91,7 @@ public class OnExitTest extends ProcessUtil {
|
||||
* Spawn 1 child to spawn 3 children each with 2 children.
|
||||
*/
|
||||
@Test
|
||||
public static void test2() {
|
||||
public void test2() {
|
||||
|
||||
// Please note (JDK-8284282):
|
||||
//
|
||||
@ -176,7 +166,7 @@ public class OnExitTest extends ProcessUtil {
|
||||
// Check that each of the spawned processes is included in the children
|
||||
List<ProcessHandle> remaining = new ArrayList<>(children);
|
||||
processes.forEach((p, parent) -> {
|
||||
Assert.assertTrue(remaining.remove(p), "spawned process should have been in children");
|
||||
Assertions.assertTrue(remaining.remove(p), "spawned process should have been in children");
|
||||
});
|
||||
|
||||
// Remove Win32 system spawned conhost.exe processes
|
||||
@ -204,7 +194,7 @@ public class OnExitTest extends ProcessUtil {
|
||||
// Verify that all 9 exit handlers were called with the correct ProcessHandle
|
||||
processes.forEach((p, parent) -> {
|
||||
ProcessHandle value = completions.get(p).getNow(null);
|
||||
Assert.assertEquals(p, value, "onExit.get value expected: " + p
|
||||
Assertions.assertEquals(value, p, "onExit.get value expected: " + p
|
||||
+ ", actual: " + value
|
||||
+ ": " + p.info());
|
||||
});
|
||||
@ -212,9 +202,9 @@ public class OnExitTest extends ProcessUtil {
|
||||
// Show the status of the original children
|
||||
children.forEach(p -> printProcess(p, "after onExit:"));
|
||||
|
||||
Assert.assertEquals(proc.isAlive(), false, "destroyed process is alive:: %s%n" + proc);
|
||||
Assertions.assertFalse(proc.isAlive(), "destroyed process is alive:: %s%n" + proc);
|
||||
} catch (IOException | InterruptedException ex) {
|
||||
Assert.fail(ex.getMessage());
|
||||
Assertions.fail(ex.getMessage(), ex);
|
||||
} finally {
|
||||
if (procHandle != null) {
|
||||
destroyProcessTree(procHandle);
|
||||
@ -231,7 +221,7 @@ public class OnExitTest extends ProcessUtil {
|
||||
* Check that (B) does not complete until (A) has exited.
|
||||
*/
|
||||
@Test
|
||||
public static void peerOnExitTest() {
|
||||
public void peerOnExitTest() {
|
||||
String line = null;
|
||||
ArrayBlockingQueue<String> alines = new ArrayBlockingQueue<>(100);
|
||||
ArrayBlockingQueue<String> blines = new ArrayBlockingQueue<>(100);
|
||||
@ -265,9 +255,9 @@ public class OnExitTest extends ProcessUtil {
|
||||
try {
|
||||
line = blines.poll(5L, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException ie) {
|
||||
Assert.fail("interrupted", ie);
|
||||
Assertions.fail("interrupted", ie);
|
||||
}
|
||||
Assert.assertNull(line, "waitpid didn't wait");
|
||||
Assertions.assertNull(line, "waitpid didn't wait");
|
||||
|
||||
A.toHandle().onExit().thenAccept(p -> {
|
||||
System.out.printf(" A.toHandle().onExit().A info: %s, now: %s%n",
|
||||
@ -296,16 +286,16 @@ public class OnExitTest extends ProcessUtil {
|
||||
split = getSplitLine(blines);
|
||||
} while (!"waitpid".equals(split[1]));
|
||||
|
||||
Assert.assertEquals(split[2], "false", "Process A should not be alive");
|
||||
Assertions.assertEquals("false", split[2], "Process A should not be alive");
|
||||
|
||||
B.sendAction("exit", 0L);
|
||||
} catch (IOException ioe) {
|
||||
Assert.fail("unable to start JavaChild B", ioe);
|
||||
Assertions.fail("unable to start JavaChild B", ioe);
|
||||
} finally {
|
||||
B.destroyForcibly();
|
||||
}
|
||||
} catch (IOException ioe2) {
|
||||
Assert.fail("unable to start JavaChild A", ioe2);
|
||||
Assertions.fail("unable to start JavaChild A", ioe2);
|
||||
} finally {
|
||||
A.destroyForcibly();
|
||||
}
|
||||
@ -328,7 +318,7 @@ public class OnExitTest extends ProcessUtil {
|
||||
}
|
||||
return split;
|
||||
} catch (InterruptedException ie) {
|
||||
Assert.fail("interrupted", ie);
|
||||
Assertions.fail("interrupted", ie);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2026, 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
|
||||
@ -38,12 +38,12 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.test.lib.Utils;
|
||||
import org.testng.Assert;
|
||||
import org.testng.TestNG;
|
||||
import org.testng.annotations.Test;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Test counting and JavaChild.spawning and counting of Processes.
|
||||
* @requires vm.flagless
|
||||
* @library /test/lib
|
||||
* @modules java.base/jdk.internal.misc
|
||||
@ -54,25 +54,15 @@ import org.testng.annotations.Test;
|
||||
* jdk.test.lib.JDKToolLauncher
|
||||
* jdk.test.lib.Platform
|
||||
* jdk.test.lib.process.*
|
||||
* @run testng/othervm TreeTest
|
||||
* @summary Test counting and JavaChild.spawning and counting of Processes.
|
||||
* @run junit/othervm TreeTest
|
||||
* @author Roger Riggs
|
||||
*/
|
||||
public class TreeTest extends ProcessUtil {
|
||||
// Main can be used to run the tests from the command line with only testng.jar.
|
||||
@SuppressWarnings("raw_types")
|
||||
public static void main(String[] args) {
|
||||
Class<?>[] testclass = {TreeTest.class};
|
||||
TestNG testng = new TestNG();
|
||||
testng.setTestClasses(testclass);
|
||||
testng.run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test counting and spawning and counting of Processes.
|
||||
*/
|
||||
@Test
|
||||
public static void test1() {
|
||||
public void test1() {
|
||||
final int MAXCHILDREN = 2;
|
||||
List<JavaChild> spawned = new ArrayList<>();
|
||||
|
||||
@ -92,14 +82,14 @@ public class TreeTest extends ProcessUtil {
|
||||
spawned.stream()
|
||||
.map(Process::toHandle)
|
||||
.filter(p -> !initialChildren.contains(p))
|
||||
.forEach(p -> Assert.fail("Spawned process missing from children: " + p));
|
||||
.forEach(p -> Assertions.fail("Spawned process missing from children: " + p));
|
||||
|
||||
// Send exit command to each spawned Process
|
||||
spawned.forEach(p -> {
|
||||
try {
|
||||
p.sendAction("exit", "");
|
||||
} catch (IOException ex) {
|
||||
Assert.fail("IOException in sendAction", ex);
|
||||
Assertions.fail("IOException in sendAction", ex);
|
||||
}
|
||||
});
|
||||
|
||||
@ -107,7 +97,7 @@ public class TreeTest extends ProcessUtil {
|
||||
spawned.forEach(p -> {
|
||||
do {
|
||||
try {
|
||||
Assert.assertEquals(p.waitFor(), 0, "exit status incorrect");
|
||||
Assertions.assertEquals(0, p.waitFor(), "exit status incorrect");
|
||||
break;
|
||||
} catch (InterruptedException ex) {
|
||||
continue; // Retry
|
||||
@ -118,7 +108,7 @@ public class TreeTest extends ProcessUtil {
|
||||
// Verify that ProcessHandle.isAlive sees each of them as not alive
|
||||
for (Process p : spawned) {
|
||||
ProcessHandle ph = p.toHandle();
|
||||
Assert.assertFalse(ph.isAlive(),
|
||||
Assertions.assertFalse(ph.isAlive(),
|
||||
"ProcessHandle.isAlive for exited process: " + ph);
|
||||
}
|
||||
|
||||
@ -126,13 +116,13 @@ public class TreeTest extends ProcessUtil {
|
||||
final List<ProcessHandle> afterChildren = getChildren(self);
|
||||
spawned.stream()
|
||||
.map(Process::toHandle)
|
||||
.filter(p -> afterChildren.contains(p))
|
||||
.forEach(p -> Assert.fail("Spawned process missing from children: " + p));
|
||||
.filter(afterChildren::contains)
|
||||
.forEach(p -> Assertions.fail("Spawned process missing from children: " + p));
|
||||
|
||||
} catch (IOException ioe) {
|
||||
Assert.fail("unable to spawn process", ioe);
|
||||
Assertions.fail("unable to spawn process", ioe);
|
||||
} finally {
|
||||
// Cleanup any left over processes
|
||||
// Cleanup any leftover processes
|
||||
spawned.stream()
|
||||
.map(Process::toHandle)
|
||||
.filter(ProcessHandle::isAlive)
|
||||
@ -147,7 +137,7 @@ public class TreeTest extends ProcessUtil {
|
||||
* Test counting and spawning and counting of Processes.
|
||||
*/
|
||||
@Test
|
||||
public static void test2() {
|
||||
public void test2() {
|
||||
try {
|
||||
ConcurrentHashMap<ProcessHandle, ProcessHandle> processes = new ConcurrentHashMap<>();
|
||||
|
||||
@ -162,12 +152,12 @@ public class TreeTest extends ProcessUtil {
|
||||
ProcessHandle p1Handle = p1.toHandle();
|
||||
printf(" p1 pid: %d%n", p1.pid());
|
||||
|
||||
// Gather the PIDs from the output of the spawing process
|
||||
// Gather the PIDs from the output of the spawning process
|
||||
p1.forEachOutputLine((s) -> {
|
||||
String[] split = s.trim().split(" ");
|
||||
if (split.length == 3 && split[1].equals("spawn")) {
|
||||
Long child = Long.valueOf(split[2]);
|
||||
Long parent = Long.valueOf(split[0].split(":")[0]);
|
||||
long child = Long.parseLong(split[2]);
|
||||
long parent = Long.parseLong(split[0].split(":")[0]);
|
||||
processes.put(ProcessHandle.of(child).get(), ProcessHandle.of(parent).get());
|
||||
}
|
||||
});
|
||||
@ -179,11 +169,11 @@ public class TreeTest extends ProcessUtil {
|
||||
List<ProcessHandle> subprocesses = waitForAllChildren(p1Handle, spawnNew);
|
||||
Optional<Instant> p1Start = p1Handle.info().startInstant();
|
||||
for (ProcessHandle ph : subprocesses) {
|
||||
Assert.assertTrue(ph.isAlive(), "Child should be alive: " + ph);
|
||||
Assertions.assertTrue(ph.isAlive(), "Child should be alive: " + ph);
|
||||
// Verify each child was started after the parent
|
||||
ph.info().startInstant()
|
||||
.ifPresent(childStart -> p1Start.ifPresent(parentStart -> {
|
||||
Assert.assertFalse(childStart.isBefore(parentStart),
|
||||
Assertions.assertFalse(childStart.isBefore(parentStart),
|
||||
String.format("Child process started before parent: child: %s, parent: %s",
|
||||
childStart, parentStart));
|
||||
}));
|
||||
@ -217,8 +207,8 @@ public class TreeTest extends ProcessUtil {
|
||||
|
||||
// Verify that all spawned children show up in the descendants List
|
||||
processes.forEach((p, parent) -> {
|
||||
Assert.assertEquals(p.isAlive(), true, "Child should be alive: " + p);
|
||||
Assert.assertTrue(descendants.contains(p), "Spawned child should be listed in descendants: " + p);
|
||||
Assertions.assertTrue(p.isAlive(), "Child should be alive: " + p);
|
||||
Assertions.assertTrue(descendants.contains(p), "Spawned child should be listed in descendants: " + p);
|
||||
});
|
||||
|
||||
// Closing JavaChild's InputStream will cause all children to exit
|
||||
@ -228,13 +218,13 @@ public class TreeTest extends ProcessUtil {
|
||||
try {
|
||||
p.onExit().get(); // wait for the child to exit
|
||||
} catch (ExecutionException e) {
|
||||
Assert.fail("waiting for process to exit", e);
|
||||
Assertions.fail("waiting for process to exit", e);
|
||||
}
|
||||
}
|
||||
p1.waitFor(); // wait for spawned process to exit
|
||||
|
||||
// Verify spawned processes are no longer alive
|
||||
processes.forEach((ph, parent) -> Assert.assertFalse(ph.isAlive(),
|
||||
processes.forEach((ph, parent) -> Assertions.assertFalse(ph.isAlive(),
|
||||
"process should not be alive: " + ph));
|
||||
} catch (IOException | InterruptedException t) {
|
||||
t.printStackTrace();
|
||||
@ -250,7 +240,7 @@ public class TreeTest extends ProcessUtil {
|
||||
* After they exit they should no longer be listed by descendants.
|
||||
*/
|
||||
@Test
|
||||
public static void test3() {
|
||||
public void test3() {
|
||||
ConcurrentHashMap<ProcessHandle, ProcessHandle> processes = new ConcurrentHashMap<>();
|
||||
|
||||
try {
|
||||
@ -269,15 +259,15 @@ public class TreeTest extends ProcessUtil {
|
||||
p1.forEachOutputLine((s) -> {
|
||||
String[] split = s.trim().split(" ");
|
||||
if (split.length == 3 && split[1].equals("spawn")) {
|
||||
Long child = Long.valueOf(split[2]);
|
||||
Long parent = Long.valueOf(split[0].split(":")[0]);
|
||||
long child = Long.parseLong(split[2]);
|
||||
long parent = Long.parseLong(split[0].split(":")[0]);
|
||||
processes.put(ProcessHandle.of(child).get(), ProcessHandle.of(parent).get());
|
||||
spawnCount.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
// Wait for all the subprocesses to be listed as started
|
||||
Assert.assertTrue(spawnCount.await(Utils.adjustTimeout(30L), TimeUnit.SECONDS),
|
||||
Assertions.assertTrue(spawnCount.await(Utils.adjustTimeout(30L), TimeUnit.SECONDS),
|
||||
"Timeout waiting for processes to start");
|
||||
|
||||
// Debugging; list descendants that are not expected in processes
|
||||
@ -290,17 +280,17 @@ public class TreeTest extends ProcessUtil {
|
||||
.filter(ph -> !processes.containsKey(ph))
|
||||
.forEach(ph1 -> ProcessUtil.printProcess(ph1, "Extra process: "));
|
||||
ProcessUtil.logTaskList();
|
||||
Assert.assertEquals(0, count, "Extra processes in descendants");
|
||||
Assertions.assertEquals(0, count, "Extra processes in descendants");
|
||||
}
|
||||
|
||||
// Verify that all spawned children are alive, show up in the descendants list
|
||||
// then destroy them
|
||||
processes.forEach((p, parent) -> {
|
||||
Assert.assertEquals(p.isAlive(), true, "Child should be alive: " + p);
|
||||
Assert.assertTrue(descendants.contains(p), "Spawned child should be listed in descendants: " + p);
|
||||
Assertions.assertTrue(p.isAlive(), "Child should be alive: " + p);
|
||||
Assertions.assertTrue(descendants.contains(p), "Spawned child should be listed in descendants: " + p);
|
||||
p.destroyForcibly();
|
||||
});
|
||||
Assert.assertEquals(processes.size(), newChildren, "Wrong number of children");
|
||||
Assertions.assertEquals(newChildren, processes.size(), "Wrong number of children");
|
||||
|
||||
// Wait for each of the processes to exit
|
||||
processes.forEach((p, parent) -> {
|
||||
@ -317,21 +307,21 @@ public class TreeTest extends ProcessUtil {
|
||||
}
|
||||
printf("Timeout waiting for exit of pid %s, parent: %s, info: %s%n",
|
||||
p, parent, p.info());
|
||||
Assert.fail("Process still alive: " + p);
|
||||
Assertions.fail("Process still alive: " + p);
|
||||
});
|
||||
p1.destroyForcibly();
|
||||
p1.waitFor();
|
||||
|
||||
// Verify that none of the spawned children are still listed by descendants
|
||||
List<ProcessHandle> remaining = getDescendants(self);
|
||||
Assert.assertFalse(remaining.remove(p1Handle), "Child p1 should have exited");
|
||||
Assertions.assertFalse(remaining.remove(p1Handle), "Child p1 should have exited");
|
||||
remaining = remaining.stream().filter(processes::containsKey).collect(Collectors.toList());
|
||||
Assert.assertEquals(remaining.size(), 0, "Subprocess(es) should have exited: " + remaining);
|
||||
Assertions.assertEquals(0, remaining.size(), "Subprocess(es) should have exited: " + remaining);
|
||||
|
||||
} catch (IOException ioe) {
|
||||
Assert.fail("Spawn of subprocess failed", ioe);
|
||||
Assertions.fail("Spawn of subprocess failed", ioe);
|
||||
} catch (InterruptedException inte) {
|
||||
Assert.fail("InterruptedException", inte);
|
||||
Assertions.fail("InterruptedException", inte);
|
||||
} finally {
|
||||
processes.forEach((p, parent) -> {
|
||||
if (p.isAlive()) {
|
||||
@ -346,7 +336,7 @@ public class TreeTest extends ProcessUtil {
|
||||
* Test (Not really a test) that dumps the list of all Processes.
|
||||
*/
|
||||
@Test
|
||||
public static void test4() {
|
||||
public void test4() {
|
||||
printf(" Parent Child Info%n");
|
||||
Stream<ProcessHandle> s = ProcessHandle.allProcesses();
|
||||
ProcessHandle[] processes = s.toArray(ProcessHandle[]::new);
|
||||
@ -384,7 +374,7 @@ public class TreeTest extends ProcessUtil {
|
||||
}
|
||||
printf("%s %7s, %7s, %s%n", indent, p_parent, p, info);
|
||||
}
|
||||
Assert.assertFalse(fail, "Parents missing from all Processes");
|
||||
Assertions.assertFalse(fail, "Parents missing from all Processes");
|
||||
|
||||
}
|
||||
|
||||
@ -392,7 +382,7 @@ public class TreeTest extends ProcessUtil {
|
||||
* A test for scale; launch a large number (14) of subprocesses.
|
||||
*/
|
||||
@Test
|
||||
public static void test5() {
|
||||
public void test5() {
|
||||
ConcurrentHashMap<ProcessHandle, ProcessHandle> processes = new ConcurrentHashMap<>();
|
||||
|
||||
int factor = 2;
|
||||
@ -421,15 +411,15 @@ public class TreeTest extends ProcessUtil {
|
||||
p1.forEachOutputLine((s) -> {
|
||||
String[] split = s.trim().split(" ");
|
||||
if (split.length == 3 && split[1].equals("spawn")) {
|
||||
Long child = Long.valueOf(split[2]);
|
||||
Long parent = Long.valueOf(split[0].split(":")[0]);
|
||||
long child = Long.parseLong(split[2]);
|
||||
long parent = Long.parseLong(split[0].split(":")[0]);
|
||||
processes.put(ProcessHandle.of(child).get(), ProcessHandle.of(parent).get());
|
||||
spawnCount.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
// Wait for all the subprocesses to be listed as started
|
||||
Assert.assertTrue(spawnCount.await(Utils.adjustTimeout(30L), TimeUnit.SECONDS),
|
||||
Assertions.assertTrue(spawnCount.await(Utils.adjustTimeout(30L), TimeUnit.SECONDS),
|
||||
"Timeout waiting for processes to start");
|
||||
|
||||
// Debugging; list descendants that are not expected in processes
|
||||
@ -442,30 +432,29 @@ public class TreeTest extends ProcessUtil {
|
||||
.filter(ph -> !processes.containsKey(ph))
|
||||
.forEach(ph1 -> ProcessUtil.printProcess(ph1, "Extra process: "));
|
||||
ProcessUtil.logTaskList();
|
||||
Assert.assertEquals(0, count, "Extra processes in descendants");
|
||||
Assertions.assertEquals(0, count, "Extra processes in descendants");
|
||||
}
|
||||
|
||||
List<ProcessHandle> subprocesses = getChildren(p1Handle);
|
||||
printf(" children: %s%n",
|
||||
subprocesses.stream().map(p -> p.pid())
|
||||
subprocesses.stream().map(ProcessHandle::pid)
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
Assert.assertEquals(getChildren(p1Handle).size(),
|
||||
factor, "expected direct children");
|
||||
Assertions.assertEquals(factor, getChildren(p1Handle).size(), "expected direct children");
|
||||
count = getDescendants(p1Handle).size();
|
||||
long totalChildren = factor * factor * factor + factor * factor + factor;
|
||||
Assert.assertTrue(count >= totalChildren,
|
||||
Assertions.assertTrue(count >= totalChildren,
|
||||
"expected at least " + totalChildren + ", actual: " + count);
|
||||
|
||||
List<ProcessHandle> descSubprocesses = getDescendants(p1Handle);
|
||||
printf(" descendants: %s%n",
|
||||
descSubprocesses.stream().map(p -> p.pid())
|
||||
descSubprocesses.stream().map(ProcessHandle::pid)
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
p1.getOutputStream().close(); // Close stdin for the controlling p1
|
||||
p1.waitFor();
|
||||
} catch (InterruptedException | IOException ex) {
|
||||
Assert.fail("Unexpected Exception", ex);
|
||||
Assertions.fail("Unexpected Exception", ex);
|
||||
} finally {
|
||||
printf("Duration: %s%n", Duration.between(start, Instant.now()));
|
||||
if (p1 != null) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user