diff --git a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/PackageTestTest.java b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/PackageTestTest.java index 4cf89fca3cc..4723f4dadbd 100644 --- a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/PackageTestTest.java +++ b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/PackageTestTest.java @@ -351,7 +351,8 @@ public class PackageTestTest extends JUnitAdapter { } @Override - public void verifyIsOfType(PackageType ... types) { + public JPackageCommand verifyIsOfType(Set types) { + return this; } @Override diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java index a41e2b5043f..4f0e3f4e485 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java @@ -165,7 +165,7 @@ public final class AdditionalLauncher { public void applyTo(JPackageCommand cmd) { cmd.addPrerequisiteAction(this::initialize); - cmd.addVerifyAction(createVerifierAsConsumer()); + cmd.addVerifyAction(createVerifierAsConsumer(), JPackageCommand.ActionRole.LAUNCHER_VERIFIER); } public void applyTo(PackageTest test) { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/ConfigFilesStasher.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/ConfigFilesStasher.java index 11627ab9125..0b3f5defbac 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/ConfigFilesStasher.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/ConfigFilesStasher.java @@ -192,9 +192,7 @@ final class ConfigFilesStasher { } private static ApplicationLayout appImageAppLayout(JPackageCommand cmd) { - if (cmd.isRuntime()) { - throw new UnsupportedOperationException(); - } + cmd.verifyNotRuntime(); if (cmd.isImagePackageType()) { return platformAppImage(); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java index 088a9fe3bad..57915b91d8b 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java @@ -28,13 +28,16 @@ import static java.util.stream.Collectors.mapping; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toMap; import static java.util.stream.Collectors.toSet; +import static java.util.stream.Collectors.toCollection; import static jdk.jpackage.test.AdditionalLauncher.forEachAdditionalLauncher; import java.io.FileOutputStream; import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.InvalidPathException; +import java.nio.file.LinkOption; import java.nio.file.Path; import java.security.SecureRandom; import java.util.ArrayList; @@ -48,6 +51,7 @@ import java.util.Objects; import java.util.Optional; import java.util.OptionalInt; import java.util.Set; +import java.util.TreeSet; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; @@ -56,6 +60,7 @@ import java.util.regex.Pattern; import java.util.spi.ToolProvider; import java.util.stream.Collectors; import java.util.stream.Stream; +import java.util.stream.StreamSupport; import jdk.jpackage.internal.util.function.ThrowingConsumer; import jdk.jpackage.internal.util.function.ThrowingFunction; import jdk.jpackage.internal.util.function.ThrowingRunnable; @@ -85,7 +90,6 @@ public class JPackageCommand extends CommandArguments { ignoreDefaultRuntime = cmd.ignoreDefaultRuntime; ignoreDefaultVerbose = cmd.ignoreDefaultVerbose; this.immutable = immutable; - dmgInstallDir = cmd.dmgInstallDir; prerequisiteActions = new Actions(cmd.prerequisiteActions); verifyActions = new Actions(cmd.verifyActions); standardAsserts = cmd.standardAsserts; @@ -165,11 +169,6 @@ public class JPackageCommand extends CommandArguments { return null; } - public String getArgumentValue(String argName, - Function defaultValueSupplier) { - return getArgumentValue(argName, defaultValueSupplier, v -> v); - } - public T getArgumentValue(String argName, Supplier defaultValueSupplier, Function stringConverter) { @@ -332,16 +331,35 @@ public class JPackageCommand extends CommandArguments { return this; } + public JPackageCommand usePredefinedAppImage(Path predefinedAppImagePath) { + return setArgumentValue("--app-image", Objects.requireNonNull(predefinedAppImagePath)) + .removeArgumentWithValue("--input"); + } + JPackageCommand addPrerequisiteAction(ThrowingConsumer action) { prerequisiteActions.add(action); return this; } JPackageCommand addVerifyAction(ThrowingConsumer action) { - verifyActions.add(action); + return addVerifyAction(action, ActionRole.DEFAULT); + } + + enum ActionRole { + DEFAULT, + LAUNCHER_VERIFIER, + ; + } + + JPackageCommand addVerifyAction(ThrowingConsumer action, ActionRole actionRole) { + verifyActions.add(action, actionRole); return this; } + Stream> getVerifyActionsWithRole(ActionRole actionRole) { + return verifyActions.actionsWithRole(actionRole); + } + /** * Shorthand for {@code helloAppImage(null)}. */ @@ -550,11 +568,7 @@ public class JPackageCommand extends CommandArguments { } if (TKit.isOSX()) { - if (packageType() == PackageType.MAC_DMG && dmgInstallDir != null) { - return dmgInstallDir; - } else { - return MacHelper.getInstallationDirectory(this); - } + return MacHelper.getInstallationDirectory(this); } throw TKit.throwUnknownPlatformError(); @@ -676,10 +690,11 @@ public class JPackageCommand extends CommandArguments { return Collections.unmodifiableList(names); } - private void verifyNotRuntime() { + JPackageCommand verifyNotRuntime() { if (isRuntime()) { - throw new IllegalArgumentException("Java runtime packaging"); + throw new UnsupportedOperationException("Java runtime packaging"); } + return this; } /** @@ -1212,6 +1227,52 @@ public class JPackageCommand extends CommandArguments { MacHelper.verifyUnsignedBundleSignature(cmd); } }), + PREDEFINED_APP_IMAGE_COPY(cmd -> { + Optional.ofNullable(cmd.getArgumentValue("--app-image")).filter(_ -> { + return !TKit.isOSX() || !MacHelper.signPredefinedAppImage(cmd); + }).map(Path::of).ifPresent(predefinedAppImage -> { + + TKit.trace(String.format( + "Check contents of the predefined app image [%s] copied verbatim", + predefinedAppImage)); + + var outputAppImageDir = cmd.pathToUnpackedPackageFile(cmd.appInstallationDirectory()); + + try (var walk = Files.walk(predefinedAppImage)) { + var filteredWalk = walk; + if (!cmd.expectAppImageFile()) { + var appImageFile = AppImageFile.getPathInAppImage(predefinedAppImage); + // Exclude ".jpackage.xml" as it should no be in the output bundle. + var pred = Predicate.isEqual(appImageFile).negate(); + if (TKit.isOSX()) { + // On MacOS exclude files that can be signed as their digests change. + pred = pred.and(path -> { + return MacHelper.isVerbatimCopyFromPredefinedAppImage(cmd, path); + }); + } + + filteredWalk = walk.filter(pred); + } + + var verbatimPaths = filteredWalk.collect(toCollection(TreeSet::new)); + + // Remove nonempty directories from the collection of paths copied verbatim. + verbatimPaths.removeAll(verbatimPaths.stream().map(Path::getParent).toList()); + + verbatimPaths.forEach(ThrowingConsumer.toConsumer(p -> { + if (Files.isDirectory(p, LinkOption.NOFOLLOW_LINKS)) { + TKit.assertDirectoryExists(p); + } else { + TKit.assertSameFileContent(p, outputAppImageDir.resolve(predefinedAppImage.relativize(p))); + } + })); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + + TKit.trace("Done"); + }); + }) ; StandardAssert(Consumer action) { @@ -1220,9 +1281,7 @@ public class JPackageCommand extends CommandArguments { private static JPackageCommand convertFromRuntime(JPackageCommand cmd) { var copy = cmd.createMutableCopy(); - copy.immutable = false; copy.removeArgumentWithValue("--runtime-image"); - copy.dmgInstallDir = cmd.appInstallationDirectory(); if (!copy.hasArgument("--name")) { copy.addArguments("--name", cmd.nameFromRuntimeImage().orElseThrow()); } @@ -1440,29 +1499,35 @@ public class JPackageCommand extends CommandArguments { return getPrintableCommandLine(); } - public void verifyIsOfType(Collection types) { - verifyIsOfType(types.toArray(PackageType[]::new)); + public final JPackageCommand verifyIsOfType(PackageType ... types) { + return verifyIsOfType(Set.of(types)); } - public void verifyIsOfType(PackageType ... types) { - final var typesSet = Stream.of(types).collect(Collectors.toSet()); + public final JPackageCommand verifyIsOfType(Iterable types) { + return verifyIsOfType(StreamSupport.stream(types.spliterator(), false).collect(toSet())); + } + + public JPackageCommand verifyIsOfType(Set types) { + Objects.requireNonNull(types); if (!hasArgument("--type")) { if (!isImagePackageType()) { - if ((TKit.isLinux() && typesSet.equals(PackageType.LINUX)) || (TKit.isWindows() && typesSet.equals(PackageType.WINDOWS))) { - return; + if ((TKit.isLinux() && types.equals(PackageType.LINUX)) || (TKit.isWindows() && types.equals(PackageType.WINDOWS))) { + return this; } - if (TKit.isOSX() && typesSet.equals(PackageType.MAC)) { - return; + if (TKit.isOSX() && types.equals(PackageType.MAC)) { + return this; } - } else if (typesSet.equals(Set.of(PackageType.IMAGE))) { - return; + } else if (types.equals(Set.of(PackageType.IMAGE))) { + return this; } } - if (!typesSet.contains(packageType())) { - throw new IllegalArgumentException("Unexpected type"); + if (!types.contains(packageType())) { + throw new UnsupportedOperationException(String.format("Unsupported operation for type [%s]", packageType().getType())); } + + return this; } public CfgFile readLauncherCfgFile() { @@ -1558,18 +1623,47 @@ public class JPackageCommand extends CommandArguments { } void add(ThrowingConsumer action) { - Objects.requireNonNull(action); + add(action, ActionRole.DEFAULT); + } + + void add(ThrowingConsumer action, ActionRole role) { verifyMutable(); - actions.add(new Consumer() { - @Override - public void accept(JPackageCommand t) { - if (!executed) { - executed = true; - ThrowingConsumer.toConsumer(action).accept(t); - } + actions.add(new Action(action, role)); + } + + Stream> actionsWithRole(ActionRole role) { + Objects.requireNonNull(role); + return actions.stream().filter(action -> { + return Objects.equals(action.role(), role); + }).map(Action::impl); + } + + private static final class Action implements Consumer { + + Action(ThrowingConsumer impl, ActionRole role) { + this.impl = Objects.requireNonNull(impl); + this.role = Objects.requireNonNull(role); + } + + ActionRole role() { + return role; + } + + ThrowingConsumer impl() { + return impl; + } + + @Override + public void accept(JPackageCommand cmd) { + if (!executed) { + executed = true; + ThrowingConsumer.toConsumer(impl).accept(cmd); } - private boolean executed; - }); + } + + private final ActionRole role; + private final ThrowingConsumer impl; + private boolean executed; } @Override @@ -1578,7 +1672,7 @@ public class JPackageCommand extends CommandArguments { actions.forEach(action -> action.accept(JPackageCommand.this)); } - private final List> actions; + private final List actions; } private Boolean withToolProvider; @@ -1589,7 +1683,6 @@ public class JPackageCommand extends CommandArguments { private boolean ignoreDefaultRuntime; private boolean ignoreDefaultVerbose; private boolean immutable; - private Path dmgInstallDir; private final Actions prerequisiteActions; private final Actions verifyActions; private Path executeInDirectory; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherVerifier.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherVerifier.java index 489788b565a..da5b8583c72 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherVerifier.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherVerifier.java @@ -24,6 +24,7 @@ package jdk.jpackage.test; import static java.util.stream.Collectors.toMap; import static jdk.jpackage.test.AdditionalLauncher.NO_ICON; +import static jdk.jpackage.test.AdditionalLauncher.getAdditionalLauncherProperties; import static jdk.jpackage.test.LauncherShortcut.LINUX_SHORTCUT; import java.io.IOException; @@ -34,6 +35,7 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.function.BiConsumer; +import java.util.function.BiFunction; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Stream; @@ -72,6 +74,12 @@ public final class LauncherVerifier { new LauncherVerifier(cmd).verify(cmd, Action.EXECUTE_LAUNCHER); } + static String launcherDescription(JPackageCommand cmd, String launcherName) { + return launcherDescription(cmd, launcherName, (theCmd, theLauncherName) -> { + return getAdditionalLauncherProperties(theCmd, theLauncherName); + }); + } + public enum Action { VERIFY_ICON(LauncherVerifier::verifyIcon), @@ -137,8 +145,8 @@ public final class LauncherVerifier { } private String getDescription(JPackageCommand cmd) { - return findProperty("description").orElseGet(() -> { - return cmd.getArgumentValue("--description", cmd::name); + return launcherDescription(cmd, name, (theCmd, theLauncherName) -> { + return properties.orElseThrow(); }); } @@ -272,7 +280,11 @@ public final class LauncherVerifier { } private void verifyDescription(JPackageCommand cmd) throws IOException { - if (TKit.isWindows()) { + if (TKit.isWindows() && !cmd.hasArgument("--app-image")) { + // On Windows, check the description if the predefined app image is not configured. + // The description and the icon are encoded in the launcher executable, which should be + // copied verbatim from the predefined app image into the output bundle. + // This check is done in the JPackageCommand class, so there is no need to duplicate it here. String expectedDescription = getDescription(cmd); Path launcherPath = cmd.appLauncherPath(name); String actualDescription = @@ -424,6 +436,24 @@ public final class LauncherVerifier { }); } + private static String launcherDescription( + JPackageCommand cmd, + String launcherName, + BiFunction addLauncherPropertyFileGetter) { + + return PropertyFinder.findLauncherProperty(cmd, launcherName, + PropertyFinder.cmdlineOptionWithValue("--description"), + PropertyFinder.launcherPropertyFile("description"), + PropertyFinder.nop() + ).orElseGet(() -> { + if (cmd.isMainLauncher(launcherName)) { + return cmd.mainLauncherName(); + } else { + return launcherDescription(cmd, null, addLauncherPropertyFileGetter); + } + }); + } + private static final class DefaultEntitlements { private static Map loadFromResources(String resourceName) { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java index c8df0f640d0..25358e8ecdc 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java @@ -26,7 +26,6 @@ import static java.util.Collections.unmodifiableSortedSet; import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toMap; import static java.util.stream.Collectors.toSet; -import static jdk.jpackage.test.AdditionalLauncher.getAdditionalLauncherProperties; import java.io.IOException; import java.io.UncheckedIOException; @@ -560,14 +559,7 @@ public final class LinuxHelper { TKit.assertTrue(mandatoryKeys.isEmpty(), String.format( "Check for missing %s keys in the file", mandatoryKeys)); - final String launcherDescription; - if (cmd.name().equals(launcherName) || predefinedAppImage.isPresent()) { - launcherDescription = Optional.ofNullable(cmd.getArgumentValue("--description")).orElseGet(cmd::name); - } else { - launcherDescription = getAdditionalLauncherProperties(cmd, launcherName).findProperty("description").or(() -> { - return Optional.ofNullable(cmd.getArgumentValue("--description")); - }).orElseGet(cmd::name); - } + final var launcherDescription = LauncherVerifier.launcherDescription(cmd, launcherName); for (var e : List.of( Map.entry("Type", "Application"), diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java index 5c0914ed2f4..4e239e16b59 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java @@ -545,6 +545,43 @@ public final class MacHelper { } } + static boolean isVerbatimCopyFromPredefinedAppImage(JPackageCommand cmd, Path path) { + cmd.verifyIsOfType(PackageType.MAC); + + final var predefinedAppImage = Path.of(cmd.getArgumentValue("--app-image")); + + final var appLayout = ApplicationLayout.macAppImage().resolveAt(predefinedAppImage); + + if (!path.startsWith(predefinedAppImage)) { + throw new IllegalArgumentException( + String.format("Path [%s] is not in directory [%s]", path, predefinedAppImage)); + } + + if (path.startsWith(appLayout.contentDirectory().resolve("_CodeSignature"))) { + // A file in the "Contents/_CodeSignature" directory. + return false; + } + + final var outputAppImageDir = cmd.pathToUnpackedPackageFile(cmd.appInstallationDirectory()); + + final var outputAppImagePath = outputAppImageDir.resolve(predefinedAppImage.relativize(path)); + + if (path.startsWith(appLayout.launchersDirectory()) && + cmd.launcherNames(true).stream().map(cmd::appLauncherPath).collect(toSet()).contains(outputAppImagePath)) { + // The `path` references a launcher. + // It can be signed and its digest may change. + return false; + } + + if (path.startsWith(appLayout.runtimeHomeDirectory().resolve("bin"))) { + // The `path` references an executable native command in JDK's "bin" subdirectory. + // It can be signed and its digest may change. + return false; + } + + return true; + } + static void verifyUnsignedBundleSignature(JPackageCommand cmd) { if (!cmd.isImagePackageType()) { MacSignVerify.assertUnsigned(cmd.outputBundle()); @@ -716,12 +753,8 @@ public final class MacHelper { final var defaultInstallLocation = Path.of( cmd.isRuntime() ? "/Library/Java/JavaVirtualMachines" : "/Applications"); - final Path installLocation; - if (cmd.packageType() == PackageType.MAC_DMG) { - installLocation = defaultInstallLocation; - } else { - installLocation = cmd.getArgumentValue("--install-dir", () -> defaultInstallLocation, Path::of); - } + final Path installLocation = Optional.ofNullable(cmd.getArgumentValue("--install-dir")) + .map(Path::of).orElse(defaultInstallLocation); return installLocation.resolve(cmd.name() + (cmd.isRuntime() ? ".jdk" : ".app")); } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java index 2e73f43b58d..5b3815510ce 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java @@ -60,6 +60,7 @@ import java.util.stream.StreamSupport; import jdk.jpackage.internal.util.function.ThrowingBiConsumer; import jdk.jpackage.internal.util.function.ThrowingConsumer; import jdk.jpackage.internal.util.function.ThrowingRunnable; +import jdk.jpackage.test.JPackageCommand.ActionRole; /** @@ -233,6 +234,15 @@ public final class PackageTest extends RunnablePackageTest { return this; } + public PackageTest usePredefinedAppImage(JPackageCommand appImageCmd) { + appImageCmd.verifyIsOfType(PackageType.IMAGE); + addInitializer(cmd -> { + cmd.usePredefinedAppImage(appImageCmd.outputBundle()); + }); + appImageCmd.getVerifyActionsWithRole(ActionRole.LAUNCHER_VERIFIER).forEach(this::addInstallVerifier); + return this; + } + public PackageTest disablePackageInstaller() { currentTypes.forEach(disabledInstallers::add); return this; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PropertyFinder.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PropertyFinder.java index e310de855c6..54e3ef2ec54 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PropertyFinder.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PropertyFinder.java @@ -26,7 +26,9 @@ import static jdk.jpackage.test.AdditionalLauncher.getAdditionalLauncherProperti import java.nio.file.Path; import java.util.Objects; import java.util.Optional; +import java.util.function.BiFunction; import java.util.function.Function; +import java.util.function.Supplier; import java.util.function.UnaryOperator; import jdk.jpackage.test.AdditionalLauncher.PropertyFile; @@ -42,6 +44,12 @@ final class PropertyFinder { }; } + default Finder defaultValue(Supplier v) { + return target -> { + return Optional.of(find(target).orElseGet(v)); + }; + } + default Finder map(UnaryOperator v) { Objects.requireNonNull(v); return target -> { @@ -134,7 +142,27 @@ final class PropertyFinder { Finder addLauncherPropertyFileFinder, Finder appImageFileFinder) { + return findLauncherProperty( + cmd, + launcherName, + (theCmd, theLauncherName) -> { + return getAdditionalLauncherProperties(theCmd, theLauncherName); + }, + cmdlineFinder, + addLauncherPropertyFileFinder, + appImageFileFinder); + } + + static Optional findLauncherProperty( + JPackageCommand cmd, + String launcherName, + BiFunction addLauncherPropertyFileGetter, + Finder cmdlineFinder, + Finder addLauncherPropertyFileFinder, + Finder appImageFileFinder) { + Objects.requireNonNull(cmd); + Objects.requireNonNull(addLauncherPropertyFileGetter); Objects.requireNonNull(cmdlineFinder); Objects.requireNonNull(addLauncherPropertyFileFinder); Objects.requireNonNull(appImageFileFinder); @@ -148,7 +176,7 @@ final class PropertyFinder { if (mainLauncher) { reply = cmdlineFinder.find(cmd); } else if (appImageFilePath.isEmpty()) { - var props = getAdditionalLauncherProperties(cmd, launcherName); + var props = addLauncherPropertyFileGetter.apply(cmd, launcherName); reply = addLauncherPropertyFileFinder.find(props); } else { reply = Optional.empty(); diff --git a/test/jdk/tools/jpackage/macosx/SigningPackageTwoStepTest.java b/test/jdk/tools/jpackage/macosx/SigningPackageTwoStepTest.java index 32311fd121e..586d8d68444 100644 --- a/test/jdk/tools/jpackage/macosx/SigningPackageTwoStepTest.java +++ b/test/jdk/tools/jpackage/macosx/SigningPackageTwoStepTest.java @@ -199,10 +199,8 @@ public class SigningPackageTwoStepTest { test.forTypes(signPackage.keySet()).addRunOnceInitializer(() -> { appImageCmd.setArgumentValue("--dest", TKit.createTempDirectory("appimage")).execute(0); - }).addInitializer(cmd -> { + }).usePredefinedAppImage(appImageCmd).addInitializer(cmd -> { MacHelper.useKeychain(cmd, keychain); - cmd.addArguments("--app-image", appImageCmd.outputBundle()); - cmd.removeArgumentWithValue("--input"); Optional.ofNullable(signPackage.get(cmd.packageType())).ifPresent(signOption -> { signOption.setTo(cmd); }); diff --git a/test/jdk/tools/jpackage/share/AddLShortcutTest.java b/test/jdk/tools/jpackage/share/AddLShortcutTest.java index f000e79227e..ef8f277e267 100644 --- a/test/jdk/tools/jpackage/share/AddLShortcutTest.java +++ b/test/jdk/tools/jpackage/share/AddLShortcutTest.java @@ -196,27 +196,22 @@ public class AddLShortcutTest { // and applies shortcut configuration to the main launcher in the native packaging jpackage command. // - Path[] predefinedAppImage = new Path[1]; + var appImageCmd = JPackageCommand.helloAppImage() + .setArgumentValue("--name", "foo") + .setFakeRuntime(); - new PackageTest().addRunOnceInitializer(() -> { - var cmd = JPackageCommand.helloAppImage() - .setArgumentValue("--name", "foo") - .setFakeRuntime(); + for (var i = 1; i != cfgs.length; ++i) { + var al = new AdditionalLauncher("launcher-" + i); + cfgs[i].applyToAdditionalLauncher(al); + al.withoutVerifyActions(Action.EXECUTE_LAUNCHER).applyTo(appImageCmd); + } - for (var i = 1; i != cfgs.length; ++i) { - var al = new AdditionalLauncher("launcher-" + i); - cfgs[i].applyToAdditionalLauncher(al); - al.withoutVerifyActions(Action.EXECUTE_LAUNCHER).applyTo(cmd); - } - - cmd.execute(); - - predefinedAppImage[0] = cmd.outputBundle(); - }).addInitializer(cmd -> { + new PackageTest() + .addRunOnceInitializer(appImageCmd::execute) + .usePredefinedAppImage(appImageCmd) + .addInitializer(cmd -> { cfgs[0].applyToMainLauncher(cmd); - cmd.removeArgumentWithValue("--input"); cmd.setArgumentValue("--name", "AddLShortcutDir2Test"); - cmd.addArguments("--app-image", predefinedAppImage[0]); }).run(RunnablePackageTest.Action.CREATE_AND_UNPACK); } @@ -237,20 +232,15 @@ public class AddLShortcutTest { shortcutArgs.add(startupDirectory.asStringValue()); } - Path[] predefinedAppImage = new Path[1]; + var appImageCmd = JPackageCommand.helloAppImage() + .setArgumentValue("--name", "foo") + .setFakeRuntime(); - new PackageTest().addRunOnceInitializer(() -> { - var cmd = JPackageCommand.helloAppImage() - .setArgumentValue("--name", "foo") - .setFakeRuntime(); - - cmd.execute(); - - predefinedAppImage[0] = cmd.outputBundle(); - }).addInitializer(cmd -> { - cmd.removeArgumentWithValue("--input"); + new PackageTest() + .addRunOnceInitializer(appImageCmd::execute) + .usePredefinedAppImage(appImageCmd) + .addInitializer(cmd -> { cmd.setArgumentValue("--name", "AddLShortcutDir3Test"); - cmd.addArguments("--app-image", predefinedAppImage[0]); cmd.ignoreDefaultVerbose(true); }).addInitializer(cmd -> { cmd.addArguments(shortcutArgs); diff --git a/test/jdk/tools/jpackage/share/AddLauncherTest.java b/test/jdk/tools/jpackage/share/AddLauncherTest.java index 21f475cbd78..2a85de33051 100644 --- a/test/jdk/tools/jpackage/share/AddLauncherTest.java +++ b/test/jdk/tools/jpackage/share/AddLauncherTest.java @@ -275,10 +275,9 @@ public class AddLauncherTest { if (withPredefinedAppImage) { new PackageTest().addInitializer(cmd -> { cmd.setArgumentValue("--name", "Bar"); - // Should not have impact of launcher descriptions, but it does. + // Should not have impact on launcher descriptions, but it does. cmd.setArgumentValue("--description", "Installer"); - cmd.removeArgumentWithValue("--input").setArgumentValue("--app-image", target.cmd().orElseThrow().outputBundle()); - }).mutate(addLinuxShortcuts()).run(Action.CREATE_AND_UNPACK); + }).usePredefinedAppImage(target.cmd().orElseThrow()).mutate(addLinuxShortcuts()).run(Action.CREATE_AND_UNPACK); } } diff --git a/test/jdk/tools/jpackage/share/AppContentTest.java b/test/jdk/tools/jpackage/share/AppContentTest.java index 5b5734df61d..97c83bba57d 100644 --- a/test/jdk/tools/jpackage/share/AppContentTest.java +++ b/test/jdk/tools/jpackage/share/AppContentTest.java @@ -499,11 +499,11 @@ public class AppContentTest { return new FileContentFactory(() -> { var basedir = TKit.createTempDirectory("content").resolve(path); - for (var textFile : Map.ofEntries( + for (var textFile : List.of( entry("woods/moose", "The moose"), entry("woods/bear", "The bear"), entry("woods/trees/jay", "The gray jay") - ).entrySet()) { + )) { var src = basedir.resolve(textFile.getKey()); Files.createDirectories(src.getParent()); TKit.createTextFile(src, Stream.of(textFile.getValue())); diff --git a/test/jdk/tools/jpackage/share/AppImagePackageTest.java b/test/jdk/tools/jpackage/share/AppImagePackageTest.java index aacb76b122b..94eb086e4c6 100644 --- a/test/jdk/tools/jpackage/share/AppImagePackageTest.java +++ b/test/jdk/tools/jpackage/share/AppImagePackageTest.java @@ -62,15 +62,12 @@ public class AppImagePackageTest { @Test public static void test() { - var appImageCmd = JPackageCommand.helloAppImage() - .setArgumentValue("--dest", TKit.createTempDirectory("appimage")); + final var appImageCmd = createAppImageCommand(); new PackageTest() .addRunOnceInitializer(appImageCmd::execute) - .addInitializer(cmd -> { - cmd.addArguments("--app-image", appImageCmd.outputBundle()); - cmd.removeArgumentWithValue("--input"); - }).addBundleDesktopIntegrationVerifier(false).run(); + .usePredefinedAppImage(appImageCmd) + .addBundleDesktopIntegrationVerifier(false).run(); } /** @@ -85,10 +82,7 @@ public class AppImagePackageTest { @Parameter("false") public static void testEmpty(boolean withIcon) throws IOException { - var appImageCmd = JPackageCommand.helloAppImage() - .setFakeRuntime() - .setArgumentValue("--name", "EmptyAppImagePackageTest") - .setArgumentValue("--dest", TKit.createTempDirectory("appimage")); + final var appImageCmd = createAppImageCommand(); new PackageTest() .addRunOnceInitializer(appImageCmd::execute) @@ -116,12 +110,11 @@ public class AppImagePackageTest { TKit.trace("Done"); } }) + .usePredefinedAppImage(appImageCmd) .addInitializer(cmd -> { - cmd.addArguments("--app-image", appImageCmd.outputBundle()); if (withIcon) { - cmd.addArguments("--icon", iconPath("icon")); + cmd.setArgumentValue("--icon", iconPath("icon")); } - cmd.removeArgumentWithValue("--input"); cmd.excludeStandardAsserts( StandardAssert.MAIN_JAR_FILE, @@ -160,10 +153,8 @@ public class AppImagePackageTest { */ @Test public static void testBadAppImage3() { - Path appImageDir = TKit.createTempDirectory("appimage"); - JPackageCommand appImageCmd = JPackageCommand.helloAppImage(). - setFakeRuntime().setArgumentValue("--dest", appImageDir); + final var appImageCmd = createAppImageCommand(); configureBadAppImage(appImageCmd.outputBundle()).addRunOnceInitializer(() -> { appImageCmd.execute(); @@ -176,10 +167,8 @@ public class AppImagePackageTest { */ @Test public static void testBadAppImageFile() { - final var appImageRoot = TKit.createTempDirectory("appimage"); - final var appImageCmd = JPackageCommand.helloAppImage(). - setFakeRuntime().setArgumentValue("--dest", appImageRoot); + final var appImageCmd = createAppImageCommand(); final var appImageDir = appImageCmd.outputBundle(); @@ -202,13 +191,17 @@ public class AppImagePackageTest { private static PackageTest configureBadAppImage(Path appImageDir, CannedFormattedString expectedError) { return new PackageTest().addInitializer(cmd -> { - cmd.addArguments("--app-image", appImageDir); - cmd.removeArgumentWithValue("--input"); + cmd.usePredefinedAppImage(appImageDir); cmd.ignoreDefaultVerbose(true); // no "--verbose" option cmd.validateOutput(expectedError); }).setExpectedExitCode(1); } + private static JPackageCommand createAppImageCommand() { + final var appImageRoot = TKit.createTempDirectory("appimage"); + return JPackageCommand.helloAppImage().setFakeRuntime().setArgumentValue("--dest", appImageRoot); + } + private static Path iconPath(String name) { return TKit.TEST_SRC_ROOT.resolve(Path.of("resources", name + TKit.ICON_SUFFIX)); diff --git a/test/jdk/tools/jpackage/share/InstallDirTest.java b/test/jdk/tools/jpackage/share/InstallDirTest.java index 5106eed3fc6..db22077cd62 100644 --- a/test/jdk/tools/jpackage/share/InstallDirTest.java +++ b/test/jdk/tools/jpackage/share/InstallDirTest.java @@ -34,8 +34,6 @@ import jdk.jpackage.test.JPackageStringBundle; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.RunnablePackageTest.Action; -import jdk.jpackage.test.TKit; -import jdk.jpackage.test.TKit.TextStreamVerifier; /** * Test --install-dir parameter. Output of the test should be @@ -113,9 +111,9 @@ public class InstallDirTest { .run(); } - record DmgTestSpec(Path installDir, boolean runtimeInstaller) { + record TestSpec(Path installDir, boolean runtimeInstaller) { - DmgTestSpec { + TestSpec { Objects.requireNonNull(installDir); } @@ -135,8 +133,8 @@ public class InstallDirTest { return this; } - DmgTestSpec create() { - return new DmgTestSpec(installDir, runtimeInstaller); + TestSpec create() { + return new TestSpec(installDir, runtimeInstaller); } private Path installDir; @@ -154,7 +152,7 @@ public class InstallDirTest { } void run() { - final var test = new PackageTest().forTypes(PackageType.MAC_DMG).ignoreBundleOutputDir(); + final var test = new PackageTest().ignoreBundleOutputDir(); if (runtimeInstaller) { test.addInitializer(cmd -> { cmd.removeArgumentWithValue("--input"); @@ -164,33 +162,33 @@ public class InstallDirTest { } test.addInitializer(JPackageCommand::setFakeRuntime).addInitializer(cmd -> { - cmd.addArguments("--install-dir", installDir); + cmd.setArgumentValue("--install-dir", installDir); }).run(Action.CREATE_AND_UNPACK); } } @Test(ifOS = OperatingSystem.MACOS) @ParameterSupplier - public static void testDmg(DmgTestSpec testSpec) { + public static void testMac(TestSpec testSpec) { testSpec.run(); } - public static List testDmg() { + public static List testMac() { return Stream.of( - DmgTestSpec.build().acceptedInstallDir("/foo"), - DmgTestSpec.build().acceptedInstallDir("/foo/bar"), - DmgTestSpec.build().acceptedInstallDir("/foo").runtimeInstaller(), - DmgTestSpec.build().acceptedInstallDir("/foo/bar").runtimeInstaller(), + TestSpec.build().acceptedInstallDir("/foo"), + TestSpec.build().acceptedInstallDir("/foo/bar"), + TestSpec.build().acceptedInstallDir("/foo").runtimeInstaller(), + TestSpec.build().acceptedInstallDir("/foo/bar").runtimeInstaller(), - DmgTestSpec.build().acceptedInstallDir("/Library/Java/JavaVirtualMachines"), - DmgTestSpec.build().acceptedInstallDir("/Applications").runtimeInstaller(), + TestSpec.build().acceptedInstallDir("/Library/Java/JavaVirtualMachines"), + TestSpec.build().acceptedInstallDir("/Applications").runtimeInstaller(), - DmgTestSpec.build().acceptedInstallDir("/Applications"), - DmgTestSpec.build().acceptedInstallDir("/Applications/foo/bar/buz"), + TestSpec.build().acceptedInstallDir("/Applications"), + TestSpec.build().acceptedInstallDir("/Applications/foo/bar/buz"), - DmgTestSpec.build().runtimeInstaller().acceptedInstallDir("/Library/Java/JavaVirtualMachines"), - DmgTestSpec.build().runtimeInstaller().acceptedInstallDir("/Library/Java/JavaVirtualMachines/foo/bar/buz") - ).map(DmgTestSpec.Builder::create).map(testSpec -> { + TestSpec.build().runtimeInstaller().acceptedInstallDir("/Library/Java/JavaVirtualMachines"), + TestSpec.build().runtimeInstaller().acceptedInstallDir("/Library/Java/JavaVirtualMachines/foo/bar/buz") + ).map(TestSpec.Builder::create).map(testSpec -> { return new Object[] { testSpec }; }).toList(); } diff --git a/test/jdk/tools/jpackage/share/MultiLauncherTwoPhaseTest.java b/test/jdk/tools/jpackage/share/MultiLauncherTwoPhaseTest.java index d348b5c170d..0786255893f 100644 --- a/test/jdk/tools/jpackage/share/MultiLauncherTwoPhaseTest.java +++ b/test/jdk/tools/jpackage/share/MultiLauncherTwoPhaseTest.java @@ -22,13 +22,12 @@ */ import java.nio.file.Path; -import java.io.IOException; import jdk.jpackage.test.AdditionalLauncher; +import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.TKit; -import jdk.jpackage.test.Annotations.Test; -import jdk.jpackage.test.JPackageCommand; /** * Test multiple launchers in two phases. First test creates app image and then @@ -55,7 +54,7 @@ import jdk.jpackage.test.JPackageCommand; public class MultiLauncherTwoPhaseTest { @Test - public static void test() throws IOException { + public static void test() { Path appimageOutput = TKit.createTempDirectory("appimage"); JPackageCommand appImageCmd = JPackageCommand.helloAppImage() @@ -68,12 +67,9 @@ public class MultiLauncherTwoPhaseTest { launcher2.applyTo(appImageCmd); PackageTest packageTest = new PackageTest() - .addRunOnceInitializer(() -> appImageCmd.execute()) + .addRunOnceInitializer(appImageCmd::execute) .addBundleDesktopIntegrationVerifier(true) - .addInitializer(cmd -> { - cmd.addArguments("--app-image", appImageCmd.outputBundle()); - cmd.removeArgumentWithValue("--input"); - }) + .usePredefinedAppImage(appImageCmd) .forTypes(PackageType.WINDOWS) .addInitializer(cmd -> { cmd.addArguments("--win-shortcut", "--win-menu", diff --git a/test/jdk/tools/jpackage/share/MultiNameTwoPhaseTest.java b/test/jdk/tools/jpackage/share/MultiNameTwoPhaseTest.java index de8412c2839..6d4c597cb51 100644 --- a/test/jdk/tools/jpackage/share/MultiNameTwoPhaseTest.java +++ b/test/jdk/tools/jpackage/share/MultiNameTwoPhaseTest.java @@ -22,13 +22,12 @@ */ import java.nio.file.Path; -import java.io.IOException; +import jdk.jpackage.test.Annotations.Parameter; +import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.TKit; -import jdk.jpackage.test.Annotations.Test; -import jdk.jpackage.test.Annotations.Parameter; -import jdk.jpackage.test.JPackageCommand; /** * Test creation of packages in tho phases with different names. @@ -58,9 +57,7 @@ public class MultiNameTwoPhaseTest { @Parameter({"MultiNameTest", ""}) @Parameter({"", "MultiNameTestInstaller"}) @Parameter({"", ""}) - public static void test(String... testArgs) throws IOException { - String appName = testArgs[0]; - String installName = testArgs[1]; + public static void test(String appName, String installName) { Path appimageOutput = TKit.createTempDirectory("appimage"); @@ -74,9 +71,8 @@ public class MultiNameTwoPhaseTest { PackageTest packageTest = new PackageTest() .addRunOnceInitializer(() -> appImageCmd.execute()) .addBundleDesktopIntegrationVerifier(true) + .usePredefinedAppImage(appImageCmd) .addInitializer(cmd -> { - cmd.addArguments("--app-image", appImageCmd.outputBundle()); - cmd.removeArgumentWithValue("--input"); cmd.removeArgumentWithValue("--name"); if (!installName.isEmpty()) { cmd.addArguments("--name", installName); diff --git a/test/jdk/tools/jpackage/share/PostImageScriptTest.java b/test/jdk/tools/jpackage/share/PostImageScriptTest.java index 68ded999e4a..5e9127d8fa8 100644 --- a/test/jdk/tools/jpackage/share/PostImageScriptTest.java +++ b/test/jdk/tools/jpackage/share/PostImageScriptTest.java @@ -107,10 +107,7 @@ public class PostImageScriptTest { }); } case EXTERNAL_APP_IMAGE -> { - test.addInitializer(cmd -> { - cmd.removeArgumentWithValue("--input"); - cmd.addArguments("--app-image", appImageCmd.outputBundle()); - }); + test.usePredefinedAppImage(appImageCmd); } } diff --git a/test/jdk/tools/jpackage/share/ServiceTest.java b/test/jdk/tools/jpackage/share/ServiceTest.java index 56e003f508c..226f8f16bdc 100644 --- a/test/jdk/tools/jpackage/share/ServiceTest.java +++ b/test/jdk/tools/jpackage/share/ServiceTest.java @@ -243,10 +243,7 @@ public class ServiceTest { new PackageTest().excludeTypes(MAC_DMG) .addRunOnceInitializer(appImageCmd.cmd().orElseThrow()::execute) - .addInitializer(cmd -> { - cmd.removeArgumentWithValue("--input"); - cmd.addArguments("--app-image", appImageCmd.cmd().orElseThrow().outputBundle()); - }) + .usePredefinedAppImage(appImageCmd.cmd().orElseThrow()) .addInitializer(cmd -> { if (mainLauncherAsService) { cmd.addArgument("--launcher-as-service"); diff --git a/test/jdk/tools/jpackage/windows/Win8282351Test.java b/test/jdk/tools/jpackage/windows/Win8282351Test.java index 55357437762..93731c7cfc6 100644 --- a/test/jdk/tools/jpackage/windows/Win8282351Test.java +++ b/test/jdk/tools/jpackage/windows/Win8282351Test.java @@ -24,9 +24,11 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import jdk.jpackage.test.PackageTest; -import jdk.jpackage.test.JPackageCommand; +import java.util.List; +import java.util.stream.Stream; import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.JPackageCommand; +import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.RunnablePackageTest.Action; import jdk.jpackage.test.TKit; @@ -48,13 +50,13 @@ import jdk.jpackage.test.TKit; public class Win8282351Test { @Test - public void test() throws IOException { + public void test() { Path appimageOutput = TKit.createTempDirectory("appimage"); JPackageCommand appImageCmd = JPackageCommand.helloAppImage() .setFakeRuntime().setArgumentValue("--dest", appimageOutput); - String[] filesWithDollarCharsInNames = new String[]{ + var filesWithDollarCharsInNames = Stream.of( "Pane$$anon$$greater$1.class", "$", "$$", @@ -63,11 +65,11 @@ public class Win8282351Test { "$$$$$", "foo$.class", "1$b$$a$$$r$$$$.class" - }; + ).map(Path::of).toList(); - String[] dirsWithDollarCharsInNames = new String[]{ - Path.of("foo", String.join("/", filesWithDollarCharsInNames)).toString() - }; + var dirsWithDollarCharsInNames = List.of( + filesWithDollarCharsInNames.stream().reduce(Path.of("foo"), Path::resolve) + ); String name = appImageCmd.name() + "$-$$-$$$"; @@ -75,7 +77,7 @@ public class Win8282351Test { .addRunOnceInitializer(() -> { appImageCmd.execute(); for (var path : filesWithDollarCharsInNames) { - createImageFile(appImageCmd, Path.of(path)); + createImageFile(appImageCmd, path); } for (var path : dirsWithDollarCharsInNames) { @@ -83,16 +85,15 @@ public class Win8282351Test { appImageCmd.outputBundle().resolve(path)); } }) + .usePredefinedAppImage(appImageCmd) .addInitializer(cmd -> { cmd.setArgumentValue("--name", name); - cmd.addArguments("--app-image", appImageCmd.outputBundle()); - cmd.removeArgumentWithValue("--input"); cmd.addArgument("--win-menu"); cmd.addArgument("--win-shortcut"); }) .addInstallVerifier(cmd -> { for (var path : filesWithDollarCharsInNames) { - verifyImageFile(appImageCmd, Path.of(path)); + verifyImageFile(appImageCmd, path); } for (var path : dirsWithDollarCharsInNames) {