mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
8375050: Simplify process management in jpackage tests
Reviewed-by: almatvee
This commit is contained in:
parent
f7be1dcf29
commit
47029ccfec
@ -35,6 +35,7 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.spi.ToolProvider;
|
||||
import java.util.stream.IntStream;
|
||||
@ -109,15 +110,6 @@ public final class Executor extends CommandArguments<Executor> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Executor setWinRunWithEnglishOutput(boolean value) {
|
||||
if (!TKit.isWindows()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"setWinRunWithEnglishOutput is only valid on Windows platform");
|
||||
}
|
||||
winEnglishOutput = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Executor setWindowsTmpDir(String tmp) {
|
||||
if (!TKit.isWindows()) {
|
||||
throw new UnsupportedOperationException(
|
||||
@ -195,6 +187,11 @@ public final class Executor extends CommandArguments<Executor> {
|
||||
return storeOutputInFiles(true);
|
||||
}
|
||||
|
||||
public Executor processListener(Consumer<Process> v) {
|
||||
commandOutputControl.processListener(v);
|
||||
return this;
|
||||
}
|
||||
|
||||
public record Result(CommandOutputControl.Result base) {
|
||||
public Result {
|
||||
Objects.requireNonNull(base);
|
||||
@ -310,11 +307,6 @@ public final class Executor extends CommandArguments<Executor> {
|
||||
"Can't change directory when using tool provider");
|
||||
}
|
||||
|
||||
if (toolProvider != null && winEnglishOutput) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't change locale when using tool provider");
|
||||
}
|
||||
|
||||
return ThrowingSupplier.toSupplier(() -> {
|
||||
if (toolProvider != null) {
|
||||
return runToolProvider();
|
||||
@ -434,17 +426,8 @@ public final class Executor extends CommandArguments<Executor> {
|
||||
return executable.toAbsolutePath();
|
||||
}
|
||||
|
||||
private List<String> prefixCommandLineArgs() {
|
||||
if (winEnglishOutput) {
|
||||
return List.of("cmd.exe", "/c", "chcp", "437", ">nul", "2>&1", "&&");
|
||||
} else {
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
|
||||
private Result runExecutable() throws IOException, InterruptedException {
|
||||
List<String> command = new ArrayList<>();
|
||||
command.addAll(prefixCommandLineArgs());
|
||||
command.add(executablePath().toString());
|
||||
command.addAll(args);
|
||||
ProcessBuilder builder = new ProcessBuilder(command);
|
||||
@ -522,8 +505,7 @@ public final class Executor extends CommandArguments<Executor> {
|
||||
exec = executablePath().toString();
|
||||
}
|
||||
|
||||
var cmdline = Stream.of(prefixCommandLineArgs(), List.of(exec), args).flatMap(
|
||||
List::stream).toList();
|
||||
var cmdline = Stream.of(List.of(exec), args).flatMap(List::stream).toList();
|
||||
|
||||
return String.format(format, CommandLineFormat.DEFAULT.apply(cmdline), cmdline.size());
|
||||
}
|
||||
@ -559,6 +541,5 @@ public final class Executor extends CommandArguments<Executor> {
|
||||
private Path directory;
|
||||
private Set<String> removeEnvVars = new HashSet<>();
|
||||
private Map<String, String> setEnvVars = new HashMap<>();
|
||||
private boolean winEnglishOutput;
|
||||
private String winTmpDir = null;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 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,6 +35,7 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.regex.Matcher;
|
||||
@ -315,37 +316,33 @@ public final class HelloApp {
|
||||
|
||||
public static void executeLauncherAndVerifyOutput(JPackageCommand cmd,
|
||||
String... args) {
|
||||
AppOutputVerifier av = assertMainLauncher(cmd, args);
|
||||
if (av != null) {
|
||||
assertMainLauncher(cmd, args).ifPresent(av -> {
|
||||
av.executeAndVerifyOutput(args);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Executor.Result executeLauncher(JPackageCommand cmd,
|
||||
String... args) {
|
||||
AppOutputVerifier av = assertMainLauncher(cmd, args);
|
||||
if (av != null) {
|
||||
return assertMainLauncher(cmd, args).map(av -> {
|
||||
return av.saveOutput(true).execute(args);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}).orElseThrow();
|
||||
}
|
||||
|
||||
public static AppOutputVerifier assertMainLauncher(JPackageCommand cmd,
|
||||
public static Optional<AppOutputVerifier> assertMainLauncher(JPackageCommand cmd,
|
||||
String... args) {
|
||||
final Path launcherPath = cmd.appLauncherPath();
|
||||
if (!cmd.canRunLauncher(String.format("Not running [%s] launcher",
|
||||
launcherPath))) {
|
||||
return null;
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return assertApp(launcherPath)
|
||||
return Optional.of(assertApp(launcherPath)
|
||||
.addDefaultArguments(Optional
|
||||
.ofNullable(cmd.getAllArgumentValues("--arguments"))
|
||||
.orElseGet(() -> new String[0]))
|
||||
.addJavaOptions(Optional
|
||||
.ofNullable(cmd.getAllArgumentValues("--java-options"))
|
||||
.orElseGet(() -> new String[0]));
|
||||
.orElseGet(() -> new String[0])));
|
||||
}
|
||||
|
||||
|
||||
@ -426,6 +423,11 @@ public final class HelloApp {
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public AppOutputVerifier processListener(Consumer<Process> v) {
|
||||
processListener = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void verifyOutput(String... args) {
|
||||
final List<String> launcherArgs = List.of(args);
|
||||
final List<String> appArgs;
|
||||
@ -479,6 +481,7 @@ public final class HelloApp {
|
||||
.saveOutput(saveOutput)
|
||||
.dumpOutput()
|
||||
.setExecutable(executablePath)
|
||||
.processListener(processListener)
|
||||
.addArguments(List.of(args));
|
||||
|
||||
env.forEach((envVarName, envVarValue) -> {
|
||||
@ -493,6 +496,7 @@ public final class HelloApp {
|
||||
private final Path launcherPath;
|
||||
private Path outputFilePath;
|
||||
private int expectedExitCode;
|
||||
private Consumer<Process> processListener;
|
||||
private final List<String> defaultLauncherArgs;
|
||||
private final Map<String, String> params;
|
||||
private final Map<String, String> env;
|
||||
|
||||
@ -42,8 +42,6 @@ import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
import jdk.jpackage.internal.util.function.ThrowingRunnable;
|
||||
import jdk.jpackage.test.PackageTest.PackageHandlers;
|
||||
@ -306,91 +304,6 @@ public class WindowsHelper {
|
||||
"Failed to get file description of [%s]", pathToExeFile));
|
||||
}
|
||||
|
||||
public static void killProcess(long pid) {
|
||||
Executor.of("taskkill", "/F", "/PID", Long.toString(pid)).dumpOutput(true).execute();
|
||||
}
|
||||
|
||||
public static void killAppLauncherProcess(JPackageCommand cmd,
|
||||
String launcherName, int expectedCount) {
|
||||
var pids = findAppLauncherPIDs(cmd, launcherName);
|
||||
try {
|
||||
TKit.assertEquals(expectedCount, pids.length, String.format(
|
||||
"Check [%d] %s app launcher processes found running",
|
||||
expectedCount, Optional.ofNullable(launcherName).map(
|
||||
str -> "[" + str + "]").orElse("<main>")));
|
||||
} finally {
|
||||
if (pids.length != 0) {
|
||||
killProcess(pids[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static long[] findAppLauncherPIDs(JPackageCommand cmd, String launcherName) {
|
||||
// Get the list of PIDs and PPIDs of app launcher processes. Run setWinRunWithEnglishOutput(true) for JDK-8344275.
|
||||
// powershell -NoLogo -NoProfile -NonInteractive -Command
|
||||
// "Get-CimInstance Win32_Process -Filter \"Name = 'foo.exe'\" | select ProcessID,ParentProcessID"
|
||||
String command = "Get-CimInstance Win32_Process -Filter \\\"Name = '"
|
||||
+ cmd.appLauncherPath(launcherName).getFileName().toString()
|
||||
+ "'\\\" | select ProcessID,ParentProcessID";
|
||||
List<String> output = Executor.of("powershell", "-NoLogo", "-NoProfile", "-NonInteractive", "-Command", command)
|
||||
.dumpOutput(true).saveOutput().setWinRunWithEnglishOutput(true).executeAndGetOutput();
|
||||
|
||||
if (output.size() < 1) {
|
||||
return new long[0];
|
||||
}
|
||||
|
||||
String[] headers = Stream.of(output.get(1).split("\\s+", 2)).map(
|
||||
String::trim).map(String::toLowerCase).toArray(String[]::new);
|
||||
Pattern pattern;
|
||||
if (headers[0].equals("parentprocessid") && headers[1].equals(
|
||||
"processid")) {
|
||||
pattern = Pattern.compile("^\\s+(?<ppid>\\d+)\\s+(?<pid>\\d+)$");
|
||||
} else if (headers[1].equals("parentprocessid") && headers[0].equals(
|
||||
"processid")) {
|
||||
pattern = Pattern.compile("^\\s+(?<pid>\\d+)\\s+(?<ppid>\\d+)$");
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"Unrecognizable output of \'Get-CimInstance Win32_Process\' command");
|
||||
}
|
||||
|
||||
List<long[]> processes = output.stream().skip(3).map(line -> {
|
||||
Matcher m = pattern.matcher(line);
|
||||
long[] pids = null;
|
||||
if (m.matches()) {
|
||||
pids = new long[]{Long.parseLong(m.group("pid")), Long.
|
||||
parseLong(m.group("ppid"))};
|
||||
}
|
||||
return pids;
|
||||
}).filter(Objects::nonNull).toList();
|
||||
|
||||
switch (processes.size()) {
|
||||
case 2 -> {
|
||||
final long parentPID;
|
||||
final long childPID;
|
||||
if (processes.get(0)[0] == processes.get(1)[1]) {
|
||||
parentPID = processes.get(0)[0];
|
||||
childPID = processes.get(1)[0];
|
||||
} else if (processes.get(1)[0] == processes.get(0)[1]) {
|
||||
parentPID = processes.get(1)[0];
|
||||
childPID = processes.get(0)[0];
|
||||
} else {
|
||||
TKit.assertUnexpected("App launcher processes unrelated");
|
||||
return null; // Unreachable
|
||||
}
|
||||
return new long[]{parentPID, childPID};
|
||||
}
|
||||
case 1 -> {
|
||||
return new long[]{processes.get(0)[0]};
|
||||
}
|
||||
default -> {
|
||||
TKit.assertUnexpected(String.format(
|
||||
"Unexpected number of running processes [%d]",
|
||||
processes.size()));
|
||||
return null; // Unreachable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isUserLocalInstall(JPackageCommand cmd) {
|
||||
return cmd.hasArgument("--win-per-user-install");
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2025, 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
|
||||
@ -49,11 +49,10 @@ public class ArgumentsFilteringTest {
|
||||
public void test1() {
|
||||
JPackageCommand cmd = JPackageCommand.helloAppImage();
|
||||
cmd.executeAndAssertHelloAppImageCreated();
|
||||
var appVerifier = HelloApp.assertMainLauncher(cmd);
|
||||
if (appVerifier != null) {
|
||||
HelloApp.assertMainLauncher(cmd).ifPresent(appVerifier -> {
|
||||
appVerifier.execute("-psn_1_1");
|
||||
appVerifier.verifyOutput();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -61,10 +60,9 @@ public class ArgumentsFilteringTest {
|
||||
JPackageCommand cmd = JPackageCommand.helloAppImage()
|
||||
.addArguments("--arguments", "-psn_2_2");
|
||||
cmd.executeAndAssertHelloAppImageCreated();
|
||||
var appVerifier = HelloApp.assertMainLauncher(cmd);
|
||||
if (appVerifier != null) {
|
||||
HelloApp.assertMainLauncher(cmd).ifPresent(appVerifier -> {
|
||||
appVerifier.execute("-psn_1_1");
|
||||
appVerifier.verifyOutput("-psn_2_2");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 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
|
||||
@ -240,8 +240,7 @@ public final class MainClassTest {
|
||||
cmd.executeAndAssertHelloAppImageCreated();
|
||||
} else {
|
||||
cmd.executeAndAssertImageCreated();
|
||||
var appVerifier = HelloApp.assertMainLauncher(cmd);
|
||||
if (appVerifier != null) {
|
||||
HelloApp.assertMainLauncher(cmd).ifPresent(appVerifier -> {
|
||||
List<String> output = appVerifier
|
||||
.saveOutput(true)
|
||||
.expectedExitCode(1)
|
||||
@ -249,7 +248,7 @@ public final class MainClassTest {
|
||||
TKit.assertTextStream(String.format(
|
||||
"Error: Could not find or load main class %s",
|
||||
nonExistingMainClass)).apply(output);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CfgFile cfg = cmd.readLauncherCfgFile();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 2025, 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
|
||||
@ -21,12 +21,14 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import static jdk.jpackage.test.WindowsHelper.killAppLauncherProcess;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.HelloApp;
|
||||
import jdk.jpackage.test.JPackageCommand;
|
||||
import jdk.jpackage.test.TKit;
|
||||
|
||||
/**
|
||||
* Test that terminating of the parent app launcher process automatically
|
||||
@ -46,7 +48,7 @@ import jdk.jpackage.test.JPackageCommand;
|
||||
public class Win8301247Test {
|
||||
|
||||
@Test
|
||||
public void test() throws InterruptedException {
|
||||
public void test() throws InterruptedException, ExecutionException {
|
||||
var cmd = JPackageCommand.helloAppImage().ignoreFakeRuntime();
|
||||
|
||||
// Launch the app in a way it doesn't exit to let us trap app laucnher
|
||||
@ -54,20 +56,41 @@ public class Win8301247Test {
|
||||
cmd.addArguments("--java-options", "-Djpackage.test.noexit=true");
|
||||
cmd.executeAndAssertImageCreated();
|
||||
|
||||
var f = new CompletableFuture<Process>();
|
||||
|
||||
// Launch the app in a separate thread
|
||||
new Thread(() -> {
|
||||
HelloApp.executeLauncher(cmd);
|
||||
HelloApp.assertMainLauncher(cmd).get().processListener(f::complete).execute();
|
||||
}).start();
|
||||
|
||||
// Wait a bit to let the app start
|
||||
Thread.sleep(Duration.ofSeconds(10));
|
||||
var mainLauncherProcess = f.get();
|
||||
|
||||
// Find the main app launcher process and kill it
|
||||
killAppLauncherProcess(cmd, null, 2);
|
||||
Optional<ProcessHandle> childProcess = Optional.empty();
|
||||
|
||||
// Wait a bit and check if child app launcher process is still running (it must NOT)
|
||||
Thread.sleep(Duration.ofSeconds(5));
|
||||
try {
|
||||
// Wait a bit to let the app start
|
||||
Thread.sleep(Duration.ofSeconds(10));
|
||||
|
||||
killAppLauncherProcess(cmd, null, 0);
|
||||
try (var children = mainLauncherProcess.children()) {
|
||||
childProcess = children.filter(p -> {
|
||||
return mainLauncherProcess.info().command().equals(p.info().command());
|
||||
}).findFirst();
|
||||
}
|
||||
|
||||
TKit.assertTrue(childProcess.isPresent(),
|
||||
String.format("Check the main launcher process with PID=%d restarted", mainLauncherProcess.pid()));
|
||||
} finally {
|
||||
// Kill the main app launcher process
|
||||
TKit.trace("About to kill the main launcher process...");
|
||||
mainLauncherProcess.destroyForcibly();
|
||||
|
||||
// Wait a bit and check if child app launcher process is still running (it must NOT)
|
||||
Thread.sleep(Duration.ofSeconds(5));
|
||||
|
||||
childProcess.ifPresent(p -> {
|
||||
TKit.assertTrue(!p.isAlive(), String.format(
|
||||
"Check restarted main launcher process with PID=%d is not alive", p.pid()));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2024, 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
|
||||
@ -44,7 +44,6 @@ import static jdk.jpackage.test.HelloApp.configureAndExecute;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.Executor;
|
||||
import jdk.jpackage.test.TKit;
|
||||
import static jdk.jpackage.test.WindowsHelper.killProcess;
|
||||
|
||||
public class WinChildProcessTest {
|
||||
private static final Path TEST_APP_JAVA = TKit.TEST_SRC_ROOT
|
||||
@ -52,7 +51,7 @@ public class WinChildProcessTest {
|
||||
|
||||
@Test
|
||||
public static void test() {
|
||||
long childPid = 0;
|
||||
Optional<ProcessHandle> child = Optional.empty();
|
||||
try {
|
||||
JPackageCommand cmd = JPackageCommand
|
||||
.helloAppImage(TEST_APP_JAVA + "*Hello")
|
||||
@ -69,21 +68,18 @@ public class WinChildProcessTest {
|
||||
String pidStr = output.get(0);
|
||||
|
||||
// parse child PID
|
||||
childPid = Long.parseLong(pidStr.split("=", 2)[1]);
|
||||
var childPid = Long.parseLong(pidStr.split("=", 2)[1]);
|
||||
|
||||
// Check whether the termination of third party application launcher
|
||||
// also terminating the launched third party application
|
||||
// If third party application is not terminated the test is
|
||||
// successful else failure
|
||||
Optional<ProcessHandle> processHandle = ProcessHandle.of(childPid);
|
||||
boolean isAlive = processHandle.isPresent()
|
||||
&& processHandle.get().isAlive();
|
||||
TKit.assertTrue(isAlive, "Check child process is alive");
|
||||
child = ProcessHandle.of(childPid);
|
||||
boolean isAlive = child.map(ProcessHandle::isAlive).orElse(false);
|
||||
TKit.assertTrue(isAlive, String.format("Check child process with PID=%d is alive", childPid));
|
||||
} finally {
|
||||
if (childPid != 0) {
|
||||
// Kill only a specific child instance
|
||||
killProcess(childPid);
|
||||
}
|
||||
TKit.trace("About to kill the child process...");
|
||||
child.ifPresent(ProcessHandle::destroyForcibly);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2024, 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,15 +21,18 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import static jdk.jpackage.test.WindowsHelper.killAppLauncherProcess;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.CfgFile;
|
||||
import jdk.jpackage.test.HelloApp;
|
||||
import jdk.jpackage.test.JPackageCommand;
|
||||
import jdk.jpackage.test.TKit;
|
||||
|
||||
/* @test
|
||||
* @bug 8340311
|
||||
@ -47,7 +50,7 @@ import jdk.jpackage.test.JPackageCommand;
|
||||
public class WinNoRestartTest {
|
||||
|
||||
@Test
|
||||
public static void test() throws InterruptedException, IOException {
|
||||
public static void test() throws InterruptedException, IOException, ExecutionException {
|
||||
var cmd = JPackageCommand.helloAppImage().ignoreFakeRuntime();
|
||||
|
||||
// Configure test app to launch in a way it will not exit
|
||||
@ -77,7 +80,7 @@ public class WinNoRestartTest {
|
||||
private static record NoRerunConfig(NoRerunSectionConfig firstSection,
|
||||
NoRerunSectionConfig secondSection, boolean expectedNoRestarted) {
|
||||
|
||||
void apply(JPackageCommand cmd, CfgFile origCfgFile) throws InterruptedException {
|
||||
void apply(JPackageCommand cmd, CfgFile origCfgFile) throws InterruptedException, ExecutionException {
|
||||
// Alter the main launcher .cfg file
|
||||
var cfgFile = new CfgFile();
|
||||
if (firstSection != null) {
|
||||
@ -92,16 +95,40 @@ public class WinNoRestartTest {
|
||||
// Save updated main launcher .cfg file
|
||||
cfgFile.save(cmd.appLauncherCfgPath(null));
|
||||
|
||||
var f = new CompletableFuture<Process>();
|
||||
|
||||
// Launch the app in a separate thread
|
||||
new Thread(() -> {
|
||||
HelloApp.executeLauncher(cmd);
|
||||
HelloApp.assertMainLauncher(cmd).get().processListener(f::complete).execute();
|
||||
}).start();
|
||||
|
||||
// Wait a bit to let the app start
|
||||
Thread.sleep(Duration.ofSeconds(10));
|
||||
var mainLauncherProcess = f.get();
|
||||
|
||||
// Find the main app launcher process and kill it
|
||||
killAppLauncherProcess(cmd, null, expectedNoRestarted ? 1 : 2);
|
||||
try {
|
||||
// Wait a bit to let the app start
|
||||
Thread.sleep(Duration.ofSeconds(10));
|
||||
|
||||
try (var children = mainLauncherProcess.children()) {
|
||||
Optional<String> childPid = children.filter(p -> {
|
||||
return mainLauncherProcess.info().command().equals(p.info().command());
|
||||
}).map(ProcessHandle::pid).map(Object::toString).findFirst();
|
||||
|
||||
Optional<String> expectedChildPid;
|
||||
if (expectedNoRestarted) {
|
||||
expectedChildPid = Optional.empty();
|
||||
} else {
|
||||
expectedChildPid = childPid.or(() -> {
|
||||
return Optional.of("<some>");
|
||||
});
|
||||
}
|
||||
TKit.assertEquals(expectedChildPid, childPid, String.format(
|
||||
"Check the main launcher process with PID=%d restarted",
|
||||
mainLauncherProcess.pid()));
|
||||
}
|
||||
} finally {
|
||||
TKit.trace("About to kill the main launcher process...");
|
||||
mainLauncherProcess.destroyForcibly();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user