8382684: jpackage: assorted fixes of the test lib

Reviewed-by: almatvee
This commit is contained in:
Alexey Semenyuk 2026-04-22 01:54:54 +00:00
parent b64d23d108
commit 624739e3e5
15 changed files with 102 additions and 147 deletions

View File

@ -33,7 +33,6 @@ import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.spi.ToolProvider;
import jdk.jpackage.internal.util.function.ExceptionBox;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
@ -74,51 +73,45 @@ class JPackageCommandTest extends JUnitAdapter.TestSrcInitializer {
void test() {
final Optional<ToolProvider> global;
switch (globalType) {
final Optional<ToolProvider> global = switch (globalType) {
case SET_CUSTOM_TOOL_PROVIDER -> {
global = Optional.of(createNewToolProvider("jpackage-mock-global"));
JPackageCommand.useToolProviderByDefault(global.get());
var tp = createNewToolProvider("jpackage-mock-global");
JPackageCommand.useToolProviderByDefault(tp);
yield Optional.of(tp);
}
case SET_DEFAULT_TOOL_PROVIDER -> {
global = Optional.of(JavaTool.JPACKAGE.asToolProvider());
JPackageCommand.useToolProviderByDefault();
yield Optional.of(JavaTool.JPACKAGE.asToolProvider());
}
case SET_PROCESS -> {
global = Optional.empty();
JPackageCommand.useExecutableByDefault();
yield Optional.empty();
}
case SET_NONE -> {
global = Optional.empty();
yield Optional.empty();
}
default -> {
throw ExceptionBox.reachedUnreachable();
}
}
};
var cmd = new JPackageCommand();
final Optional<ToolProvider> instance;
switch (instanceType) {
final Optional<ToolProvider> instance = switch (instanceType) {
case SET_CUSTOM_TOOL_PROVIDER -> {
instance = Optional.of(createNewToolProvider("jpackage-mock"));
cmd.useToolProvider(instance.get());
var tp = createNewToolProvider("jpackage-mock");
cmd.useToolProvider(tp);
yield Optional.of(tp);
}
case SET_DEFAULT_TOOL_PROVIDER -> {
instance = Optional.of(JavaTool.JPACKAGE.asToolProvider());
cmd.useToolProvider(true);
yield Optional.of(JavaTool.JPACKAGE.asToolProvider());
}
case SET_PROCESS -> {
instance = Optional.empty();
cmd.useToolProvider(false);
yield Optional.empty();
}
case SET_NONE -> {
instance = Optional.empty();
yield Optional.empty();
}
default -> {
throw ExceptionBox.reachedUnreachable();
}
}
};
var actual = cmd.createExecutor().getToolProvider();

View File

@ -65,7 +65,6 @@ import jdk.jpackage.internal.model.DottedVersion;
import jdk.jpackage.internal.util.MacBundle;
import jdk.jpackage.internal.util.Result;
import jdk.jpackage.internal.util.RuntimeReleaseFile;
import jdk.jpackage.internal.util.function.ExceptionBox;
import jdk.jpackage.internal.util.function.ThrowingConsumer;
import jdk.jpackage.internal.util.function.ThrowingFunction;
import jdk.jpackage.internal.util.function.ThrowingRunnable;
@ -495,8 +494,7 @@ public class JPackageCommand extends CommandArguments<JPackageCommand> {
public static Path createInputRuntimeImage(RuntimeImageType role) {
Objects.requireNonNull(role);
final Path runtimeImageDir;
switch (role) {
return switch (role) {
case RUNTIME_TYPE_FAKE -> {
Consumer<Path> createBulkFile = ThrowingConsumer.toConsumer(path -> {
@ -508,7 +506,7 @@ public class JPackageCommand extends CommandArguments<JPackageCommand> {
}
});
runtimeImageDir = TKit.createTempDirectory("fake_runtime");
var runtimeImageDir = TKit.createTempDirectory("fake_runtime");
TKit.trace(String.format("Init fake runtime in [%s] directory", runtimeImageDir));
@ -521,32 +519,28 @@ public class JPackageCommand extends CommandArguments<JPackageCommand> {
// Package bundles with 0KB size are unexpected and considered
// an error by PackageTest.
createBulkFile.accept(runtimeImageDir.resolve(Path.of("lib", "bulk")));
yield runtimeImageDir;
}
case RUNTIME_TYPE_HELLO_APP -> {
if (JPackageCommand.DEFAULT_RUNTIME_IMAGE != null && !isFakeRuntime(DEFAULT_RUNTIME_IMAGE)) {
runtimeImageDir = JPackageCommand.DEFAULT_RUNTIME_IMAGE;
} else {
runtimeImageDir = TKit.createTempDirectory("runtime-image").resolve("data");
yield DEFAULT_RUNTIME_IMAGE.filter(Predicate.not(JPackageCommand::isFakeRuntime)).orElseGet(() -> {
var dir = TKit.createTempDirectory("runtime-image").resolve("data");
new Executor().setToolProvider(JavaTool.JLINK)
.dumpOutput()
.addArguments(
"--output", runtimeImageDir.toString(),
"--output", dir.toString(),
"--add-modules", "java.desktop",
"--strip-debug",
"--no-header-files",
"--no-man-pages")
.execute();
}
}
default -> {
throw ExceptionBox.reachedUnreachable();
return dir;
});
}
}
return runtimeImageDir;
};
}
public JPackageCommand setPackageType(PackageType type) {
@ -868,6 +862,7 @@ public class JPackageCommand extends CommandArguments<JPackageCommand> {
} else if (TKit.isLinux()) {
criticalRuntimeFiles = LinuxHelper.CRITICAL_RUNTIME_FILES;
} else if (TKit.isOSX()) {
runtimeDir = MacBundle.fromPath(runtimeDir).map(MacBundle::homeDir).orElse(runtimeDir);
criticalRuntimeFiles = MacHelper.CRITICAL_RUNTIME_FILES;
} else {
throw TKit.throwUnknownPlatformError();
@ -972,8 +967,7 @@ public class JPackageCommand extends CommandArguments<JPackageCommand> {
}
public JPackageCommand ignoreFakeRuntime() {
return ignoreDefaultRuntime(Optional.ofNullable(DEFAULT_RUNTIME_IMAGE)
.map(JPackageCommand::isFakeRuntime).orElse(false));
return ignoreDefaultRuntime(DEFAULT_RUNTIME_IMAGE.map(JPackageCommand::isFakeRuntime).orElse(false));
}
public JPackageCommand ignoreDefaultVerbose(boolean v) {
@ -1801,9 +1795,12 @@ public class JPackageCommand extends CommandArguments<JPackageCommand> {
// to allow the jlink process to print exception stacktraces on any failure
addArgument("-J-Djlink.debug=true");
}
if (!hasArgument("--runtime-image") && !hasArgument("--jlink-options") && !hasArgument("--app-image") && DEFAULT_RUNTIME_IMAGE != null && !ignoreDefaultRuntime) {
addArguments("--runtime-image", DEFAULT_RUNTIME_IMAGE);
}
DEFAULT_RUNTIME_IMAGE.filter(_ -> {
return Stream.of("--runtime-image", "--jlink-options", "--app-image").noneMatch(this::hasArgument) && !ignoreDefaultRuntime;
}).ifPresent(defaultRuntime -> {
addArguments("--runtime-image", defaultRuntime);
});
if (!hasArgument("--verbose") && TKit.verboseJPackage() && !ignoreDefaultVerbose) {
addArgument("--verbose");
@ -2015,26 +2012,23 @@ public class JPackageCommand extends CommandArguments<JPackageCommand> {
}
Optional<ToolProvider> toolProvider() {
switch (mode) {
return switch (mode) {
case USE_PROCESS -> {
return Optional.empty();
yield Optional.empty();
}
case USE_TOOL_PROVIDER -> {
if (customToolProvider != null) {
return Optional.of(customToolProvider);
yield Optional.of(customToolProvider);
} else {
return TKit.state().findProperty(DefaultToolProviderKey.VALUE).map(ToolProvider.class::cast).or(() -> {
yield TKit.state().findProperty(DefaultToolProviderKey.VALUE).map(ToolProvider.class::cast).or(() -> {
return Optional.of(JavaTool.JPACKAGE.asToolProvider());
});
}
}
case INHERIT_DEFAULTS -> {
return TKit.state().findProperty(DefaultToolProviderKey.VALUE).map(ToolProvider.class::cast);
yield TKit.state().findProperty(DefaultToolProviderKey.VALUE).map(ToolProvider.class::cast);
}
default -> {
throw ExceptionBox.reachedUnreachable();
}
}
};
}
ToolProviderSource() {
@ -2088,7 +2082,7 @@ public class JPackageCommand extends CommandArguments<JPackageCommand> {
// The value of the property will be automatically appended to
// jpackage command line if the command line doesn't have
// `--runtime-image` parameter set.
public static final Path DEFAULT_RUNTIME_IMAGE = Optional.ofNullable(TKit.getConfigProperty("runtime-image")).map(Path::of).orElse(null);
private static final Optional<Path> DEFAULT_RUNTIME_IMAGE = Optional.ofNullable(TKit.getConfigProperty("runtime-image")).map(Path::of);
public static final String DEFAULT_VERSION = "1.0";

View File

@ -585,17 +585,14 @@ public final class LinuxHelper {
var appLayout = cmd.appLayout();
LauncherShortcut.LINUX_SHORTCUT.expectShortcut(cmd, predefinedAppImage, launcherName).map(shortcutWorkDirType -> {
switch (shortcutWorkDirType) {
return switch (shortcutWorkDirType) {
case DEFAULT -> {
return (Path)null;
yield (Path)null;
}
case APP_DIR -> {
return cmd.pathToPackageFile(appLayout.appDirectory());
yield cmd.pathToPackageFile(appLayout.appDirectory());
}
default -> {
throw new AssertionError();
}
}
};
}).map(Path::toString).ifPresentOrElse(shortcutWorkDir -> {
var actualShortcutWorkDir = data.find("Path");
TKit.assertTrue(actualShortcutWorkDir.isPresent(), "Check [Path] key exists");

View File

@ -1340,8 +1340,7 @@ public final class MacHelper {
)).map(Path::of).collect(toSet());
}
static final Set<Path> CRITICAL_RUNTIME_FILES = Set.of(Path.of(
"Contents/Home/lib/server/libjvm.dylib"));
static final Set<Path> CRITICAL_RUNTIME_FILES = Set.of(Path.of("lib/server/libjvm.dylib"));
private static final Method getServicePListFileName = initGetServicePListFileName();

View File

@ -890,17 +890,14 @@ public final class MacSign {
private String validatedCN() {
return Optional.ofNullable(subjectCommonName).orElseGet(() -> {
switch (type) {
return switch (type) {
case CODE_SIGN -> {
return StandardCertificateNamePrefix.CODE_SIGN.value() + validatedUserName();
yield StandardCertificateNamePrefix.CODE_SIGN.value() + validatedUserName();
}
case INSTALLER -> {
return StandardCertificateNamePrefix.INSTALLER.value() + validatedUserName();
yield StandardCertificateNamePrefix.INSTALLER.value() + validatedUserName();
}
default -> {
throw new UnsupportedOperationException();
}
}
};
});
}

View File

@ -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
@ -213,17 +213,14 @@ public final class WinShortcutVerifier {
final var installDir = Path.of(installRoot.getMsiPropertyName()).resolve(getInstallationSubDirectory(cmd));
final Function<StartupDirectory, Path> workDir = startupDirectory -> {
switch (startupDirectory) {
return switch (startupDirectory) {
case DEFAULT -> {
return installDir;
yield installDir;
}
case APP_DIR -> {
return ApplicationLayout.windowsAppImage().resolveAt(installDir).appDirectory();
yield ApplicationLayout.windowsAppImage().resolveAt(installDir).appDirectory();
}
default -> {
throw new IllegalArgumentException();
}
}
};
};
if (winMenu.isPresent()) {

View File

@ -133,22 +133,19 @@ public record CommandActionSpecs(List<CommandActionSpec> specs) {
}
public Builder exit(CommandMockExit exit) {
switch (exit) {
return switch (exit) {
case SUCCEED -> {
return exit();
yield exit();
}
case EXIT_1 -> {
return exit(1);
yield exit(1);
}
case THROW_MOCK_IO_EXCEPTION -> {
return action(CommandActionSpec.create("<I/O error>", () -> {
yield action(CommandActionSpec.create("<I/O error>", () -> {
throw new MockingToolProvider.RethrowableException(new MockIOException("Kaput!"));
}));
}
default -> {
throw ExceptionBox.reachedUnreachable();
}
}
};
}
public Builder mutate(Consumer<Builder> mutator) {

View File

@ -66,6 +66,7 @@ public class DottedVersionTest {
var dv = cfg.createVersion.apply(cfg.input());
assertEquals(cfg.expectedSuffix(), dv.getUnprocessedSuffix());
assertEquals(cfg.expectedComponentCount(), dv.getComponents().length);
assertEquals(cfg.expectedComponentCount(), dv.getComponentsCount());
assertEquals(cfg.expectedToComponent(), dv.toComponentsString());
assertEquals(dv.toString(), cfg.input());
}

View File

@ -84,6 +84,17 @@ public class ExceptionBoxTest {
assertSame(err, thrown);
}
@Test
public void test_unbox_reachedUnreachable() {
var err = new MyThrowable();
var thrown = assertThrowsExactly(AssertionError.class, () -> {
ExceptionBox.unbox(err);
});
assertEquals(ExceptionBox.reachedUnreachable().getMessage(), thrown.getMessage());
assertNull(thrown.getCause());
}
@Test
public void test_reachedUnreachable() {
var err = ExceptionBox.reachedUnreachable();
@ -320,4 +331,9 @@ public class ExceptionBoxTest {
Objects.requireNonNull(format);
System.out.println(String.format("[%s]: %s", Thread.currentThread(), String.format(format, args)));
}
private static final class MyThrowable extends Throwable {
private static final long serialVersionUID = 1L;
}
}

View File

@ -35,7 +35,6 @@ import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import jdk.jpackage.internal.util.function.ExceptionBox;
import jdk.jpackage.test.Annotations.Parameter;
import jdk.jpackage.test.Annotations.ParameterSupplier;
import jdk.jpackage.test.Annotations.Test;
@ -392,25 +391,20 @@ public class MacSignTest {
Objects.requireNonNull(keychain);
String cmdlinePatternFormat;
String signIdentity;
switch (option.optionName().orElseThrow()) {
String signIdentity = switch (option.optionName().orElseThrow()) {
case KEY_IDENTITY_APP_IMAGE, KEY_USER_NAME -> {
cmdlinePatternFormat = "^/usr/bin/codesign -s %s -vvvv --timestamp --options runtime --prefix \\S+ --keychain %s";
if (option.passThrough().orElse(false)) {
signIdentity = String.format("'%s'", option.asCmdlineArgs().getLast());
yield String.format("'%s'", option.asCmdlineArgs().getLast());
} else {
signIdentity = MacSign.CertificateHash.of(option.certRequest().cert()).toString();
yield MacSign.CertificateHash.of(option.certRequest().cert()).toString();
}
}
case KEY_IDENTITY_INSTALLER -> {
cmdlinePatternFormat = "^/usr/bin/productbuild --resources \\S+ --sign %s --keychain %s";
signIdentity = String.format("'%s'", option.asCmdlineArgs().getLast());
yield String.format("'%s'", option.asCmdlineArgs().getLast());
}
default -> {
throw ExceptionBox.reachedUnreachable();
}
}
};
return new FailedCommandErrorValidator(Pattern.compile(String.format(
cmdlinePatternFormat,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2025, 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
@ -458,9 +458,6 @@ public class AddLShortcutTest {
case DEFAULT -> {
cmd.addArgument(shortcut.optionName());
}
default -> {
cmd.addArguments(shortcut.optionName(), value);
}
}
}

View File

@ -767,6 +767,11 @@ public final class AppVersionTest {
AppTestSpec {
Objects.requireNonNull(appDesc);
Objects.requireNonNull(spec);
spec.findVersionSource(ModuleVersionSource.class).map(ModuleVersionSource::appDesc).ifPresent(moduleAppDesc -> {
if (!moduleAppDesc.equals(appDesc)) {
throw new IllegalArgumentException();
}
});
}
AppTestSpec(TestSpec spec) {

View File

@ -873,20 +873,16 @@ public final class ErrorTest {
for (var withAppImage : List.of(true, false)) {
for (var existingCertType : CertificateType.values()) {
Token keychain;
StandardCertificateNamePrefix missingCertificateNamePrefix;
switch (existingCertType) {
StandardCertificateNamePrefix missingCertificateNamePrefix = switch (existingCertType) {
case INSTALLER -> {
keychain = Token.KEYCHAIN_WITH_PKG_CERT;
missingCertificateNamePrefix = StandardCertificateNamePrefix.CODE_SIGN;
yield StandardCertificateNamePrefix.CODE_SIGN;
}
case CODE_SIGN -> {
keychain = Token.KEYCHAIN_WITH_APP_IMAGE_CERT;
missingCertificateNamePrefix = StandardCertificateNamePrefix.INSTALLER;
yield StandardCertificateNamePrefix.INSTALLER;
}
default -> {
throw new AssertionError();
}
}
};
var builder = testSpec()
.type(PackageType.MAC_PKG)

View File

@ -152,10 +152,9 @@ public final class ModularAppTest {
HelloApp.createBundle(appDesc, moduleOutputDir);
final var workDir = TKit.createTempDirectory("runtime").resolve("data");
final Path jlinkOutputDir;
switch (runtimeType) {
final Path jlinkOutputDir = switch (runtimeType) {
case IMAGE -> {
jlinkOutputDir = workDir;
yield workDir;
}
case MAC_BUNDLE -> {
var macBundle = new MacBundle(workDir);
@ -164,12 +163,9 @@ public final class ModularAppTest {
Files.createDirectories(macBundle.homeDir().getParent());
Files.createDirectories(macBundle.macOsDir());
Files.createFile(macBundle.infoPlistFile());
jlinkOutputDir = macBundle.homeDir();
yield macBundle.homeDir();
}
default -> {
throw new AssertionError();
}
}
};
// List of modules required for the test app.
final var modules = new String[] {
@ -264,9 +260,6 @@ public final class ModularAppTest {
case NON_EXISTING_DIR -> {
yield nonExistingDir;
}
default -> {
throw new AssertionError();
}
}).get();
});
}).<String>mapMulti((path, acc) -> {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 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,13 +21,13 @@
* questions.
*/
import static jdk.jpackage.test.JPackageCommand.RuntimeImageType.RUNTIME_TYPE_HELLO_APP;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import jdk.jpackage.test.Annotations.Test;
import jdk.jpackage.test.Executor;
import jdk.jpackage.test.JPackageCommand;
import jdk.jpackage.test.JavaTool;
import jdk.jpackage.test.TKit;
/*
@ -44,30 +44,9 @@ public class RuntimeImageTest {
@Test
public static void test() throws IOException {
JPackageCommand cmd = JPackageCommand.helloAppImage();
if (JPackageCommand.DEFAULT_RUNTIME_IMAGE == null) {
final Path workDir = TKit.createTempDirectory("runtime").resolve("data");
final Path jlinkOutputDir = workDir.resolve("temp.runtime");
Files.createDirectories(jlinkOutputDir.getParent());
new Executor()
.setToolProvider(JavaTool.JLINK)
.dumpOutput()
.addArguments(
"--output", jlinkOutputDir.toString(),
"--add-modules", "java.desktop",
"--strip-debug",
"--no-header-files",
"--no-man-pages",
"--strip-native-commands")
.execute();
cmd.setArgumentValue("--runtime-image", jlinkOutputDir.toString());
}
cmd.executeAndAssertHelloAppImageCreated();
JPackageCommand.helloAppImage()
.setArgumentValue("--runtime-image", JPackageCommand.createInputRuntimeImage(RUNTIME_TYPE_HELLO_APP))
.executeAndAssertHelloAppImageCreated();
}
@Test