diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java index af892f18f7b..1466714f8dd 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java @@ -296,7 +296,9 @@ final public class TKit { if (!path.toFile().exists()) { return path; } - nameComponents[0] = String.format("%s.%d", baseName, i); + // Don't use period (.) as a separator. OSX codesign fails to sign folders + // with subfolders with names like "input.0". + nameComponents[0] = String.format("%s-%d", baseName, i); } throw new IllegalStateException(String.format( "Failed to create unique file name from [%s] basename after %d attempts", diff --git a/test/jdk/tools/jpackage/share/AppContentTest.java b/test/jdk/tools/jpackage/share/AppContentTest.java index a343e20d8a7..94362530751 100644 --- a/test/jdk/tools/jpackage/share/AppContentTest.java +++ b/test/jdk/tools/jpackage/share/AppContentTest.java @@ -21,23 +21,25 @@ * questions. */ -import java.nio.file.Path; +import java.io.IOException; import java.nio.file.Files; -import jdk.jpackage.internal.ApplicationLayout; +import java.nio.file.Path; 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.Annotations.Parameters; import java.util.Arrays; import java.util.Collection; import java.util.List; +import static java.util.stream.Collectors.joining; +import java.util.stream.Stream; +import jdk.jpackage.internal.IOUtils; +import jdk.jpackage.test.Functional.ThrowingFunction; +import jdk.jpackage.test.JPackageCommand; -import jdk.internal.util.OSVersion; /** - * Tests generation of packages with input folder containing empty folders. + * Tests generation of packages with additional content in app image. */ /* @@ -55,14 +57,18 @@ import jdk.internal.util.OSVersion; */ public class AppContentTest { - private static final String TEST_JAVA = TKit.TEST_SRC_ROOT.resolve( - "apps/PrintEnv.java").toString(); - private static final String TEST_DUKE = TKit.TEST_SRC_ROOT.resolve( - "apps/dukeplug.png").toString(); - private static final String TEST_DIR = TKit.TEST_SRC_ROOT.resolve( - "apps").toString(); - private static final String TEST_BAD = TKit.TEST_SRC_ROOT.resolve( - "non-existant").toString(); + private static final String TEST_JAVA = "apps/PrintEnv.java"; + private static final String TEST_DUKE = "apps/dukeplug.png"; + private static final String TEST_DIR = "apps"; + private static final String TEST_BAD = "non-existant"; + + // On OSX `--app-content` paths will be copied into the "Contents" folder + // of the output app image. + // "codesign" imposes restrictions on the directory structure of "Contents" folder. + // In particular, random files should be placed in "Contents/Resources" folder + // otherwise "codesign" will fail to sign. + // Need to prepare arguments for `--app-content` accordingly. + private final static boolean copyInResources = TKit.isOSX(); private final List testPathArgs; @@ -82,37 +88,90 @@ public class AppContentTest { @Test public void test() throws Exception { - - // On macOS signing may or may not work for modified app bundles. - // It works on macOS 15 and up, but fails on macOS below 15. final int expectedJPackageExitCode; - final boolean isMacOS15 = (OSVersion.current().compareTo( - new OSVersion(15, 0, 0)) > 0); - if (testPathArgs.contains(TEST_BAD) || (TKit.isOSX() && !isMacOS15)) { + if (testPathArgs.contains(TEST_BAD)) { expectedJPackageExitCode = 1; } else { expectedJPackageExitCode = 0; } + var appContentInitializer = new AppContentInitializer(testPathArgs); + new PackageTest().configureHelloApp() - .addInitializer(cmd -> { - for (String arg : testPathArgs) { - cmd.addArguments("--app-content", arg); - } - }) + .addRunOnceInitializer(appContentInitializer::initAppContent) + .addInitializer(appContentInitializer::applyTo) .addInstallVerifier(cmd -> { - ApplicationLayout appLayout = cmd.appLayout(); - Path contentDir = appLayout.contentDirectory(); + Path baseDir = getAppContentRoot(cmd); for (String arg : testPathArgs) { List paths = Arrays.asList(arg.split(",")); for (String p : paths) { Path name = Path.of(p).getFileName(); - TKit.assertPathExists(contentDir.resolve(name), true); + TKit.assertPathExists(baseDir.resolve(name), true); } } }) .setExpectedExitCode(expectedJPackageExitCode) .run(); + } + + private static Path getAppContentRoot(JPackageCommand cmd) { + Path contentDir = cmd.appLayout().contentDirectory(); + if (copyInResources) { + return contentDir.resolve("Resources"); + } else { + return contentDir; } + } + + private static final class AppContentInitializer { + AppContentInitializer(List appContentArgs) { + appContentPathGroups = appContentArgs.stream().map(arg -> { + return Stream.of(arg.split(",")).map(Path::of).toList(); + }).toList(); + } + + void initAppContent() { + jpackageArgs = appContentPathGroups.stream() + .map(AppContentInitializer::initAppContentPaths) + .mapMulti((appContentPaths, consumer) -> { + consumer.accept("--app-content"); + consumer.accept( + appContentPaths.stream().map(Path::toString).collect( + joining(","))); + }).toList(); + } + + void applyTo(JPackageCommand cmd) { + cmd.addArguments(jpackageArgs); + } + + private static Path copyAppContentPath(Path appContentPath) throws IOException { + var appContentArg = TKit.createTempDirectory("app-content").resolve("Resources"); + var srcPath = TKit.TEST_SRC_ROOT.resolve(appContentPath); + var dstPath = appContentArg.resolve(srcPath.getFileName()); + Files.createDirectories(dstPath.getParent()); + IOUtils.copyRecursive(srcPath, dstPath); + return appContentArg; + } + + private static List initAppContentPaths(List appContentPaths) { + if (copyInResources) { + return appContentPaths.stream().map(appContentPath -> { + if (appContentPath.endsWith(TEST_BAD)) { + return appContentPath; + } else { + return ThrowingFunction.toFunction( + AppContentInitializer::copyAppContentPath).apply( + appContentPath); + } + }).toList(); + } else { + return appContentPaths.stream().map(TKit.TEST_SRC_ROOT::resolve).toList(); + } + } + + private List jpackageArgs; + private final List> appContentPathGroups; + } }