# HG changeset patch # User herrick # Date 1571236328 14400 # Node ID 3bf53ffa9ae779f028c3e988914aa25566b9bee5 # Parent 2c43b89b1679c8986b2fe62b3fd415ee0f77bc6e 8232279 : Improve test helpers #2 Submitted-by: asemenyuk Reviewed-by: aherrick, almatvee diff -r 2c43b89b1679 -r 3bf53ffa9ae7 src/jdk.jpackage/share/classes/jdk/jpackage/internal/ApplicationLayout.java --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ApplicationLayout.java Wed Oct 16 09:57:23 2019 -0400 +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ApplicationLayout.java Wed Oct 16 10:32:08 2019 -0400 @@ -129,8 +129,6 @@ )); } - - public static ApplicationLayout platformAppImage() { if (Platform.isWindows()) { return windowsAppImage(); @@ -147,7 +145,7 @@ throw Platform.throwUnknownPlatformError(); } - static ApplicationLayout javaRuntime() { + public static ApplicationLayout javaRuntime() { return new ApplicationLayout(Map.of(PathRole.RUNTIME, Path.of(""))); } diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Annotations.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Annotations.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Annotations.java Wed Oct 16 10:32:08 2019 -0400 @@ -32,21 +32,36 @@ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) + public @interface BeforeEach { + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public @interface AfterEach { + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) public @interface Test { } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) - @Repeatable(Parameters.class) + @Repeatable(ParameterGroup.class) public @interface Parameter { - String value(); + String[] value(); + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public @interface ParameterGroup { + + Parameter[] value(); } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Parameters { - - Parameter[] value(); } } diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CfgFile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CfgFile.java Wed Oct 16 10:32:08 2019 -0400 @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2019, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.test; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public final class CfgFile { + public String getValue(String section, String key) { + Objects.requireNonNull(section); + Objects.requireNonNull(key); + + Map entries = data.get(section); + TKit.assertTrue(entries != null, String.format( + "Check section [%s] is found in [%s] cfg file", section, id)); + + String value = entries.get(key); + TKit.assertNotNull(value, String.format( + "Check key [%s] is found in [%s] section of [%s] cfg file", key, + section, id)); + + return value; + } + + private CfgFile(Map> data, String id) { + this.data = data; + this.id = id; + } + + public static CfgFile readFromFile(Path path) throws IOException { + TKit.trace(String.format("Read [%s] jpackage cfg file", path)); + + final Pattern sectionBeginRegex = Pattern.compile( "\\s*\\[([^]]*)\\]\\s*"); + final Pattern keyRegex = Pattern.compile( "\\s*([^=]*)=(.*)" ); + + Map> result = new HashMap<>(); + + String currentSectionName = null; + Map currentSection = new HashMap<>(); + for (String line : Files.readAllLines(path)) { + Matcher matcher = sectionBeginRegex.matcher(line); + if (matcher.find()) { + if (currentSectionName != null) { + result.put(currentSectionName, Collections.unmodifiableMap( + new HashMap<>(currentSection))); + } + currentSectionName = matcher.group(1); + currentSection.clear(); + continue; + } + + matcher = keyRegex.matcher(line); + if (matcher.find()) { + currentSection.put(matcher.group(1), matcher.group(2)); + continue; + } + } + + if (!currentSection.isEmpty()) { + result.put("", Collections.unmodifiableMap(currentSection)); + } + + return new CfgFile(Collections.unmodifiableMap(result), path.toString()); + } + + private final Map> data; + private final String id; +} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java Wed Oct 16 10:32:08 2019 -0400 @@ -59,6 +59,10 @@ return this; } + public Executor setToolProvider(JavaTool v) { + return setToolProvider(v.asToolProvider()); + } + public Executor setDirectory(Path v) { directory = v; return this; @@ -167,6 +171,11 @@ } public Result execute() { + if (toolProvider != null && directory != null) { + throw new IllegalArgumentException( + "Can't change directory when using tool provider"); + } + return ThrowingSupplier.toSupplier(() -> { if (toolProvider != null) { return runToolProvider(); @@ -193,9 +202,22 @@ SaveOutputType.FIRST_LINE); } + private Path executablePath() { + if (directory == null || executable.isAbsolute()) { + return executable; + } + + // If relative path to executable is used it seems to be broken when + // ProcessBuilder changes the directory. On Windows it changes the + // directory first and on Linux it looks up for executable before + // changing the directory. So to stay of safe side, use absolute path + // to executable. + return executable.toAbsolutePath(); + } + private Result runExecutable() throws IOException, InterruptedException { List command = new ArrayList<>(); - command.add(executable.toString()); + command.add(executablePath().toString()); command.addAll(args); ProcessBuilder builder = new ProcessBuilder(command); StringBuilder sb = new StringBuilder(getPrintableCommandLine()); @@ -315,7 +337,7 @@ format = "tool provider " + format; exec = toolProvider.name(); } else { - exec = executable.toString(); + exec = executablePath().toString(); } return String.format(format, printCommandLine(exec, args), diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java Wed Oct 16 10:32:08 2019 -0400 @@ -37,43 +37,27 @@ public class HelloApp { - private HelloApp() { - setClassName(CLASS_NAME).setJarFileName("hello.jar"); - } - - /** - * Set fully qualified class name. E.g: foo.bar.Buzz. - */ - private HelloApp setClassName(String v) { - qualifiedClassName = v; - return this; - } - - private HelloApp setModuleName(String v) { - moduleName = v; - return this; - } - - private HelloApp setJarFileName(String v) { - jarFileName = v; - return this; - } - - private HelloApp setModuleVersion(String v) { - moduleVersion = v; - return this; + HelloApp(JavaAppDesc appDesc) { + if (appDesc == null) { + this.appDesc = createDefaltAppDesc(); + } else { + this.appDesc = appDesc; + } } private JarBuilder prepareSources(Path srcDir) throws IOException { + final String qualifiedClassName = appDesc.className(); + final String className = qualifiedClassName.substring( qualifiedClassName.lastIndexOf('.') + 1); - final String packageName = packageName(); + final String packageName = appDesc.packageName(); final Path srcFile = srcDir.resolve(Path.of(String.join( File.separator, qualifiedClassName.split("\\.")) + ".java")); Files.createDirectories(srcFile.getParent()); JarBuilder jarBuilder = createJarBuilder().addSourceFile(srcFile); + final String moduleName = appDesc.moduleName(); if (moduleName != null) { Path moduleInfoFile = srcDir.resolve("module-info.java"); TKit.createTextFile(moduleInfoFile, List.of( @@ -82,9 +66,7 @@ "}" )); jarBuilder.addSourceFile(moduleInfoFile); - if (moduleVersion != null) { - jarBuilder.setModuleVersion(moduleVersion); - } + jarBuilder.setModuleVersion(appDesc.moduleVersion()); } // Add package directive and replace class name in java source file. @@ -124,11 +106,19 @@ } private JarBuilder createJarBuilder() { - return new JarBuilder().setMainClass(qualifiedClassName); + JarBuilder builder = new JarBuilder(); + if (appDesc.jarWithMainClass()) { + builder.setMainClass(appDesc.className()); + } + return builder; } - private void addTo(JPackageCommand cmd) { - if (moduleName != null && packageName() == null) { + void addTo(JPackageCommand cmd) { + final String moduleName = appDesc.moduleName(); + final String jarFileName = appDesc.jarFileName(); + final String qualifiedClassName = appDesc.className(); + + if (moduleName != null && appDesc.packageName() == null) { throw new IllegalArgumentException(String.format( "Module [%s] with default package", moduleName)); } @@ -177,55 +167,9 @@ } } - private String packageName() { - int lastDotIdx = qualifiedClassName.lastIndexOf('.'); - if (lastDotIdx == -1) { - return null; - } - return qualifiedClassName.substring(0, lastDotIdx); - } - - /** - * Configures Java application to be used with the given jpackage command. - * Syntax of encoded Java application description is - * [jar_file:][module_name/]qualified_class_name[@module_version]. - * - * E.g.: duke.jar:com.other/com.other.foo.bar.Buz@3.7 encodes modular - * application. Module name is `com.other`. Main class is - * `com.other.foo.bar.Buz`. Module version is `3.7`. Application will be - * compiled and packed in `duke.jar` jar file. - * - * @param cmd jpackage command to configure - * @param javaAppDesc encoded Java application description - */ - static void addTo(JPackageCommand cmd, String javaAppDesc) { - HelloApp helloApp = new HelloApp(); - if (javaAppDesc != null) { - String moduleNameAndOther = Functional.identity(() -> { - String[] components = javaAppDesc.split(":", 2); - if (components.length == 2) { - helloApp.setJarFileName(components[0]); - } - return components[components.length - 1]; - }).get(); - - String classNameAndOther = Functional.identity(() -> { - String[] components = moduleNameAndOther.split("/", 2); - if (components.length == 2) { - helloApp.setModuleName(components[0]); - } - return components[components.length - 1]; - }).get(); - - Functional.identity(() -> { - String[] components = classNameAndOther.split("@", 2); - helloApp.setClassName(components[0]); - if (components.length == 2) { - helloApp.setModuleVersion(components[1]); - } - }).run(); - } - helloApp.addTo(cmd); + static JavaAppDesc createDefaltAppDesc() { + return new JavaAppDesc().setClassName(CLASS_NAME).setJarFileName( + "hello.jar"); } static void verifyOutputFile(Path outputFile, List args) { @@ -250,24 +194,12 @@ } public static void executeLauncherAndVerifyOutput(JPackageCommand cmd) { - final Path launcherPath; - if (cmd.packageType() == PackageType.IMAGE) { - launcherPath = cmd.appImage().resolve(cmd.launcherPathInAppImage()); - if (cmd.isFakeRuntimeInAppImage(String.format( - "Not running [%s] launcher from application image", - launcherPath))) { - return; - } - } else { - launcherPath = cmd.launcherInstallationPath(); - if (cmd.isFakeRuntimeInstalled(String.format( - "Not running [%s] launcher", launcherPath))) { - return; - } + final Path launcherPath = cmd.appLauncherPath(); + if (!cmd.isFakeRuntime(String.format("Not running [%s] launcher", + launcherPath))) { + executeAndVerifyOutput(launcherPath, cmd.getAllArgumentValues( + "--arguments")); } - - executeAndVerifyOutput(launcherPath, cmd.getAllArgumentValues( - "--arguments")); } public static void executeAndVerifyOutput(Path helloAppLauncher, @@ -278,7 +210,7 @@ public static void executeAndVerifyOutput(Path helloAppLauncher, List defaultLauncherArgs) { // Output file will be created in the current directory. - Path outputFile = Path.of(OUTPUT_FILENAME); + Path outputFile = TKit.workDir().resolve(OUTPUT_FILENAME); ThrowingFunction.toFunction(Files::deleteIfExists).apply(outputFile); new Executor() .setDirectory(outputFile.getParent()) @@ -291,10 +223,7 @@ final static String OUTPUT_FILENAME = "appOutput.txt"; - private String qualifiedClassName; - private String moduleName; - private String jarFileName; - private String moduleVersion; + private final JavaAppDesc appDesc; private static final Path HELLO_JAVA = TKit.TEST_SRC_ROOT.resolve( "apps/image/Hello.java"); diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java Wed Oct 16 10:32:08 2019 -0400 @@ -31,10 +31,13 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; +import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.jpackage.internal.ApplicationLayout; import jdk.jpackage.test.Functional.ThrowingConsumer; +import jdk.jpackage.test.Functional.ThrowingFunction; /** * jpackage command line with prerequisite actions. Prerequisite actions can be @@ -47,10 +50,20 @@ actions = new ArrayList<>(); } + public JPackageCommand(JPackageCommand cmd) { + this(); + args.addAll(cmd.args); + withToolProvider = cmd.withToolProvider; + saveConsoleOutput = cmd.saveConsoleOutput; + suppressOutput = cmd.suppressOutput; + ignoreDefaultRuntime = cmd.ignoreDefaultRuntime; + immutable = cmd.immutable; + actionsExecuted = cmd.actionsExecuted; + } + JPackageCommand createImmutableCopy() { - JPackageCommand reply = new JPackageCommand(); + JPackageCommand reply = new JPackageCommand(this); reply.immutable = true; - reply.args.addAll(args); return reply; } @@ -152,6 +165,11 @@ return addArguments(name, value.toString()); } + public boolean isImagePackageType() { + return PackageType.IMAGE == getArgumentValue("--package-type", + () -> null, PACKAGE_TYPES::get); + } + public PackageType packageType() { // Don't try to be in sync with jpackage defaults. Keep it simple: // if no `--package-type` explicitely set on the command line, consider @@ -194,8 +212,21 @@ public JPackageCommand setFakeRuntime() { verifyMutable(); - try { + ThrowingConsumer createBulkFile = path -> { + Files.createDirectories(path.getParent()); + try (FileOutputStream out = new FileOutputStream(path.toFile())) { + byte[] bytes = new byte[4 * 1024]; + new SecureRandom().nextBytes(bytes); + out.write(bytes); + } + }; + + addAction(cmd -> { Path fakeRuntimeDir = TKit.workDir().resolve("fake_runtime"); + + TKit.trace(String.format("Init fake runtime in [%s] directory", + fakeRuntimeDir)); + Files.createDirectories(fakeRuntimeDir); if (TKit.isWindows() || TKit.isLinux()) { @@ -206,22 +237,19 @@ fakeRuntimeDir.resolve("bin").toFile().mkdir(); } - Path bulk = fakeRuntimeDir.resolve(Path.of("bin", "bulk")); + if (TKit.isOSX()) { + // Make MacAppImageBuilder happy + createBulkFile.accept(fakeRuntimeDir.resolve(Path.of( + "Contents/Home/lib/jli/libjli.dylib"))); + } // Mak sure fake runtime takes some disk space. // Package bundles with 0KB size are unexpected and considered // an error by PackageTest. - Files.createDirectories(bulk.getParent()); - try (FileOutputStream out = new FileOutputStream(bulk.toFile())) { - byte[] bytes = new byte[4 * 1024]; - new SecureRandom().nextBytes(bytes); - out.write(bytes); - } + createBulkFile.accept(fakeRuntimeDir.resolve(Path.of("bin", "bulk"))); - addArguments("--runtime-image", fakeRuntimeDir); - } catch (IOException ex) { - throw new RuntimeException(ex); - } + cmd.addArguments("--runtime-image", fakeRuntimeDir); + }); return this; } @@ -232,23 +260,37 @@ return this; } + /** + * Shorthand for {@code helloAppImage(null)}. + */ public static JPackageCommand helloAppImage() { - return helloAppImage(null); + JavaAppDesc javaAppDesc = null; + return helloAppImage(javaAppDesc); } /** * Creates new JPackageCommand instance configured with the test Java app. * For the explanation of `javaAppDesc` parameter, see documentation for - * HelloApp.addTo() method. + * #JavaAppDesc.parse() method. * * @param javaAppDesc Java application description * @return this */ public static JPackageCommand helloAppImage(String javaAppDesc) { + final JavaAppDesc appDesc; + if (javaAppDesc == null) { + appDesc = null; + } else { + appDesc = JavaAppDesc.parse(javaAppDesc); + } + return helloAppImage(appDesc); + } + + public static JPackageCommand helloAppImage(JavaAppDesc javaAppDesc) { JPackageCommand cmd = new JPackageCommand(); cmd.setDefaultInputOutput().setDefaultAppName(); PackageType.IMAGE.applyTo(cmd); - HelloApp.addTo(cmd, javaAppDesc); + new HelloApp(javaAppDesc).addTo(cmd); return cmd; } @@ -262,37 +304,70 @@ return addArguments("--name", TKit.getCurrentDefaultAppName()); } + /** + * Returns path to output bundle of configured jpackage command. + * + * If this is build image command, returns path to application image directory. + */ public Path outputBundle() { - final PackageType type = packageType(); - if (PackageType.IMAGE == type) { - return null; - } - - String bundleName = null; - if (PackageType.LINUX.contains(type)) { + final String bundleName; + if (isImagePackageType()) { + String dirName = name(); + if (TKit.isOSX()) { + dirName = dirName + ".app"; + } + bundleName = dirName; + } else if (TKit.isLinux()) { bundleName = LinuxHelper.getBundleName(this); - } else if (PackageType.WINDOWS.contains(type)) { + } else if (TKit.isWindows()) { bundleName = WindowsHelper.getBundleName(this); - } else if (PackageType.MAC.contains(type)) { + } else if (TKit.isOSX()) { bundleName = MacHelper.getBundleName(this); + } else { + throw TKit.throwUnknownPlatformError(); } return outputDir().resolve(bundleName); } /** - * Returns path to directory where application will be installed. + * Returns application layout. + * + * If this is build image command, returns application image layout of the + * output bundle relative to output directory. Otherwise returns layout of + * installed application relative to the root directory. + * + * If this command builds Java runtime, not an application, returns + * corresponding layout. + */ + public ApplicationLayout appLayout() { + final ApplicationLayout layout; + if (isRuntime()) { + layout = ApplicationLayout.javaRuntime(); + } else { + layout = ApplicationLayout.platformAppImage(); + } + + if (isImagePackageType()) { + return layout.resolveAt(outputBundle()); + } + + return layout.resolveAt(appInstallationDirectory()); + } + + /** + * Returns path to directory where application will be installed or null if + * this is build image command. * * E.g. on Linux for app named Foo default the function will return * `/opt/foo` */ public Path appInstallationDirectory() { - final PackageType type = packageType(); - if (PackageType.IMAGE == type) { + if (isImagePackageType()) { return null; } - if (PackageType.LINUX.contains(type)) { + if (TKit.isLinux()) { if (isRuntime()) { // Not fancy, but OK. return Path.of(getArgumentValue("--install-dir", () -> "/opt"), @@ -300,139 +375,104 @@ } // Launcher is in "bin" subfolder of the installation directory. - return launcherInstallationPath().getParent().getParent(); + return appLauncherPath().getParent().getParent(); } - if (PackageType.WINDOWS.contains(type)) { + if (TKit.isWindows()) { return WindowsHelper.getInstallationDirectory(this); } - if (PackageType.MAC.contains(type)) { + if (TKit.isOSX()) { return MacHelper.getInstallationDirectory(this); } - throw throwUnexpectedPackageTypeError(); - } - - /** - * Returns path where application's Java runtime will be installed. - * If the command will package Java run-time only, still returns path to - * runtime subdirectory. - * - * E.g. on Linux for app named `Foo` the function will return - * `/opt/foo/runtime` - */ - public Path appRuntimeInstallationDirectory() { - if (PackageType.IMAGE == packageType()) { - return null; - } - return appInstallationDirectory().resolve(appRuntimePath(packageType())); - } - - /** - * Returns path where application launcher will be installed. - * If the command will package Java run-time only, still returns path to - * application launcher. - * - * E.g. on Linux for app named Foo default the function will return - * `/opt/foo/bin/Foo` - */ - public Path launcherInstallationPath() { - final PackageType type = packageType(); - if (PackageType.IMAGE == type) { - return null; - } - - if (PackageType.LINUX.contains(type)) { - return outputDir().resolve(LinuxHelper.getLauncherPath(this)); - } - - if (PackageType.WINDOWS.contains(type)) { - return appInstallationDirectory().resolve(name() + ".exe"); - } - - if (PackageType.MAC.contains(type)) { - return appInstallationDirectory().resolve(Path.of("Contents", "MacOS", name())); - } - - throw throwUnexpectedPackageTypeError(); - } - - /** - * Returns path to application image directory. - * - * E.g. if --dest is set to `foo` and --name is set to `bar` the function - * will return `foo/bar` path on Linux and Windows and `foo/bar.app` on macOS. - * - * @throws IllegalArgumentException is command is doing platform packaging - */ - public Path appImage() { - verifyIsOfType(PackageType.IMAGE); - String dirName = name(); - if (TKit.isOSX()) { - dirName = dirName + ".app"; - } - return outputDir().resolve(dirName); - } - - /** - * Returns path to application launcher relative to image directory. - * - * E.g. if --name is set to `Foo` the function will return `bin/Foo` path on - * Linux, and `Foo.exe` on Windows. - * - * @throws IllegalArgumentException is command is doing platform packaging - */ - public Path launcherPathInAppImage() { - verifyIsOfType(PackageType.IMAGE); - - if (TKit.isLinux()) { - return Path.of("bin", name()); - } - - if (TKit.isOSX()) { - return Path.of("Contents", "MacOS", name()); - } - - if (TKit.isWindows()) { - return Path.of(name() + ".exe"); - } - throw TKit.throwUnknownPlatformError(); } /** - * Returns path to runtime directory relative to image directory. + * Returns path to application's Java runtime. + * If the command will package Java runtime only, returns correct path to + * runtime directory. * - * @throws IllegalArgumentException if command is configured for platform - * packaging + * E.g.: + * [jpackage --name Foo --package-type rpm] -> `/opt/foo/lib/runtime` + * [jpackage --name Foo --package-type app-image --dest bar] -> `bar/Foo/lib/runtime` + * [jpackage --name Foo --package-type rpm --runtime-image java] -> `/opt/foo` */ - public Path appRuntimeDirectoryInAppImage() { - verifyIsOfType(PackageType.IMAGE); - return appRuntimePath(packageType()); + public Path appRuntimeDirectory() { + return appLayout().runtimeDirectory(); } - private static Path appRuntimePath(PackageType type) { - if (TKit.isLinux()) { - return Path.of("lib/runtime"); - } - if (TKit.isOSX()) { - return Path.of("Contents/runtime"); + /** + * Returns path for application launcher with the given name. + * + * E.g.: [jpackage --name Foo --package-type rpm] -> `/opt/foo/bin/Foo` + * [jpackage --name Foo --package-type app-image --dest bar] -> + * `bar/Foo/bin/Foo` + * + * @param launcherName name of launcher or {@code null} for the main + * launcher + * + * @throws IllegalArgumentException if the command is configured for + * packaging Java runtime + */ + public Path appLauncherPath(String launcherName) { + verifyNotRuntime(); + if (launcherName == null) { + launcherName = name(); } - return Path.of("runtime"); + if (TKit.isWindows()) { + launcherName = launcherName + ".exe"; + } + + if (isImagePackageType()) { + return appLayout().launchersDirectory().resolve(launcherName); + } + + if (TKit.isLinux()) { + LinuxHelper.getLauncherPath(this).getParent().resolve(launcherName); + } + + return appLayout().launchersDirectory().resolve(launcherName); } - public boolean isFakeRuntimeInAppImage(String msg) { - return isFakeRuntime(appImage().resolve( - appRuntimeDirectoryInAppImage()), msg); + /** + * Shorthand for {@code appLauncherPath(null)}. + */ + public Path appLauncherPath() { + return appLauncherPath(null); + } + + private void verifyNotRuntime() { + if (isRuntime()) { + throw new IllegalArgumentException("Java runtime packaging"); + } } - public boolean isFakeRuntimeInstalled(String msg) { - return isFakeRuntime(appRuntimeInstallationDirectory(), msg); + /** + * Returns path to .cfg file of the given application launcher. + * + * E.g.: + * [jpackage --name Foo --package-type rpm] -> `/opt/foo/lib/app/Foo.cfg` + * [jpackage --name Foo --package-type app-image --dest bar] -> `bar/Foo/lib/app/Foo.cfg` + * + * @param launcher name of launcher or {@code null} for the main launcher + * + * @throws IllegalArgumentException if the command is configured for + * packaging Java runtime + */ + public Path appLauncherCfgPath(String launcherName) { + verifyNotRuntime(); + if (launcherName == null) { + launcherName = name(); + } + return appLayout().appDirectory().resolve(launcherName + ".cfg"); } - private static boolean isFakeRuntime(Path runtimeDir, String msg) { + public boolean isFakeRuntime(String msg) { + Path runtimeDir = appRuntimeDirectory(); + final Collection criticalRuntimeFiles; if (TKit.isWindows()) { criticalRuntimeFiles = WindowsHelper.CRITICAL_RUNTIME_FILES; @@ -482,12 +522,18 @@ return this; } + public JPackageCommand ignoreDefaultRuntime(boolean v) { + verifyMutable(); + ignoreDefaultRuntime = v; + return this; + } + public boolean isWithToolProvider() { return Optional.ofNullable(withToolProvider).orElse( defaultWithToolProvider); } - public void executePrerequisiteActions() { + public JPackageCommand executePrerequisiteActions() { verifyMutable(); if (!actionsExecuted) { actionsExecuted = true; @@ -495,26 +541,35 @@ actions.stream().forEach(r -> r.accept(this)); } } + return this; + } + + public Executor createExecutor() { + verifyMutable(); + Executor exec = new Executor() + .saveOutput(saveConsoleOutput).dumpOutput(!suppressOutput) + .addArguments(args); + + if (isWithToolProvider()) { + exec.setToolProvider(JavaTool.JPACKAGE); + } else { + exec.setExecutable(JavaTool.JPACKAGE); + } + + return exec; } public Executor.Result execute() { executePrerequisiteActions(); - if (packageType() == PackageType.IMAGE) { + if (isImagePackageType()) { TKit.deleteDirectoryContentsRecursive(outputDir()); } - Executor exec = new Executor() - .saveOutput(saveConsoleOutput).dumpOutput(!suppressOutput) - .addArguments(new JPackageCommand().addArguments( - args).adjustArgumentsBeforeExecution().args); - - if (isWithToolProvider()) { - exec.setToolProvider(JavaTool.JPACKAGE.asToolProvider()); - } else { - exec.setExecutable(JavaTool.JPACKAGE); - } - return exec.execute(); + return new JPackageCommand(this) + .adjustArgumentsBeforeExecution() + .createExecutor() + .execute(); } public JPackageCommand executeAndAssertHelloAppImageCreated() { @@ -530,15 +585,18 @@ public JPackageCommand assertImageCreated() { verifyIsOfType(PackageType.IMAGE); - TKit.assertExecutableFileExists(appImage().resolve( - launcherPathInAppImage())); - TKit.assertDirectoryExists(appImage().resolve( - appRuntimeDirectoryInAppImage())); + TKit.assertDirectoryExists(appRuntimeDirectory()); + + if (!isRuntime()) { + TKit.assertExecutableFileExists(appLauncherPath()); + TKit.assertFileExists(appLauncherCfgPath(null)); + } + return this; } private JPackageCommand adjustArgumentsBeforeExecution() { - if (!hasArgument("--runtime-image") && !hasArgument("--app-image") && DEFAULT_RUNTIME_IMAGE != null) { + if (!hasArgument("--runtime-image") && !hasArgument("--app-image") && DEFAULT_RUNTIME_IMAGE != null && !ignoreDefaultRuntime) { addArguments("--runtime-image", DEFAULT_RUNTIME_IMAGE); } @@ -549,10 +607,6 @@ return this; } - private static RuntimeException throwUnexpectedPackageTypeError() { - throw new IllegalArgumentException("Unexpected package type"); - } - String getPrintableCommandLine() { return new Executor() .setExecutable(JavaTool.JPACKAGE) @@ -565,9 +619,41 @@ } public void verifyIsOfType(PackageType ... types) { - if (!Arrays.asList(types).contains(packageType())) { - throwUnexpectedPackageTypeError(); + final Set typesSet = Set.of(types); + if (!hasArgument("--package-type")) { + if (!isImagePackageType()) { + if (TKit.isLinux() && typesSet.equals(PackageType.LINUX)) { + return; + } + + if (TKit.isWindows() && typesSet.equals(PackageType.WINDOWS)) { + return; + } + + if (TKit.isOSX() && typesSet.equals(PackageType.MAC)) { + return; + } + } else if (typesSet.equals(Set.of(PackageType.IMAGE))) { + return; + } } + + if (!typesSet.contains(packageType())) { + throw new IllegalArgumentException("Unexpected package type"); + } + } + + public CfgFile readLaunherCfgFile() { + return readLaunherCfgFile(null); + } + + public CfgFile readLaunherCfgFile(String launcherName) { + verifyIsOfType(PackageType.IMAGE); + if (isRuntime()) { + return null; + } + return ThrowingFunction.toFunction(CfgFile::readFromFile).apply( + appLauncherCfgPath(launcherName)); } public static String escapeAndJoin(String... args) { @@ -616,6 +702,7 @@ private Boolean withToolProvider; private boolean saveConsoleOutput; private boolean suppressOutput; + private boolean ignoreDefaultRuntime; private boolean immutable; private boolean actionsExecuted; private final List> actions; diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JarBuilder.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JarBuilder.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JarBuilder.java Wed Oct 16 10:32:08 2019 -0400 @@ -62,15 +62,16 @@ public void create() { TKit.withTempDirectory("jar-workdir", workDir -> { - Executor.Result javacReply = new Executor() - .setExecutable(JavaTool.JAVAC) - .addArguments("-d", workDir.toString()) - .addPathArguments(sourceFiles).execute(); - javacReply.assertExitCodeIsZero(); + if (!sourceFiles.isEmpty()) { + new Executor() + .setToolProvider(JavaTool.JAVAC) + .addArguments("-d", workDir.toString()) + .addPathArguments(sourceFiles) + .execute().assertExitCodeIsZero(); + } Path tmpJar = workDir.resolve("foo.jar"); Executor jarExe = new Executor(); - jarExe.setExecutable(JavaTool.JAR).addArguments("-c", "-v", "-f", - tmpJar.toString()); + jarExe.setToolProvider(JavaTool.JAR).addArguments("-c", "-f", tmpJar.toString()); if (moduleVersion != null) { jarExe.addArguments(String.format("--module-version=%s", moduleVersion)); @@ -79,8 +80,7 @@ jarExe.addArguments("-e", mainClass); } jarExe.addArguments("-C", workDir.toString(), "."); - javacReply = jarExe.execute(); - javacReply.assertExitCodeIsZero(); + jarExe.execute().assertExitCodeIsZero(); outputJar.getParentFile().mkdirs(); Files.copy(tmpJar, outputJar.toPath(), REPLACE_EXISTING); }); diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JavaAppDesc.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JavaAppDesc.java Wed Oct 16 10:32:08 2019 -0400 @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2019, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.test; + +import java.util.Objects; + + +public final class JavaAppDesc { + public JavaAppDesc() { + } + + public JavaAppDesc setClassName(String v) { + qualifiedClassName = v; + return this; + } + + public JavaAppDesc setModuleName(String v) { + moduleName = v; + return this; + } + + public JavaAppDesc setJarFileName(String v) { + jarFileName = v; + return this; + } + + public JavaAppDesc setModuleVersion(String v) { + moduleVersion = v; + return this; + } + + public JavaAppDesc setJarWithMainClass(boolean v) { + jarWithMainClass = v; + return this; + } + + public String className() { + return qualifiedClassName; + } + + public String moduleName() { + return moduleName; + } + + public String packageName() { + int lastDotIdx = qualifiedClassName.lastIndexOf('.'); + if (lastDotIdx == -1) { + return null; + } + return qualifiedClassName.substring(0, lastDotIdx); + } + + public String jarFileName() { + return jarFileName; + } + + public String moduleVersion() { + return moduleVersion; + } + + public boolean jarWithMainClass() { + return jarWithMainClass; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + if (jarFileName != null) { + sb.append(jarFileName).append(':'); + } + if (moduleName != null) { + sb.append(moduleName).append('/'); + } + if (qualifiedClassName != null) { + sb.append(qualifiedClassName); + } + if (jarWithMainClass) { + sb.append('!'); + } + if (moduleVersion != null) { + sb.append('@').append(moduleVersion); + } + return sb.toString(); + } + + /** + * Create Java application description form encoded string value. + * + * Syntax of encoded Java application description is + * [jar_file:][module_name/]qualified_class_name[!][@module_version]. + * + * E.g.: `duke.jar:com.other/com.other.foo.bar.Buz!@3.7` encodes modular + * application. Module name is `com.other`. Main class is + * `com.other.foo.bar.Buz`. Module version is `3.7`. Application will be + * compiled and packed in `duke.jar` jar file. jar command will set module + * version (3.7) and main class (Buz) attributes in the jar file. + * + * E.g.: `Ciao` encodes non-modular `Ciao` class in the default package. + * jar command will not put main class attribute in the jar file. + * Default name will be picked for jar file - `hello.jar`. + * + * @param cmd jpackage command to configure + * @param javaAppDesc encoded Java application description + */ + public static JavaAppDesc parse(String javaAppDesc) { + JavaAppDesc desc = HelloApp.createDefaltAppDesc(); + + if (javaAppDesc == null) { + return desc; + } + + String moduleNameAndOther = Functional.identity(() -> { + String[] components = javaAppDesc.split(":", 2); + if (components.length == 2) { + desc.setJarFileName(components[0]); + } + return components[components.length - 1]; + }).get(); + + String classNameAndOther = Functional.identity(() -> { + String[] components = moduleNameAndOther.split("/", 2); + if (components.length == 2) { + desc.setModuleName(components[0]); + } + return components[components.length - 1]; + }).get(); + + Functional.identity(() -> { + String[] components = classNameAndOther.split("@", 2); + if (components[0].endsWith("!")) { + components[0] = components[0].substring(0, + components[0].length() - 1); + desc.setJarWithMainClass(true); + } + desc.setClassName(components[0]); + if (components.length == 2) { + desc.setModuleVersion(components[1]); + } + }).run(); + + return desc; + } + + private String qualifiedClassName; + private String moduleName; + private String jarFileName; + private String moduleVersion; + private boolean jarWithMainClass; +} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java Wed Oct 16 10:32:08 2019 -0400 @@ -200,7 +200,7 @@ final boolean checkPrerequisites; if (cmd.isRuntime()) { - Path runtimeDir = cmd.appRuntimeInstallationDirectory(); + Path runtimeDir = cmd.appRuntimeDirectory(); Set expectedCriticalRuntimePaths = CRITICAL_RUNTIME_FILES.stream().map( runtimeDir::resolve).collect(Collectors.toSet()); Set actualCriticalRuntimePaths = getPackageFiles(cmd).filter( @@ -339,7 +339,7 @@ TKit.trace(String.format("Done")); - TKit.assertEquals(cmd.launcherInstallationPath().toString(), + TKit.assertEquals(cmd.appLauncherPath().toString(), mimeHandler, String.format( "Check mime type handler is the main application launcher")); diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java Wed Oct 16 10:32:08 2019 -0400 @@ -22,11 +22,70 @@ */ package jdk.jpackage.test; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.nio.file.Path; +import java.util.List; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; +import jdk.jpackage.test.Functional.ThrowingConsumer; +import jdk.jpackage.test.Functional.ThrowingSupplier; +import org.xml.sax.SAXException; public class MacHelper { + public static void withExplodedDmg(JPackageCommand cmd, + ThrowingConsumer consumer) { + cmd.verifyIsOfType(PackageType.MAC_DMG); + + var plist = readPList(new Executor() + .setExecutable("/usr/bin/hdiutil") + .dumpOutput() + .addArguments("attach", cmd.outputBundle().toString(), "-plist") + .executeAndGetOutput()); + + final Path mountPoint = Path.of(plist.queryValue("mount-point")); + try { + Path dmgImage = mountPoint.resolve(cmd.name() + ".app"); + TKit.trace(String.format("Exploded [%s] in [%s] directory", + cmd.outputBundle(), dmgImage)); + ThrowingConsumer.toConsumer(consumer).accept(dmgImage); + } finally { + new Executor() + .setExecutable("/usr/bin/hdiutil") + .addArgument("detach").addArgument(mountPoint) + .execute().assertExitCodeIsZero(); + } + } + + public static PListWrapper readPListFromAppImage(Path appImage) { + return readPList(appImage.resolve("Contents/Info.plist")); + } + + public static PListWrapper readPList(Path path) { + TKit.assertReadableFileExists(path); + return ThrowingSupplier.toSupplier(() -> readPList(Files.readAllLines( + path))).get(); + } + + public static PListWrapper readPList(List lines) { + return readPList(lines.stream()); + } + + public static PListWrapper readPList(Stream lines) { + return ThrowingSupplier.toSupplier(() -> new PListWrapper(lines.collect( + Collectors.joining()))).get(); + } + static String getBundleName(JPackageCommand cmd) { cmd.verifyIsOfType(PackageType.MAC); return String.format("%s-%s%s", getPackageName(cmd), cmd.version(), @@ -45,6 +104,35 @@ () -> cmd.name()); } + public static final class PListWrapper { + public String queryValue(String keyName) { + XPath xPath = XPathFactory.newInstance().newXPath(); + // Query for the value of element preceding element + // with value equal to `keyName` + String query = String.format( + "//string[preceding-sibling::key = \"%s\"][1]", keyName); + return ThrowingSupplier.toSupplier(() -> (String) xPath.evaluate( + query, doc, XPathConstants.STRING)).get(); + } + + PListWrapper(String xml) throws ParserConfigurationException, + SAXException, IOException { + doc = createDocumentBuilder().parse(new ByteArrayInputStream( + xml.getBytes(StandardCharsets.UTF_8))); + } + + private static DocumentBuilder createDocumentBuilder() throws + ParserConfigurationException { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultInstance(); + dbf.setFeature( + "http://apache.org/xml/features/nonvalidating/load-external-dtd", + false); + return dbf.newDocumentBuilder(); + } + + private final org.w3c.dom.Document doc; + } + static final Set CRITICAL_RUNTIME_FILES = Set.of(Path.of( "Contents/Home/lib/server/libjvm.dylib")); diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Main.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Main.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Main.java Wed Oct 16 10:32:08 2019 -0400 @@ -25,6 +25,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; import static jdk.jpackage.test.TestBuilder.CMDLINE_ARG_PREFIX; @@ -36,9 +37,7 @@ List tests = new ArrayList<>(); try (TestBuilder testBuilder = new TestBuilder(tests::add)) { for (var arg : args) { - if (TKit.VERBOSE_TEST_SETUP) { - TKit.log(String.format("Parsing [%s]...", arg)); - } + TestBuilder.trace(String.format("Parsing [%s]...", arg)); if ((CMDLINE_ARG_PREFIX + "list").equals(arg)) { listTests = true; @@ -62,15 +61,21 @@ } // Order tests by their full names to have stable test sequence. - tests = tests.stream().sorted((a, b) -> a.fullName().compareTo( - b.fullName())).collect(Collectors.toList()); + List orderedTests = tests.stream() + .sorted((a, b) -> a.fullName().compareTo(b.fullName())) + .collect(Collectors.toList()); if (listTests) { // Just list the tests - tests.stream().forEach(test -> System.out.println(test.fullName())); + orderedTests.stream().forEach(test -> System.out.println(String.format( + "%s; workDir=[%s]", test.fullName(), test.workDir()))); return; } + TKit.withExtraLogStream(() -> runTests(orderedTests)); + } + + private static void runTests(List tests) { TKit.runTests(tests); final long passedCount = tests.stream().filter(TestInstance::passed).count(); @@ -78,8 +83,8 @@ TKit.log(String.format("[ PASSED ] %d %s", passedCount, passedCount == 1 ? "test" : "tests")); - reportDetails(tests, "[ SKIPPED ]", TestInstance::skipped); - reportDetails(tests, "[ FAILED ]", TestInstance::failed); + reportDetails(tests, "[ SKIPPED ]", TestInstance::skipped, false); + reportDetails(tests, "[ FAILED ]", TestInstance::failed, true); var withSkipped = reportSummary(tests, "SKIPPED", TestInstance::skipped); var withFailures = reportSummary(tests, "FAILED", TestInstance::failed); @@ -94,13 +99,22 @@ } private static long reportDetails(List tests, - String label, Predicate selector) { + String label, Predicate selector, boolean printWorkDir) { + + final Function makeMessage = test -> { + if (printWorkDir) { + return String.format("%s %s; workDir=[%s]", label, + test.fullName(), test.workDir()); + } + return String.format("%s %s", label, test.fullName()); + }; + final long count = tests.stream().filter(selector).count(); if (count != 0) { TKit.log(String.format("%s %d %s, listed below", label, count, count == 1 ? "test" : "tests")); - tests.stream().filter(selector).forEach(test -> TKit.log( - String.format("%s %s", label, test.fullName()))); + tests.stream().filter(selector).map(makeMessage).forEachOrdered( + TKit::log); } return count; diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java Wed Oct 16 10:32:08 2019 -0400 @@ -23,40 +23,131 @@ package jdk.jpackage.test; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; import jdk.jpackage.test.Functional.ThrowingConsumer; -import jdk.jpackage.test.Functional.ThrowingSupplier; import jdk.jpackage.test.TestInstance.TestDesc; class MethodCall implements ThrowingConsumer { - MethodCall(Method method, Object... args) { + MethodCall(Object[] instanceCtorArgs, Method method) { + this.ctorArgs = Optional.ofNullable(instanceCtorArgs).orElse( + DEFAULT_CTOR_ARGS); this.method = method; - this.args = args; + this.methodArgs = new Object[0]; + } + + MethodCall(Object[] instanceCtorArgs, Method method, Object arg) { + this.ctorArgs = Optional.ofNullable(instanceCtorArgs).orElse( + DEFAULT_CTOR_ARGS); + this.method = method; + this.methodArgs = new Object[]{arg}; } TestDesc createDescription() { - return TestDesc.create(method, args); + var descBuilder = TestDesc.createBuilder().method(method); + if (methodArgs.length != 0) { + descBuilder.methodArgs(methodArgs); + } + + if (ctorArgs.length != 0) { + descBuilder.ctorArgs(ctorArgs); + } + + return descBuilder.get(); + } + + Method getMethod() { + return method; } - Constructor getRequiredConstructor() throws NoSuchMethodException { - return MethodCall.getRequiredConstructor(method); + Object newInstance() throws NoSuchMethodException, InstantiationException, + IllegalAccessException, IllegalArgumentException, + InvocationTargetException { + if ((method.getModifiers() & Modifier.STATIC) != 0) { + return null; + } + + Constructor ctor = findRequiredConstructor(method.getDeclaringClass(), + ctorArgs); + if (ctor.isVarArgs()) { + // Assume constructor doesn't have fixed, only variable parameters. + return ctor.newInstance(new Object[]{ctorArgs}); + } + + return ctor.newInstance(ctorArgs); + } + + void checkRequiredConstructor() throws NoSuchMethodException { + if ((method.getModifiers() & Modifier.STATIC) == 0) { + findRequiredConstructor(method.getDeclaringClass(), ctorArgs); + } } - static Constructor getRequiredConstructor(Method method) throws - NoSuchMethodException { - if ((method.getModifiers() & Modifier.STATIC) == 0) { - return method.getDeclaringClass().getConstructor(); + private static Constructor findVarArgConstructor(Class type) { + return Stream.of(type.getConstructors()).filter( + Constructor::isVarArgs).findFirst().orElse(null); + } + + private Constructor findRequiredConstructor(Class type, Object... ctorArgs) + throws NoSuchMethodException { + + Supplier notFoundException = () -> { + return new NoSuchMethodException(String.format( + "No public contructor in %s for %s arguments", type, + Arrays.deepToString(ctorArgs))); + }; + + if (Stream.of(ctorArgs).allMatch(Objects::nonNull)) { + // No `null` in constructor args, take easy path + try { + return type.getConstructor(Stream.of(ctorArgs).map( + Object::getClass).collect(Collectors.toList()).toArray( + Class[]::new)); + } catch (NoSuchMethodException ex) { + // Failed to find ctor that can take the given arguments. + Constructor varArgCtor = findVarArgConstructor(type); + if (varArgCtor != null) { + // There is one with variable number of arguments. Use it. + return varArgCtor; + } + throw notFoundException.get(); + } } - return null; + + List ctors = Stream.of(type.getConstructors()) + .filter(ctor -> ctor.getParameterCount() == ctorArgs.length) + .collect(Collectors.toList()); + + if (ctors.isEmpty()) { + // No public constructors that can handle the given arguments. + throw notFoundException.get(); + } + + if (ctors.size() == 1) { + return ctors.iterator().next(); + } + + // Revisit this tricky case when it will start bothering. + throw notFoundException.get(); } @Override public void accept(Object thiz) throws Throwable { - method.invoke(thiz, args); + method.invoke(thiz, methodArgs); } - private final Object[] args; + private final Object[] methodArgs; private final Method method; + private final Object[] ctorArgs; + + final static Object[] DEFAULT_CTOR_ARGS = new Object[0]; } diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -162,10 +162,9 @@ public PackageTest addHelloAppFileAssociationsVerifier(FileAssociations fa, String... faLauncherDefaultArgs) { - addInitializer(cmd -> HelloApp.addTo(cmd, null), "HelloApp"); + addInitializer(cmd -> new HelloApp(null).addTo(cmd), "HelloApp"); addInstallVerifier(cmd -> { - if (cmd.isFakeRuntimeInstalled( - "Not running file associations test")) { + if (cmd.isFakeRuntime("Not running file associations test")) { return; } @@ -219,7 +218,8 @@ } public PackageTest configureHelloApp(String encodedName) { - addInitializer(cmd -> HelloApp.addTo(cmd, encodedName)); + addInitializer( + cmd -> new HelloApp(JavaAppDesc.parse(encodedName)).addTo(cmd)); addInstallVerifier(HelloApp::executeLauncherAndVerifyOutput); return this; } @@ -297,6 +297,8 @@ type.applyTo(cmd); initializers.stream().forEach(v -> v.accept(cmd)); + cmd.executePrerequisiteActions(); + switch (action) { case CREATE: Executor.Result result = cmd.execute(); @@ -336,15 +338,13 @@ private void verifyPackageInstalled(JPackageCommand cmd) { TKit.trace(String.format("Verify installed: %s", cmd.getPrintableCommandLine())); - if (cmd.isRuntime()) { - TKit.assertPathExists( - cmd.appRuntimeInstallationDirectory(), false); - } else { - TKit.assertExecutableFileExists(cmd.launcherInstallationPath()); - } + TKit.assertDirectoryExists(cmd.appRuntimeDirectory()); + if (!cmd.isRuntime()) { + TKit.assertExecutableFileExists(cmd.appLauncherPath()); - if (PackageType.WINDOWS.contains(cmd.packageType())) { - new WindowsHelper.AppVerifier(cmd); + if (PackageType.WINDOWS.contains(cmd.packageType())) { + new WindowsHelper.AppVerifier(cmd); + } } installVerifiers.stream().forEach(v -> v.accept(cmd)); @@ -354,13 +354,14 @@ TKit.trace(String.format("Verify uninstalled: %s", cmd.getPrintableCommandLine())); if (!cmd.isRuntime()) { - TKit.assertPathExists(cmd.launcherInstallationPath(), false); - TKit.assertPathExists(cmd.appInstallationDirectory(), false); + TKit.assertPathExists(cmd.appLauncherPath(), false); + + if (PackageType.WINDOWS.contains(cmd.packageType())) { + new WindowsHelper.AppVerifier(cmd); + } } - if (PackageType.WINDOWS.contains(cmd.packageType())) { - new WindowsHelper.AppVerifier(cmd); - } + TKit.assertPathExists(cmd.appInstallationDirectory(), false); uninstallVerifiers.stream().forEach(v -> v.accept(cmd)); } diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java Wed Oct 16 10:32:08 2019 -0400 @@ -24,6 +24,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.Collections; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -117,9 +118,8 @@ private final static class Inner { - private final static Set DISABLED_PACKAGERS = Stream.of( - Optional.ofNullable( - TKit.getConfigProperty("disabledPackagers")).orElse( - "").split(",")).collect(Collectors.toUnmodifiableSet()); + private final static Set DISABLED_PACKAGERS = Optional.ofNullable( + TKit.tokenizeConfigProperty("disabledPackagers")).orElse( + Collections.emptySet()); } } diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java Wed Oct 16 10:32:08 2019 -0400 @@ -22,28 +22,24 @@ */ package jdk.jpackage.test; -import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.lang.reflect.InvocationTargetException; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardWatchEventKinds; +import java.nio.file.*; import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; -import java.nio.file.WatchEvent; -import java.nio.file.WatchKey; -import java.nio.file.WatchService; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiPredicate; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.jpackage.test.Functional.ExceptionBox; import jdk.jpackage.test.Functional.ThrowingConsumer; -import jdk.jpackage.test.Functional.ThrowingFunction; import jdk.jpackage.test.Functional.ThrowingRunnable; import jdk.jpackage.test.Functional.ThrowingSupplier; @@ -76,14 +72,26 @@ } } + static void withExtraLogStream(ThrowingRunnable action) { + if (extraLogStream != null) { + ThrowingRunnable.toRunnable(action).run(); + } else { + try (PrintStream logStream = openLogStream()) { + extraLogStream = logStream; + ThrowingRunnable.toRunnable(action).run(); + } finally { + extraLogStream = null; + } + } + } + static void runTests(List tests) { if (currentTest != null) { throw new IllegalStateException( "Unexpeced nested or concurrent Test.run() call"); } - try (PrintStream logStream = openLogStream()) { - extraLogStream = logStream; + withExtraLogStream(() -> { tests.stream().forEach(test -> { currentTest = test; try { @@ -95,9 +103,7 @@ } } }); - } finally { - extraLogStream = null; - } + }); } static Runnable ignoreExceptions(ThrowingRunnable action) { @@ -109,10 +115,7 @@ unbox(ex); } } catch (Throwable throwable) { - if (extraLogStream != null) { - throwable.printStackTrace(extraLogStream); - } - throwable.printStackTrace(); + printStackTrace(throwable); } }; } @@ -126,12 +129,7 @@ } public static Path workDir() { - Path result = Path.of("."); - String testFunctionName = currentTest.functionName(); - if (testFunctionName != null) { - result = result.resolve(testFunctionName); - } - return result; + return currentTest.workDir(); } static Path defaultInputDir() { @@ -174,10 +172,14 @@ } public static void createTextFile(Path propsFilename, Collection lines) { + createTextFile(propsFilename, lines.stream()); + } + + public static void createTextFile(Path propsFilename, Stream lines) { trace(String.format("Create [%s] text file...", propsFilename.toAbsolutePath().normalize())); ThrowingRunnable.toRunnable(() -> Files.write(propsFilename, - lines.stream().peek(TKit::trace).collect(Collectors.toList()))).run(); + lines.peek(TKit::trace).collect(Collectors.toList()))).run(); trace("Done"); } @@ -263,7 +265,7 @@ return Files.createFile(createUniqueFileName(role)); } - public static void withTempFile(String role, String suffix, + public static Path withTempFile(String role, String suffix, ThrowingConsumer action) { final Path tempFile = ThrowingSupplier.toSupplier(() -> createTempFile( role, suffix)).get(); @@ -271,6 +273,7 @@ try { ThrowingConsumer.toConsumer(action).accept(tempFile); keepIt = false; + return tempFile; } finally { if (tempFile != null && !keepIt) { ThrowingRunnable.toRunnable(() -> Files.deleteIfExists(tempFile)).run(); @@ -278,7 +281,7 @@ } } - public static void withTempDirectory(String role, + public static Path withTempDirectory(String role, ThrowingConsumer action) { final Path tempDir = ThrowingSupplier.toSupplier( () -> createTempDirectory(role)).get(); @@ -286,6 +289,7 @@ try { ThrowingConsumer.toConsumer(action).accept(tempDir); keepIt = false; + return tempDir; } finally { if (tempDir != null && tempDir.toFile().isDirectory() && !keepIt) { deleteDirectoryRecursive(tempDir, ""); @@ -293,6 +297,72 @@ } } + private static class DirectoryCleaner implements Consumer { + DirectoryCleaner traceMessage(String v) { + msg = v; + return this; + } + + DirectoryCleaner contentsOnly(boolean v) { + contentsOnly = v; + return this; + } + + @Override + public void accept(Path root) { + if (msg == null) { + if (contentsOnly) { + msg = String.format("Cleaning [%s] directory recursively", + root); + } else { + msg = String.format("Deleting [%s] directory recursively", + root); + } + } + + if (!msg.isEmpty()) { + trace(msg); + } + + List errors = new ArrayList<>(); + try { + final List paths; + if (contentsOnly) { + try (var pathStream = Files.walk(root, 0)) { + paths = pathStream.collect(Collectors.toList()); + } + } else { + paths = List.of(root); + } + + for (var path : paths) { + try (var pathStream = Files.walk(path)) { + pathStream + .sorted(Comparator.reverseOrder()) + .sequential() + .forEachOrdered(file -> { + try { + if (isWindows()) { + Files.setAttribute(file, "dos:readonly", false); + } + Files.delete(file); + } catch (IOException ex) { + errors.add(ex); + } + }); + } + } + + } catch (IOException ex) { + errors.add(ex); + } + errors.forEach(error -> trace(error.toString())); + } + + private String msg; + private boolean contentsOnly; + } + /** * Deletes contents of the given directory recursively. Shortcut for * deleteDirectoryContentsRecursive(path, null) @@ -313,21 +383,8 @@ */ public static void deleteDirectoryContentsRecursive(Path path, String msg) { if (path.toFile().isDirectory()) { - if (msg == null) { - msg = String.format("Cleaning [%s] directory recursively", path); - } - - if (!msg.isEmpty()) { - TKit.trace(msg); - } - - // Walk all children of `path` in sorted order to hit files first - // and directories last and delete each item. - ThrowingRunnable.toRunnable(() -> Stream.of( - path.toFile().listFiles()).map(File::toPath).map( - ThrowingFunction.toFunction(Files::walk)).flatMap(x -> x).sorted( - Comparator.reverseOrder()).map(Path::toFile).forEach( - File::delete)).run(); + new DirectoryCleaner().contentsOnly(true).traceMessage(msg).accept( + path); } } @@ -351,11 +408,7 @@ */ public static void deleteDirectoryRecursive(Path path, String msg) { if (path.toFile().isDirectory()) { - if (msg == null) { - msg = String.format("Deleting [%s] directory recursively", path); - } - deleteDirectoryContentsRecursive(path, msg); - ThrowingConsumer.toConsumer(Files::delete).accept(path); + new DirectoryCleaner().traceMessage(msg).accept(path); } } @@ -377,6 +430,24 @@ throw ex; } + public static Path createRelativePathCopy(final Path file) { + Path fileCopy = workDir().resolve(file.getFileName()).toAbsolutePath().normalize(); + + ThrowingRunnable.toRunnable(() -> Files.copy(file, fileCopy, + StandardCopyOption.REPLACE_EXISTING)).run(); + + final Path basePath = Path.of(".").toAbsolutePath().normalize(); + try { + return basePath.relativize(fileCopy); + } catch (IllegalArgumentException ex) { + // May happen on Windows: java.lang.IllegalArgumentException: 'other' has different root + trace(String.format("Failed to relativize [%s] at [%s]", fileCopy, + basePath)); + printStackTrace(ex); + } + return file; + } + static void waitForFileCreated(Path fileToWaitFor, long timeoutSeconds) throws IOException { @@ -423,6 +494,13 @@ } } + static void printStackTrace(Throwable throwable) { + if (extraLogStream != null) { + throwable.printStackTrace(extraLogStream); + } + throwable.printStackTrace(); + } + private static String concatMessages(String msg, String msg2) { if (msg2 != null && !msg2.isBlank()) { return msg + ": " + msg2; @@ -602,6 +680,76 @@ } } + public final static class TextStreamAsserter { + TextStreamAsserter(String value) { + this.value = value; + predicate(String::contains); + } + + public TextStreamAsserter label(String v) { + label = v; + return this; + } + + public TextStreamAsserter predicate(BiPredicate v) { + predicate = v; + return this; + } + + public TextStreamAsserter negate() { + negate = true; + return this; + } + + public TextStreamAsserter orElseThrow(RuntimeException v) { + return orElseThrow(() -> v); + } + + public TextStreamAsserter orElseThrow(Supplier v) { + createException = v; + return this; + } + + public void apply(Stream lines) { + String matchedStr = lines.filter(line -> predicate.test(line, value)).findFirst().orElse( + null); + String labelStr = Optional.ofNullable(label).orElse("output"); + if (negate) { + String msg = String.format( + "Check %s doesn't contain [%s] string", labelStr, value); + if (createException == null) { + assertNull(matchedStr, msg); + } else { + trace(msg); + if (matchedStr != null) { + throw createException.get(); + } + } + } else { + String msg = String.format("Check %s contains [%s] string", + labelStr, value); + if (createException == null) { + assertNotNull(matchedStr, msg); + } else { + trace(msg); + if (matchedStr == null) { + throw createException.get(); + } + } + } + } + + private BiPredicate predicate; + private String label; + private boolean negate; + private Supplier createException; + final private String value; + } + + public static TextStreamAsserter assertTextStream(String what) { + return new TextStreamAsserter(what); + } + private static PrintStream openLogStream() { if (LOG_FILE == null) { return null; @@ -628,6 +776,15 @@ return "jpackage.test." + propertyName; } + static Set tokenizeConfigProperty(String propertyName) { + final String val = TKit.getConfigProperty(propertyName); + if (val == null) { + return null; + } + return Stream.of(val.toLowerCase().split(",")).map(String::strip).filter( + Predicate.not(String::isEmpty)).collect(Collectors.toSet()); + } + static final Path LOG_FILE = Functional.identity(() -> { String val = getConfigProperty("logfile"); if (val == null) { @@ -637,25 +794,26 @@ }).get(); static { - String val = getConfigProperty("suppress-logging"); - if (val == null) { + Set logOptions = tokenizeConfigProperty("suppress-logging"); + if (logOptions == null) { TRACE = true; TRACE_ASSERTS = true; VERBOSE_JPACKAGE = true; VERBOSE_TEST_SETUP = true; - } else if ("all".equals(val.toLowerCase())) { + } else if (logOptions.contains("all")) { TRACE = false; TRACE_ASSERTS = false; VERBOSE_JPACKAGE = false; VERBOSE_TEST_SETUP = false; } else { - Set logOptions = Set.of(val.toLowerCase().split(",")); - TRACE = !(logOptions.contains("trace") || logOptions.contains("t")); - TRACE_ASSERTS = !(logOptions.contains("assert") || logOptions.contains( - "a")); - VERBOSE_JPACKAGE = !(logOptions.contains("jpackage") || logOptions.contains( - "jp")); - VERBOSE_TEST_SETUP = !logOptions.contains("init"); + Predicate> isNonOf = options -> { + return Collections.disjoint(logOptions, options); + }; + + TRACE = isNonOf.test(Set.of("trace", "t")); + TRACE_ASSERTS = isNonOf.test(Set.of("assert", "a")); + VERBOSE_JPACKAGE = isNonOf.test(Set.of("jpackage", "jp")); + VERBOSE_TEST_SETUP = isNonOf.test(Set.of("init", "i")); } } diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java Wed Oct 16 10:32:08 2019 -0400 @@ -23,43 +23,66 @@ package jdk.jpackage.test; -import java.lang.reflect.Constructor; +import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.lang.reflect.Modifier; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.UnaryOperator; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.jpackage.test.Annotations.AfterEach; +import jdk.jpackage.test.Annotations.BeforeEach; import jdk.jpackage.test.Annotations.Parameter; +import jdk.jpackage.test.Annotations.ParameterGroup; import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.Functional.ThrowingConsumer; import jdk.jpackage.test.Functional.ThrowingFunction; -import jdk.jpackage.test.Functional.ThrowingSupplier; final class TestBuilder implements AutoCloseable { @Override public void close() throws Exception { - flushTestGroup(null); + flushTestGroup(); } TestBuilder(Consumer testConsumer) { - argProcessors = Map.of(CMDLINE_ARG_PREFIX + "after-run", - arg -> getJavaMethodsFromArg(arg).forEach( - (method) -> afterActions.add(wrap(method, dryRun))), + argProcessors = Map.of( + CMDLINE_ARG_PREFIX + "after-run", + arg -> getJavaMethodsFromArg(arg).map( + this::wrap).forEachOrdered(afterActions::add), + CMDLINE_ARG_PREFIX + "before-run", - arg -> getJavaMethodsFromArg(arg).forEach( - (method) -> beforeActions.add(wrap(method, dryRun))), + arg -> getJavaMethodsFromArg(arg).map( + this::wrap).forEachOrdered(beforeActions::add), + CMDLINE_ARG_PREFIX + "run", - arg -> flushTestGroup(getJavaMethodsFromArg(arg).map( - TestBuilder::toMethodCalls).flatMap(List::stream).collect( + arg -> addTestGroup(getJavaMethodsFromArg(arg).map( + ThrowingFunction.toFunction( + TestBuilder::toMethodCalls)).flatMap(s -> s).collect( Collectors.toList())), + + CMDLINE_ARG_PREFIX + "exclude", + arg -> (excludedTests = Optional.ofNullable( + excludedTests).orElse(new HashSet())).add(arg), + + CMDLINE_ARG_PREFIX + "include", + arg -> (includedTests = Optional.ofNullable( + includedTests).orElse(new HashSet())).add(arg), + + CMDLINE_ARG_PREFIX + "space-subst", + arg -> spaceSubstitute = arg, + + CMDLINE_ARG_PREFIX + "group", + arg -> flushTestGroup(), + CMDLINE_ARG_PREFIX + "dry-run", - arg -> dryRun = true); + arg -> dryRun = true + ); this.testConsumer = testConsumer; clear(); } @@ -87,50 +110,93 @@ } } - private void flushTestGroup(List newTestGroup) { + private void addTestGroup(List newTestGroup) { if (testGroup != null) { - testGroup.forEach(testBody -> createTestInstance(testBody)); + testGroup.addAll(newTestGroup); + } else { + testGroup = newTestGroup; + } + } + + private static Stream filterTests(Stream tests, + Set filters, UnaryOperator pred, String logMsg) { + if (filters == null) { + return tests; + } + + // Log all matches before returning from the function + return tests.filter(test -> { + String testDescription = test.createDescription().testFullName(); + boolean match = filters.stream().anyMatch( + v -> testDescription.contains(v)); + if (match) { + trace(String.format(logMsg + ": %s", testDescription)); + } + return pred.apply(match); + }).collect(Collectors.toList()).stream(); + } + + private Stream filterTestGroup() { + Objects.requireNonNull(testGroup); + + UnaryOperator> restoreSpaces = filters -> { + if (spaceSubstitute == null || filters == null) { + return filters; + } + return filters.stream().map( + filter -> filter.replace(spaceSubstitute, " ")).collect( + Collectors.toSet()); + }; + + if (includedTests != null) { + return filterTests(testGroup.stream(), restoreSpaces.apply( + includedTests), x -> x, "Include"); + } + + return filterTests(testGroup.stream(), + restoreSpaces.apply(excludedTests), x -> !x, "Exclude"); + } + + private void flushTestGroup() { + if (testGroup != null) { + filterTestGroup().forEach(testBody -> createTestInstance(testBody)); clear(); } - testGroup = newTestGroup; } private void createTestInstance(MethodCall testBody) { - ThrowingFunction testContructor; - if (dryRun) { - testContructor = (unused) -> null; - testBody = DRY_RUN_TEST_BODY; + final List curBeforeActions; + final List curAfterActions; + + Method testMethod = testBody.getMethod(); + if (Stream.of(BeforeEach.class, AfterEach.class).anyMatch( + type -> testMethod.isAnnotationPresent(type))) { + curBeforeActions = beforeActions; + curAfterActions = afterActions; } else { - testContructor = TestBuilder::constructTest; + curBeforeActions = new ArrayList<>(beforeActions); + curAfterActions = new ArrayList<>(afterActions); + + selectFrameMethods(testMethod.getDeclaringClass(), BeforeEach.class).map( + this::wrap).forEachOrdered(curBeforeActions::add); + selectFrameMethods(testMethod.getDeclaringClass(), AfterEach.class).map( + this::wrap).forEachOrdered(curAfterActions::add); } - TestInstance test = new TestInstance(testContructor, testBody, - beforeActions, afterActions); - trace(String.format("[%s] test constructed", test.fullName())); + TestInstance test = new TestInstance(testBody, curBeforeActions, + curAfterActions, dryRun); + if (includedTests == null) { + trace(String.format("Create: %s", test.fullName())); + } testConsumer.accept(test); } - public static void nop () { - } - - private final static MethodCall DRY_RUN_TEST_BODY = ThrowingSupplier.toSupplier(() -> { - return new MethodCall(TestBuilder.class.getMethod("nop")); - }).get(); - - private static Object constructTest(MethodCall testBody) throws - NoSuchMethodException, InstantiationException, - IllegalAccessException, IllegalArgumentException, - InvocationTargetException { - Constructor ctor = testBody.getRequiredConstructor(); - if (ctor == null) { - return null; - } - return ctor.newInstance(); - } - private void clear() { beforeActions = new ArrayList<>(); afterActions = new ArrayList<>(); + excludedTests = null; + includedTests = null; + spaceSubstitute = null; testGroup = null; } @@ -142,6 +208,14 @@ } } + private static Stream selectFrameMethods(Class type, Class annotationType) { + return Stream.of(type.getMethods()) + .filter(m -> m.getParameterCount() == 0) + .filter(m -> !m.isAnnotationPresent(Test.class)) + .filter(m -> m.isAnnotationPresent(annotationType)) + .sorted((a, b) -> a.getName().compareTo(b.getName())); + } + private static Stream cmdLineArgValueToMethodNames(String v) { List result = new ArrayList<>(); String defaultClassName = null; @@ -156,6 +230,7 @@ m -> m.isAnnotationPresent(Test.class)).map( Method::getName).distinct().forEach( name -> result.add(String.join(".", token, name))); + continue; } @@ -188,7 +263,7 @@ } private static boolean isParametrized(Method method) { - return method.isAnnotationPresent(Parameters.class) || method.isAnnotationPresent( + return method.isAnnotationPresent(ParameterGroup.class) || method.isAnnotationPresent( Parameter.class); } @@ -215,19 +290,6 @@ "Method [%s] not found in [%s] class;", methodName, className)); } - // Make sure default constructor is accessible if the one is needed. - // Need to probe all methods as some of them might be static and - // some class members. - // Onlu class members require default ctor. - for (Method method : methods) { - try { - MethodCall.getRequiredConstructor(method); - } catch (NoSuchMethodException ex) { - throw new ParseException(String.format( - "Default constructor not found in [%s] class;", - className)); - } - } trace(String.format("%s -> %s", qualifiedMethodName, methods)); return methods; @@ -240,9 +302,9 @@ List::stream).sequential(); } - private static Parameter[] getParameters(Method method) { - if (method.isAnnotationPresent(Parameters.class)) { - return ((Parameters) method.getAnnotation(Parameters.class)).value(); + private static Parameter[] getMethodParameters(Method method) { + if (method.isAnnotationPresent(ParameterGroup.class)) { + return ((ParameterGroup) method.getAnnotation(ParameterGroup.class)).value(); } if (method.isAnnotationPresent(Parameter.class)) { @@ -254,20 +316,73 @@ return null; } - private static List toMethodCalls(Method method) { - if (!isParametrized(method)) { - return List.of(new MethodCall(method)); + private static Stream toCtorArgs(Method method) throws + IllegalAccessException, InvocationTargetException { + Class type = method.getDeclaringClass(); + List paremetersProviders = Stream.of(type.getMethods()) + .filter(m -> m.getParameterCount() == 0) + .filter(m -> (m.getModifiers() & Modifier.STATIC) != 0) + .filter(m -> m.isAnnotationPresent(Parameters.class)) + .sorted() + .collect(Collectors.toList()); + if (paremetersProviders.isEmpty()) { + // Single instance using the default constructor. + return Stream.ofNullable(MethodCall.DEFAULT_CTOR_ARGS); + } + + // Pick the first method from the list. + Method paremetersProvider = paremetersProviders.iterator().next(); + if (paremetersProviders.size() > 1) { + trace(String.format( + "Found %d public static methods without arguments with %s annotation. Will use %s", + paremetersProviders.size(), Parameters.class, + paremetersProvider)); + paremetersProviders.stream().map(Method::toString).forEach( + TestBuilder::trace); } - Parameter[] annotations = getParameters(method); + + // Construct collection of arguments for test class instances. + return ((Collection) paremetersProvider.invoke(null)).stream(); + } + + private static Stream toMethodCalls(Method method) throws + IllegalAccessException, InvocationTargetException { + return toCtorArgs(method).map(v -> toMethodCalls(v, method)).flatMap( + s -> s).peek(methodCall -> { + // Make sure required constructor is accessible if the one is needed. + // Need to probe all methods as some of them might be static + // and some class members. + // Only class members require ctors. + try { + methodCall.checkRequiredConstructor(); + } catch (NoSuchMethodException ex) { + throw new ParseException(ex.getMessage() + "."); + } + }); + } + + private static Stream toMethodCalls(Object[] ctorArgs, Method method) { + if (!isParametrized(method)) { + return Stream.of(new MethodCall(ctorArgs, method)); + } + Parameter[] annotations = getMethodParameters(method); if (annotations.length == 0) { - return List.of(new MethodCall(method)); + return Stream.of(new MethodCall(ctorArgs, method)); } return Stream.of(annotations).map((a) -> { - String annotationValue = a.value(); - Class paramClass = method.getParameterTypes()[0]; - return new MethodCall(method, - fromString(annotationValue, paramClass)); - }).collect(Collectors.toList()); + Class paramType = method.getParameterTypes()[0]; + final Object annotationValue; + if (!paramType.isArray()) { + annotationValue = fromString(a.value()[0], paramType); + } else { + Class paramComponentType = paramType.getComponentType(); + annotationValue = Array.newInstance(paramComponentType, a.value().length); + var idx = new AtomicInteger(-1); + Stream.of(a.value()).map(v -> fromString(v, paramComponentType)).sequential().forEach( + v -> Array.set(annotationValue, idx.incrementAndGet(), v)); + } + return new MethodCall(ctorArgs, method, annotationValue); + }); } private static Object fromString(String value, Class toType) { @@ -281,7 +396,7 @@ } // Wraps Method.invike() into ThrowingRunnable.run() - private static ThrowingConsumer wrap(Method method, boolean dryRun) { + private ThrowingConsumer wrap(Method method) { return (test) -> { Class methodClass = method.getDeclaringClass(); String methodName = String.join(".", methodClass.getName(), @@ -318,7 +433,7 @@ private String badCmdLineArg; } - private static void trace(String msg) { + static void trace(String msg) { if (TKit.VERBOSE_TEST_SETUP) { TKit.log(msg); } @@ -329,6 +444,9 @@ private List testGroup; private List beforeActions; private List afterActions; + private Set excludedTests; + private Set includedTests; + private String spaceSubstitute; private boolean dryRun; private final static Map> conv = Map.of( diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java Wed Oct 16 10:32:08 2019 -0400 @@ -23,18 +23,20 @@ package jdk.jpackage.test; +import java.lang.reflect.Array; import java.lang.reflect.Method; import java.nio.file.Files; -import java.util.Collections; -import java.util.List; +import java.nio.file.Path; +import java.util.*; +import java.util.function.Predicate; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.jpackage.test.Functional.ThrowingConsumer; import jdk.jpackage.test.Functional.ThrowingFunction; import jdk.jpackage.test.Functional.ThrowingRunnable; -import jdk.jpackage.test.Functional.ThrowingSupplier; -class TestInstance implements ThrowingRunnable { +final class TestInstance implements ThrowingRunnable { static class TestDesc { private TestDesc() { @@ -43,24 +45,81 @@ String testFullName() { StringBuilder sb = new StringBuilder(); sb.append(clazz.getSimpleName()); + if (instanceArgs != null) { + sb.append('(').append(instanceArgs).append(')'); + } if (functionName != null) { sb.append('.'); sb.append(functionName); - if (args != null) { - sb.append('(').append(args).append(')'); + if (functionArgs != null) { + sb.append('(').append(functionArgs).append(')'); } } return sb.toString(); } - private Class clazz; - private String functionName; - private String args; + static Builder createBuilder() { + return new Builder(); + } + + static final class Builder implements Supplier { + private Builder() { + } + + Builder method(Method v) { + method = v; + return this; + } + + Builder ctorArgs(Object... v) { + ctorArgs = ofNullable(v); + return this; + } + + Builder methodArgs(Object... v) { + methodArgs = ofNullable(v); + return this; + } - private static TestDesc create() { - TestDesc desc = new TestDesc(); - desc.clazz = enclosingMainMethodClass(); - return desc; + @Override + public TestDesc get() { + TestDesc desc = new TestDesc(); + if (method == null) { + desc.clazz = enclosingMainMethodClass(); + } else { + desc.clazz = method.getDeclaringClass(); + desc.functionName = method.getName(); + desc.functionArgs = formatArgs(methodArgs); + desc.instanceArgs = formatArgs(ctorArgs); + } + return desc; + } + + private static String formatArgs(List values) { + if (values == null) { + return null; + } + return values.stream().map(v -> { + if (v != null && v.getClass().isArray()) { + return String.format("%s(length=%d)", + Arrays.deepToString((Object[]) v), + Array.getLength(v)); + } + return String.format("%s", v); + }).collect(Collectors.joining(", ")); + } + + private static List ofNullable(Object... values) { + List result = new ArrayList(); + for (var v: values) { + result.add(v); + } + return result; + } + + private List ctorArgs; + private List methodArgs; + private Method method; } static TestDesc create(Method m, Object... args) { @@ -68,11 +127,22 @@ desc.clazz = m.getDeclaringClass(); desc.functionName = m.getName(); if (args.length != 0) { - desc.args = Stream.of(args).map(Object::toString).collect( - Collectors.joining(",")); + desc.functionArgs = Stream.of(args).map(v -> { + if (v.getClass().isArray()) { + return String.format("%s(length=%d)", + Arrays.deepToString((Object[]) v), + Array.getLength(v)); + } + return String.format("%s", v); + }).collect(Collectors.joining(", ")); } return desc; } + + private Class clazz; + private String functionName; + private String functionArgs; + private String instanceArgs; } TestInstance(ThrowingRunnable testBody) { @@ -81,18 +151,19 @@ this.testBody = (unused) -> testBody.run(); this.beforeActions = Collections.emptyList(); this.afterActions = Collections.emptyList(); - this.testDesc = TestDesc.create(); + this.testDesc = TestDesc.createBuilder().get(); + this.dryRun = false; } - TestInstance(ThrowingFunction testConstructor, MethodCall testBody, - List beforeActions, - List afterActions) { + TestInstance(MethodCall testBody, List beforeActions, + List afterActions, boolean dryRun) { assertCount = 0; - this.testConstructor = testConstructor; + this.testConstructor = v -> ((MethodCall)v).newInstance(); this.testBody = testBody; this.beforeActions = beforeActions; this.afterActions = afterActions; this.testDesc = testBody.createDescription(); + this.dryRun = dryRun; } void notifyAssert() { @@ -133,17 +204,44 @@ } } + Path workDir() { + Path result = Path.of("."); + List components = new ArrayList<>(); + + String testFunctionName = functionName(); + if (testFunctionName != null) { + components.add(testFunctionName); + } + + if (isPrametrized()) { + components.add(String.format("%08x", fullName().hashCode())); + } + + if (!components.isEmpty()) { + result = result.resolve(String.join(".", components)); + } + + return result; + } + + boolean isPrametrized() { + return Stream.of(testDesc.functionArgs, testDesc.instanceArgs).anyMatch( + Objects::nonNull); + } + @Override public void run() throws Throwable { - final String fullName = testDesc.testFullName(); + final String fullName = fullName(); TKit.log(String.format("[ RUN ] %s", fullName)); try { Object testInstance = testConstructor.apply(testBody); - beforeActions.forEach((a) -> ThrowingConsumer.toConsumer(a).accept( + beforeActions.forEach(a -> ThrowingConsumer.toConsumer(a).accept( testInstance)); - Files.createDirectories(TKit.workDir()); try { - testBody.accept(testInstance); + if (!dryRun) { + Files.createDirectories(workDir()); + testBody.accept(testInstance); + } } finally { afterActions.forEach(a -> TKit.ignoreExceptions(() -> a.accept( testInstance))); @@ -155,6 +253,11 @@ } else if (status == null) { status = Status.Failed; } + + if (!KEEP_WORK_DIR.contains(status)) { + TKit.deleteDirectoryRecursive(workDir()); + } + TKit.log(String.format("%s %s; checks=%d", status, fullName, assertCount)); } @@ -196,4 +299,30 @@ private final ThrowingConsumer testBody; private final List beforeActions; private final List afterActions; + private final boolean dryRun; + + private final static Set KEEP_WORK_DIR = Functional.identity( + () -> { + final String propertyName = "keep-work-dir"; + Set keepWorkDir = TKit.tokenizeConfigProperty( + propertyName); + if (keepWorkDir == null) { + return Set.of(Status.Failed); + } + + Predicate> isOneOf = options -> { + return !Collections.disjoint(keepWorkDir, options); + }; + + Set result = new HashSet<>(); + if (isOneOf.test(Set.of("pass", "p"))) { + result.add(Status.Passed); + } + if (isOneOf.test(Set.of("fail", "f"))) { + result.add(Status.Failed); + } + + return Collections.unmodifiableSet(result); + }).get(); + } diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java Wed Oct 16 10:32:08 2019 -0400 @@ -62,7 +62,7 @@ } private void verifyDesktopShortcut() { - boolean appInstalled = cmd.launcherInstallationPath().toFile().exists(); + boolean appInstalled = cmd.appLauncherPath().toFile().exists(); if (cmd.hasArgument("--win-shortcut")) { if (isUserLocalInstall(cmd)) { verifyUserLocalDesktopShortcut(appInstalled); @@ -102,7 +102,7 @@ } private void verifyStartMenuShortcut() { - boolean appInstalled = cmd.launcherInstallationPath().toFile().exists(); + boolean appInstalled = cmd.appLauncherPath().toFile().exists(); if (cmd.hasArgument("--win-menu")) { if (isUserLocalInstall(cmd)) { verifyUserLocalStartMenuShortcut(appInstalled); @@ -122,16 +122,23 @@ () -> "Unknown"), cmd.name() + ".lnk"); } + private void verifyStartMenuShortcut(Path shortcutsRoot, boolean exists) { + Path shortcutPath = shortcutsRoot.resolve(startMenuShortcutPath()); + verifyShortcut(shortcutPath, exists); + if (!exists) { + TKit.assertPathExists(shortcutPath.getParent(), false); + } + } + private void verifySystemStartMenuShortcut(boolean exists) { - Path dir = Path.of(queryRegistryValueCache( - SYSTEM_SHELL_FOLDERS_REGKEY, "Common Programs")); - verifyShortcut(dir.resolve(startMenuShortcutPath()), exists); + verifyStartMenuShortcut(Path.of(queryRegistryValueCache( + SYSTEM_SHELL_FOLDERS_REGKEY, "Common Programs")), exists); + } private void verifyUserLocalStartMenuShortcut(boolean exists) { - Path dir = Path.of(queryRegistryValueCache( - USER_SHELL_FOLDERS_REGKEY, "Programs")); - verifyShortcut(dir.resolve(startMenuShortcutPath()), exists); + verifyStartMenuShortcut(Path.of(queryRegistryValueCache( + USER_SHELL_FOLDERS_REGKEY, "Programs")), exists); } private void verifyFileAssociationsRegistry() { @@ -140,7 +147,7 @@ } private void verifyFileAssociationsRegistry(Path faFile) { - boolean appInstalled = cmd.launcherInstallationPath().toFile().exists(); + boolean appInstalled = cmd.appLauncherPath().toFile().exists(); try { TKit.trace(String.format( "Get file association properties from [%s] file", diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/junit/jdk/jpackage/internal/AppImageFileTest.java --- a/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/AppImageFileTest.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/AppImageFileTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -77,6 +77,11 @@ "", "", "")); + assertInvalid(createFromXml( + "", + "A", + "B", + "")); } @Test @@ -86,9 +91,9 @@ "Foo", "")).getLauncherName()); - Assert.assertEquals("Foo", (createFromXml( + Assert.assertEquals("Boo", (createFromXml( "", - "Foo", + "Boo", "Bar", "")).getLauncherName()); @@ -130,7 +135,7 @@ params.put("add-launcher", launchersAsMap); AppImageFile aif = create(params); - List addLauncherNames = aif.getAddLauncherNames(); + List addLauncherNames = aif.getAddLauncherNames(); Assert.assertEquals(2, addLauncherNames.size()); Assert.assertTrue(addLauncherNames.contains("Launcher2Name")); Assert.assertTrue(addLauncherNames.contains("Launcher3Name")); diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/macosx/BundleIdentifierTest.java --- a/test/jdk/tools/jpackage/macosx/BundleIdentifierTest.java Wed Oct 16 09:57:23 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2018, 2019, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.File; -import java.io.FileInputStream; -import java.nio.file.Files; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathFactory; - -/* - * @test - * @summary jpackage create image bundle identifier test - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @modules jdk.jpackage - * @requires (os.family == "mac") - * @run main/othervm -Xmx512m BundleIdentifierTest - */ -public class BundleIdentifierTest { - private static final String OUTPUT = "output"; - private static final String app = JPackagePath.getApp(); - private static final String appOutput = JPackagePath.getAppOutputFile(); - private static final String MAC_PACKAGE_IDENTIFIER = "TestBundleIdentifier"; - private static final String APP_NAME = "test"; - private static final String MAIN_CLASS = "Hello"; - - private static final String [] CMD_1 = { - "--package-type", "app-image", - "--input", "input", - "--dest", OUTPUT, - "--name", APP_NAME, - "--main-jar", "hello.jar", - "--main-class", MAIN_CLASS - }; - - private static final String [] CMD_2 = { - "--package-type", "app-image", - "--input", "input", - "--dest", OUTPUT, - "--name", APP_NAME, - "--main-jar", "hello.jar", - "--main-class", MAIN_CLASS, - "--mac-package-identifier", MAC_PACKAGE_IDENTIFIER - }; - - private static void validateResult(String[] result) throws Exception { - if (result.length != 2) { - throw new AssertionError( - "Unexpected number of lines: " + result.length); - } - - if (!result[0].trim().equals("jpackage test application")) { - throw new AssertionError("Unexpected result[0]: " + result[0]); - } - - if (!result[1].trim().equals("args.length: 0")) { - throw new AssertionError("Unexpected result[1]: " + result[1]); - } - } - - private static void validate() throws Exception { - int retVal = JPackageHelper.execute(null, app); - if (retVal != 0) { - throw new AssertionError( - "Test application exited with error: " + retVal); - } - - File outfile = new File(appOutput); - if (!outfile.exists()) { - throw new AssertionError(appOutput + " was not created"); - } - - String output = Files.readString(outfile.toPath()); - String[] result = output.split("\n"); - validateResult(result); - } - - private static void validateBundleIdentifier(String bundleIdentifier) - throws Exception { - System.out.println("Validating bundleIdentifier: " + bundleIdentifier); - - File infoPList = new File(OUTPUT + File.separator + APP_NAME + ".app" + - File.separator + "Contents" + File.separator + "Info.plist"); - - DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultInstance(); - dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); - DocumentBuilder b = dbf.newDocumentBuilder(); - org.w3c.dom.Document doc = b.parse(new FileInputStream( - infoPList.getAbsolutePath())); - - XPath xPath = XPathFactory.newInstance().newXPath(); - // Query for the value of element preceding element - // with value equal to CFBundleIdentifier - String v = (String)xPath.evaluate( - "//string[preceding-sibling::key = \"CFBundleIdentifier\"][1]", - doc, XPathConstants.STRING); - - if (!v.equals(bundleIdentifier)) { - throw new AssertionError("Unexpected value of CFBundleIdentifier key: [" - + v + "]. Expected value: [" + bundleIdentifier + "]"); - } - } - - private static void testCreateAppImage(String [] cmd, - String bundleIdentifier, - boolean validateApp) throws Exception { - JPackageHelper.executeCLI(true, cmd); - if (validateApp) { - validate(); - } - validateBundleIdentifier(bundleIdentifier); - } - - private static void testCreateAppImageToolProvider(String [] cmd, - String bundleIdentifier, - boolean validateApp) throws Exception { - JPackageHelper.executeToolProvider(true, cmd); - if (validateApp) { - validate(); - } - validateBundleIdentifier(bundleIdentifier); - } - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloImageJar(); - testCreateAppImage(CMD_1, MAIN_CLASS, false); - JPackageHelper.deleteOutputFolder(OUTPUT); - testCreateAppImageToolProvider(CMD_1, MAIN_CLASS, false); - JPackageHelper.deleteOutputFolder(OUTPUT); - testCreateAppImage(CMD_2, MAC_PACKAGE_IDENTIFIER, true); - JPackageHelper.deleteOutputFolder(OUTPUT); - testCreateAppImageToolProvider(CMD_2, MAC_PACKAGE_IDENTIFIER, true); - } -} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/macosx/BundleNameTest.java --- a/test/jdk/tools/jpackage/macosx/BundleNameTest.java Wed Oct 16 09:57:23 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2018, 2019, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.File; -import java.io.FileInputStream; -import java.nio.file.Files; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathFactory; - -/* - * @test - * @summary jpackage create image bundle name test - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @modules jdk.jpackage - * @requires (os.family == "mac") - * @run main/othervm -Xmx512m BundleNameTest - */ -public class BundleNameTest { - private static final String OUTPUT = "output"; - private static final String app = JPackagePath.getApp(); - private static final String appOutput = JPackagePath.getAppOutputFile(); - private static final String MAC_BUNDLE_NAME = "TestBundleName"; - private static final String APP_NAME = "test"; - - private static final String [] CMD_1 = { - "--package-type", "app-image", - "--input", "input", - "--dest", OUTPUT, - "--name", APP_NAME, - "--main-jar", "hello.jar", - "--main-class", "Hello" - }; - - private static final String [] CMD_2 = { - "--package-type", "app-image", - "--input", "input", - "--dest", OUTPUT, - "--name", APP_NAME, - "--main-jar", "hello.jar", - "--main-class", "Hello", - "--mac-package-name", MAC_BUNDLE_NAME - }; - - private static void validateResult(String[] result) throws Exception { - if (result.length != 2) { - throw new AssertionError( - "Unexpected number of lines: " + result.length); - } - - if (!result[0].trim().equals("jpackage test application")) { - throw new AssertionError("Unexpected result[0]: " + result[0]); - } - - if (!result[1].trim().equals("args.length: 0")) { - throw new AssertionError("Unexpected result[1]: " + result[1]); - } - } - - private static void validate() throws Exception { - int retVal = JPackageHelper.execute(null, app); - if (retVal != 0) { - throw new AssertionError( - "Test application exited with error: " + retVal); - } - - File outfile = new File(appOutput); - if (!outfile.exists()) { - throw new AssertionError(appOutput + " was not created"); - } - - String output = Files.readString(outfile.toPath()); - String[] result = output.split("\n"); - validateResult(result); - } - - private static void validateBundleName(String bundleName) throws Exception { - System.out.println("Validating bundleName: " + bundleName); - - File infoPList = new File(OUTPUT + File.separator + APP_NAME + ".app" + - File.separator + "Contents" + File.separator + "Info.plist"); - - DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultInstance(); - dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); - DocumentBuilder b = dbf.newDocumentBuilder(); - org.w3c.dom.Document doc = b.parse(new FileInputStream( - infoPList.getAbsolutePath())); - - XPath xPath = XPathFactory.newInstance().newXPath(); - // Query for the value of element preceding element - // with value equal to CFBundleName - String v = (String)xPath.evaluate( - "//string[preceding-sibling::key = \"CFBundleName\"][1]", - doc, XPathConstants.STRING); - - if (!v.equals(bundleName)) { - throw new AssertionError("Unexpected value of CFBundleName key: [" - + v + "]. Expected value: [" + bundleName + "]"); - } - } - - private static void testCreateAppImage(String [] cmd, - String bundleName, - boolean validateApp) throws Exception { - JPackageHelper.executeCLI(true, cmd); - if (validateApp) { - validate(); - } - validateBundleName(bundleName); - } - - private static void testCreateAppImageToolProvider(String [] cmd, - String bundleName, - boolean validateApp) throws Exception { - JPackageHelper.executeToolProvider(true, cmd); - if (validateApp) { - validate(); - } - validateBundleName(bundleName); - } - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloImageJar(); - testCreateAppImage(CMD_1, APP_NAME, false); - JPackageHelper.deleteOutputFolder(OUTPUT); - testCreateAppImageToolProvider(CMD_1, APP_NAME, false); - JPackageHelper.deleteOutputFolder(OUTPUT); - testCreateAppImage(CMD_2, MAC_BUNDLE_NAME, true); - JPackageHelper.deleteOutputFolder(OUTPUT); - testCreateAppImageToolProvider(CMD_2, MAC_BUNDLE_NAME, true); - } -} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/macosx/MacPropertiesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/tools/jpackage/macosx/MacPropertiesTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2019, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.jpackage.test.TKit; +import jdk.jpackage.test.MacHelper; +import jdk.jpackage.test.JPackageCommand; +import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.Annotations.Parameter; + + +/** + * Test --mac-package-name, --mac-package-identifier parameters. + */ + +/* + * @test + * @summary jpackage with --mac-package-name, --mac-package-identifier + * @library ../helpers + * @build jdk.jpackage.test.* + * @requires (os.family == "mac") + * @modules jdk.jpackage/jdk.jpackage.internal + * @compile MacPropertiesTest.java + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=MacPropertiesTest + */ +public class MacPropertiesTest { + @Test + @Parameter("MacPackageNameTest") + public void testPackageName(String packageName) { + testParameterInAppImage("--mac-package-name", "CFBundleName", + packageName); + } + + @Test + @Parameter("Foo") + public void testPackageIdetifier(String packageId) { + testParameterInAppImage("--mac-package-identifier", "CFBundleIdentifier", + packageId); + } + + private static void testParameterInAppImage(String jpackageParameterName, + String plistKeyName, String value) { + JPackageCommand cmd = JPackageCommand.helloAppImage() + .addArguments(jpackageParameterName, value); + + cmd.executeAndAssertHelloAppImageCreated(); + + var plist = MacHelper.readPListFromAppImage(cmd.outputBundle()); + + TKit.assertEquals(value, plist.queryValue(plistKeyName), String.format( + "Check value of %s plist key", plistKeyName)); + } +} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/macosx/SigningAppImageTest.java --- a/test/jdk/tools/jpackage/macosx/SigningAppImageTest.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/macosx/SigningAppImageTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -59,10 +59,10 @@ "jpackagerTest.keychain"); cmd.executeAndAssertHelloAppImageCreated(); - Path launcherPath = cmd.appImage().resolve(cmd.launcherPathInAppImage()); + Path launcherPath = cmd.appLauncherPath(); SigningBase.verifyCodesign(launcherPath, true); - Path appImage = cmd.appImage(); + Path appImage = cmd.outputBundle(); SigningBase.verifyCodesign(appImage, true); SigningBase.verifySpctl(appImage, "exec"); }); diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/macosx/SigningPackageTest.java --- a/test/jdk/tools/jpackage/macosx/SigningPackageTest.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/macosx/SigningPackageTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -60,25 +60,14 @@ SigningBase.verifyCodesign(outputBundle, false); } - private static void verifyAppImageInDMG(JPackageCommand cmd) throws Exception { - Path disk = Paths.get("/Volumes", cmd.name()); - try { - new Executor() - .setExecutable("/usr/bin/hdiutil") - .addArgument("attach").addArgument(cmd.outputBundle()) - .execute().assertExitCodeIsZero(); - + private static void verifyAppImageInDMG(JPackageCommand cmd) { + MacHelper.withExplodedDmg(cmd, disk -> { Path appImageInDMG = disk.resolve(cmd.name() + ".app"); Path launcherPath = appImageInDMG.resolve(Path.of("Contents", "MacOS", cmd.name())); SigningBase.verifyCodesign(launcherPath, true); SigningBase.verifyCodesign(appImageInDMG, true); SigningBase.verifySpctl(appImageInDMG, "exec"); - } finally { - new Executor() - .setExecutable("/usr/bin/hdiutil") - .addArgument("detach").addArgument(disk) - .execute().assertExitCodeIsZero(); - } + }); } public static void main(String[] args) throws Exception { @@ -94,14 +83,10 @@ "--mac-signing-keychain", "jpackagerTest.keychain"); }) .forTypes(PackageType.MAC_PKG) - .addBundleVerifier(cmd -> { - verifyPKG(cmd); - }) + .addBundleVerifier(SigningPackageTest::verifyPKG) .forTypes(PackageType.MAC_DMG) - .addBundleVerifier(cmd -> { - verifyDMG(cmd); - verifyAppImageInDMG(cmd); - }) + .addBundleVerifier(SigningPackageTest::verifyDMG) + .addBundleVerifier(SigningPackageTest::verifyAppImageInDMG) .run(); }); } diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/macosx/base/SigningBase.java --- a/test/jdk/tools/jpackage/macosx/base/SigningBase.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/macosx/base/SigningBase.java Wed Oct 16 10:32:08 2019 -0400 @@ -37,14 +37,8 @@ public static String KEYCHAIN = "jpackagerTest.keychain"; private static void checkString(List result, String lookupString) { - result.stream() - .filter(line -> line.trim().equals(lookupString)).findFirst().or( - () -> { - TKit.assertUnexpected(String.format( - "Failed to find [%s] string in the output", - lookupString)); - return null; - }); + TKit.assertTextStream(lookupString).predicate( + (line, what) -> line.trim().equals(what)).apply(result.stream()); } private static List codesignResult(Path target, boolean signed) { @@ -62,7 +56,7 @@ private static void verifyCodesignResult(List result, Path target, boolean signed) { - result.stream().peek(TKit::trace); + result.stream().forEachOrdered(TKit::trace); if (signed) { String lookupString = target.toString() + ": valid on disk"; checkString(result, lookupString); @@ -86,7 +80,7 @@ } private static void verifySpctlResult(List result, Path target, String type) { - result.stream().peek(TKit::trace); + result.stream().forEachOrdered(TKit::trace); String lookupString = target.toString() + ": accepted"; checkString(result, lookupString); lookupString = "source=" + DEV_NAME; @@ -110,7 +104,7 @@ } private static void verifyPkgutilResult(List result) { - result.stream().peek(line -> TKit.trace(line)); + result.stream().forEachOrdered(TKit::trace); String lookupString = "Status: signed by a certificate trusted for current user"; checkString(result, lookupString); lookupString = "1. " + INSTALLER_CERT; diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/macosx/base/SigningCheck.java --- a/test/jdk/tools/jpackage/macosx/base/SigningCheck.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/macosx/base/SigningCheck.java Wed Oct 16 10:32:08 2019 -0400 @@ -88,13 +88,12 @@ .setExecutable("security") .addArguments("dump-trust-settings") .executeAndGetOutput(); - result.stream().peek(TKit::trace); - result.stream() - .filter(line -> line.trim().endsWith(name)).findFirst().orElseThrow( - () -> { - throw TKit.throwSkippedException("Certifcate not trusted by current user: " - + name); - }); + result.stream().forEachOrdered(TKit::trace); + TKit.assertTextStream(name) + .predicate((line, what) -> line.trim().endsWith(what)) + .orElseThrow(() -> TKit.throwSkippedException( + "Certifcate not trusted by current user: " + name)) + .apply(result.stream()); } } diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/AddModulesTest.java --- a/test/jdk/tools/jpackage/share/AddModulesTest.java Wed Oct 16 09:57:23 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2018, 2019, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - /* - * @test - * @summary jpackage create image module test - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @build Base - * @modules jdk.jpackage - * @run main/othervm -Xmx512m AddModulesTest - */ -public class AddModulesTest { - private static final String OUTPUT = "output"; - - private static final String [] CMD1 = { - "--package-type", "app-image", - "--dest", OUTPUT, - "--name", "test", - "--module", "com.hello/com.hello.Hello", - "--module-path", "input", - "--add-modules", "java.desktop", - }; - - private static final String [] CMD2 = { - "--package-type", "app-image", - "--dest", OUTPUT, - "--name", "test", - "--module", "com.hello/com.hello.Hello", - "--module-path", "input", - "--add-modules", "java.desktop,java.xml", - }; - - private static final String [] CMD3 = { - "--package-type", "app-image", - "--dest", OUTPUT, - "--name", "test", - "--module", "com.hello/com.hello.Hello", - "--module-path", "input", - "--add-modules", "java.desktop", - "--add-modules", "java.xml", - }; - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloModule(); - Base.testCreateAppImage(CMD1); - JPackageHelper.deleteOutputFolder(OUTPUT); - Base.testCreateAppImageToolProvider(CMD1); - JPackageHelper.deleteOutputFolder(OUTPUT); - Base.testCreateAppImageToolProvider(CMD2); - JPackageHelper.deleteOutputFolder(OUTPUT); - Base.testCreateAppImageToolProvider(CMD3); - } - -} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/AdditionalLaunchersTest.java --- a/test/jdk/tools/jpackage/share/AdditionalLaunchersTest.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/share/AdditionalLaunchersTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -31,6 +31,7 @@ import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.FileAssociations; +import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.TKit; /** @@ -47,41 +48,43 @@ * @library ../helpers * @build jdk.jpackage.test.* * @modules jdk.jpackage/jdk.jpackage.internal - * @run main/othervm/timeout=360 -Xmx512m AdditionalLaunchersTest + * @compile AdditionalLaunchersTest.java + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=AdditionalLaunchersTest */ + public class AdditionalLaunchersTest { - public static void main(String[] args) { - TKit.run(args, () -> { - FileAssociations fa = new FileAssociations( - MethodHandles.lookup().lookupClass().getSimpleName()); + @Test + public void test() { + FileAssociations fa = new FileAssociations( + MethodHandles.lookup().lookupClass().getSimpleName()); - // Configure a bunch of additional launchers and also setup - // file association to make sure it will be linked only to the main - // launcher. + // Configure a bunch of additional launchers and also setup + // file association to make sure it will be linked only to the main + // launcher. - PackageTest packageTest = new PackageTest().configureHelloApp() - .addInitializer(cmd -> { - fa.createFile(); - cmd.addArguments("--file-associations", fa.getPropertiesFile()); - cmd.addArguments("--arguments", "Duke", "--arguments", "is", - "--arguments", "the", "--arguments", "King"); - }); + PackageTest packageTest = new PackageTest().configureHelloApp() + .addInitializer(cmd -> { + fa.createFile(); + cmd.addArguments("--file-associations", fa.getPropertiesFile()); + cmd.addArguments("--arguments", "Duke", "--arguments", "is", + "--arguments", "the", "--arguments", "King"); + }); - packageTest.addHelloAppFileAssociationsVerifier(fa); + packageTest.addHelloAppFileAssociationsVerifier(fa); - new AdditionalLauncher("Baz2").setArguments().applyTo(packageTest); - new AdditionalLauncher("foo").setArguments("yep!").applyTo(packageTest); + new AdditionalLauncher("Baz2").setArguments().applyTo(packageTest); + new AdditionalLauncher("foo").setArguments("yep!").applyTo(packageTest); - AdditionalLauncher barLauncher = new AdditionalLauncher("Bar").setArguments( - "one", "two", "three"); - packageTest.forTypes(PackageType.LINUX).addInitializer(cmd -> { - barLauncher.setIcon(TKit.TEST_SRC_ROOT.resolve("apps/dukeplug.png")); - }); - barLauncher.applyTo(packageTest); + AdditionalLauncher barLauncher = new AdditionalLauncher("Bar").setArguments( + "one", "two", "three"); + if (TKit.isLinux()) { + barLauncher.setIcon(TKit.TEST_SRC_ROOT.resolve("apps/dukeplug.png")); + } + barLauncher.applyTo(packageTest); - packageTest.run(); - }); + packageTest.run(); } private static Path replaceFileName(Path path, String newFileName) { @@ -129,12 +132,11 @@ TKit.createPropertiesFile(propsFile, properties); }); test.addInstallVerifier(cmd -> { - Path launcherPath = replaceFileName( - cmd.launcherInstallationPath(), name); + Path launcherPath = replaceFileName(cmd.appLauncherPath(), name); TKit.assertExecutableFileExists(launcherPath); - if (cmd.isFakeRuntimeInstalled(String.format( + if (cmd.isFakeRuntime(String.format( "Not running %s launcher", launcherPath))) { return; } @@ -143,8 +145,7 @@ String[]::new)); }); test.addUninstallVerifier(cmd -> { - Path launcherPath = replaceFileName( - cmd.launcherInstallationPath(), name); + Path launcherPath = replaceFileName(cmd.appLauncherPath(), name); TKit.assertPathExists(launcherPath, false); }); diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/AppMainClassModuleTest.java --- a/test/jdk/tools/jpackage/share/AppMainClassModuleTest.java Wed Oct 16 09:57:23 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2018, 2019, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.File; -import java.nio.file.Files; - -/* - * @test - * @summary jpackage create image using main class from main module - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @modules jdk.jpackage - * @run main/othervm -Xmx512m AppMainClassModuleTest - */ -public class AppMainClassModuleTest { - - private static final String OUTPUT = "output"; - private static final String app = JPackagePath.getApp(); - private static final String appOutput = JPackagePath.getAppOutputFile(); - - private static final String[] CMD = { - "--package-type", "app-image", - "--input", "input", - "--dest", OUTPUT, - "--name", "test", - "--module", "com.hello", - "--module-path", "input" - }; - - private static final String[] CMD_MAIN_CLASS = { - "--package-type", "app-image", - "--input", "input", - "--dest", OUTPUT, - "--name", "test", - "--module", "com.hello/com.hello.Hello", - "--module-path", "input" - }; - - private static void validate(String buildOutput) throws Exception { - - File outfile = new File(appOutput); - int retVal = JPackageHelper.execute(outfile, app); - if (retVal != 0) { - throw new AssertionError( - "Test application exited with error: "); - } - - if (!outfile.exists()) { - throw new AssertionError(appOutput + " was not created"); - } - String output = Files.readString(outfile.toPath()); - String[] result = output.split("\n"); - - if (!result[0].trim().equals("jpackage test application")) { - throw new AssertionError("Unexpected result[0]: " + result[0]); - } - - if (!result[1].trim().equals("args.length: 0")) { - throw new AssertionError("Unexpected result[1]: " + result[1]); - } - } - - private static void testMainClassFromModule() throws Exception { - JPackageHelper.createHelloModule( - new JPackageHelper.ModuleArgs(null, "com.hello.Hello")); - - validate(JPackageHelper.executeCLI(true, CMD)); - JPackageHelper.deleteOutputFolder(OUTPUT); - validate(JPackageHelper.executeToolProvider(true, CMD)); - JPackageHelper.deleteOutputFolder(OUTPUT); - } - - private static void testMainClassFromCLI() throws Exception { - JPackageHelper.createHelloModule( - new JPackageHelper.ModuleArgs(null, "com.hello.Hello2")); - - validate(JPackageHelper.executeCLI(true, CMD_MAIN_CLASS)); - JPackageHelper.deleteOutputFolder(OUTPUT); - validate(JPackageHelper.executeToolProvider(true, CMD_MAIN_CLASS)); - } - - public static void main(String[] args) throws Exception { - testMainClassFromModule(); - testMainClassFromCLI(); - } - -} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/AppVersionModuleTest.java --- a/test/jdk/tools/jpackage/share/AppVersionModuleTest.java Wed Oct 16 09:57:23 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2018, 2019, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.File; -import java.nio.file.Files; - -/* - * @test - * @summary jpackage create image using version from main module - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @modules jdk.jpackage - * @run main/othervm -Xmx512m AppVersionModuleTest - */ -public class AppVersionModuleTest { - private static final String OUTPUT = "output"; - private static final String appCfg = JPackagePath.getAppCfg(); - private static final String MODULE_VERSION = "2.7"; - private static final String CLI_VERSION = "3.5"; - - private static final String[] CMD_MODULE_VERSION = { - "--package-type", "app-image", - "--input", "input", - "--dest", OUTPUT, - "--name", "test", - "--module", "com.hello/com.hello.Hello", - "--module-path", "input" - }; - - private static final String[] CMD_CLI_VERSION = { - "--package-type", "app-image", - "--input", "input", - "--dest", OUTPUT, - "--name", "test", - "--module", "com.hello/com.hello.Hello", - "--module-path", "input", - "--app-version", CLI_VERSION - }; - - private static void validate(String version) - throws Exception { - File outfile = new File(appCfg); - if (!outfile.exists()) { - throw new AssertionError(appCfg + " was not created"); - } - - String output = Files.readString(outfile.toPath()); - if (version == null) { - version = MODULE_VERSION; - } - - String expected = "app.version=" + version; - if (!output.contains(expected)) { - System.err.println("Expected: " + expected); - throw new AssertionError("Cannot find expected entry in config file"); - } - } - - private static void testVersion() throws Exception { - JPackageHelper.executeCLI(true, CMD_MODULE_VERSION); - validate(null); - JPackageHelper.deleteOutputFolder(OUTPUT); - JPackageHelper.executeCLI(true, CMD_CLI_VERSION); - validate(CLI_VERSION); - } - - private static void testVersionToolProvider() throws Exception { - JPackageHelper.deleteOutputFolder(OUTPUT); - JPackageHelper.executeToolProvider(true, CMD_MODULE_VERSION); - validate(null); - JPackageHelper.deleteOutputFolder(OUTPUT); - JPackageHelper.executeToolProvider(true, CMD_CLI_VERSION); - validate(CLI_VERSION); - } - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloModule( - new JPackageHelper.ModuleArgs(MODULE_VERSION, null)); - testVersion(); - testVersionToolProvider(); - } - -} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/AppVersionTest.java --- a/test/jdk/tools/jpackage/share/AppVersionTest.java Wed Oct 16 09:57:23 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2018, 2019, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.File; -import java.nio.file.Files; - -/* - * @test - * @summary jpackage create image --app-version test - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @modules jdk.jpackage - * @run main/othervm -Xmx512m AppVersionTest - */ -public class AppVersionTest { - private static final String OUTPUT = "output"; - private static final String appCfg = JPackagePath.getAppCfg(); - private static final String VERSION = "2.3"; - private static final String VERSION_DEFAULT = "1.0"; - - private static final String[] CMD = { - "--package-type", "app-image", - "--input", "input", - "--dest", OUTPUT, - "--name", "test", - "--main-jar", "hello.jar", - "--main-class", "Hello", - }; - - private static final String[] CMD_VERSION = { - "--package-type", "app-image", - "--input", "input", - "--dest", OUTPUT, - "--name", "test", - "--main-jar", "hello.jar", - "--main-class", "Hello", - "--app-version", VERSION}; - - private static void validate(String version) - throws Exception { - File outfile = new File(appCfg); - if (!outfile.exists()) { - throw new AssertionError(appCfg + " was not created"); - } - - String output = Files.readString(outfile.toPath()); - if (version == null) { - version = VERSION_DEFAULT; - } - - String expected = "app.version=" + version; - if (!output.contains(expected)) { - System.err.println("Expected: " + expected); - throw new AssertionError("Cannot find expected entry in config file"); - } - } - - private static void testVersion() throws Exception { - JPackageHelper.executeCLI(true, CMD); - validate(null); - JPackageHelper.deleteOutputFolder(OUTPUT); - JPackageHelper.executeCLI(true, CMD_VERSION); - validate(VERSION); - } - - private static void testVersionToolProvider() throws Exception { - JPackageHelper.deleteOutputFolder(OUTPUT); - JPackageHelper.executeToolProvider(true, CMD); - validate(null); - JPackageHelper.deleteOutputFolder(OUTPUT); - JPackageHelper.executeToolProvider(true, CMD_VERSION); - validate(VERSION); - } - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloImageJar(); - testVersion(); - testVersionToolProvider(); - } - -} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/ArgumentsTest.java --- a/test/jdk/tools/jpackage/share/ArgumentsTest.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/share/ArgumentsTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -48,13 +48,18 @@ * @summary jpackage create image with --arguments test * @library ../helpers * @build jdk.jpackage.test.* - * @modules jdk.jpackage + * @modules jdk.jpackage/jdk.jpackage.internal * @compile ArgumentsTest.java * @run main/othervm -Xmx512m jdk.jpackage.test.Main * --jpt-run=ArgumentsTest - * --jpt-before-run=jdk.jpackage.test.JPackageCommand.useToolProviderByDefault */ public class ArgumentsTest { + + @BeforeEach + public static void useJPackageToolProvider() { + JPackageCommand.useToolProviderByDefault(); + } + @Test @Parameter("Goodbye") @Parameter("com.hello/com.hello.Hello") @@ -73,8 +78,8 @@ cmd.executeAndAssertImageCreated(); - Path launcherPath = cmd.appImage().resolve(cmd.launcherPathInAppImage()); - if (!cmd.isFakeRuntimeInAppImage(String.format( + Path launcherPath = cmd.appLauncherPath(); + if (!cmd.isFakeRuntime(String.format( "Not running [%s] launcher", launcherPath))) { HelloApp.executeAndVerifyOutput(launcherPath, TRICKY_ARGUMENTS); } diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/FileAssociationsTest.java --- a/test/jdk/tools/jpackage/share/FileAssociationsTest.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/share/FileAssociationsTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -24,6 +24,7 @@ import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.FileAssociations; +import jdk.jpackage.test.Annotations.Test; /** * Test --file-associations parameter. Output of the test should be @@ -49,18 +50,19 @@ * @library ../helpers * @build jdk.jpackage.test.* * @modules jdk.jpackage/jdk.jpackage.internal - * @run main/othervm/timeout=360 -Xmx512m FileAssociationsTest + * @compile FileAssociationsTest.java + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=FileAssociationsTest */ public class FileAssociationsTest { - public static void main(String[] args) { - TKit.run(args, () -> { - PackageTest packageTest = new PackageTest(); + @Test + public static void test() { + PackageTest packageTest = new PackageTest(); - applyFileAssociations(packageTest, new FileAssociations("jptest1")); - applyFileAssociations(packageTest, - new FileAssociations("jptest2").setFilename("fa2")); - packageTest.run(); - }); + applyFileAssociations(packageTest, new FileAssociations("jptest1")); + applyFileAssociations(packageTest, + new FileAssociations("jptest2").setFilename("fa2")); + packageTest.run(); } private static void applyFileAssociations(PackageTest test, diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/HelpTest.java --- a/test/jdk/tools/jpackage/share/HelpTest.java Wed Oct 16 09:57:23 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2018, 2019, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - /* - * @test - * @summary jpackage help test - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @modules jdk.jpackage - * @run main/othervm -Xmx512m HelpTest - */ -public class HelpTest { - - // Platform specific help messages. - private static final String WINDOWS_HELP = - "--win-dir-chooser"; - private static final String OSX_HELP = - "--mac-package-identifier"; - private static final String LINUX_HELP = - "--linux-package-name"; - - private static void validate(String output1, String output2) - throws Exception { - if (output1.split("\n").length < 25) { - throw new AssertionError("jpacakger --help failed"); - } - - if (output2.split("\n").length < 25) { - throw new AssertionError("jpacakger -h failed"); - } - - // Make sure output matches for --help and -h - if (!output1.equals(output2)) { - System.err.println("================= --help ================="); - System.err.println(output1); - - System.err.println("=================== -h ==================="); - System.err.println(output2); - - throw new AssertionError( - "jpacakger help text does not match between --help and -h"); - } - - if (JPackageHelper.isWindows()) { - if (!output1.contains(WINDOWS_HELP)) { - throw new AssertionError( - "jpacakger help text missing Windows specific help"); - } - - if (output1.contains(OSX_HELP) || output1.contains(LINUX_HELP)) { - throw new AssertionError( - "jpacakger help text contains other platforms specific help"); - - } - } else if (JPackageHelper.isOSX()) { - if (!output1.contains(OSX_HELP)) { - throw new AssertionError( - "jpacakger help text missing OS X specific help"); - } - - if (output1.contains(WINDOWS_HELP) || - output1.contains(LINUX_HELP)) { - throw new AssertionError( - "jpacakger help text contains other platforms specific help"); - } - } else if (JPackageHelper.isLinux()) { - if (!output1.contains(LINUX_HELP)) { - throw new AssertionError( - "jpacakger help text missing Linux specific help"); - } - - if (output1.contains(OSX_HELP) || output1.contains(WINDOWS_HELP)) { - throw new AssertionError( - "jpacakger help text contains other platforms specific help"); - } - } - } - - private static void testHelp() throws Exception { - String output1 = JPackageHelper.executeCLI(true, "--help"); - String output2 = JPackageHelper.executeCLI(true, "-h"); - validate(output1, output2); - } - - private static void testHelpToolProvider() throws Exception { - String output1 = JPackageHelper.executeToolProvider(true, "--help"); - String output2 = JPackageHelper.executeToolProvider(true, "-h"); - validate(output1, output2); - } - - public static void main(String[] args) throws Exception { - testHelp(); - testHelpToolProvider(); - } - -} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/IconTest.java --- a/test/jdk/tools/jpackage/share/IconTest.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/share/IconTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -21,38 +21,70 @@ * questions. */ +import java.io.IOException; import java.nio.file.Files; -import jdk.jpackage.internal.ApplicationLayout; import java.nio.file.Path; +import java.nio.file.StandardCopyOption; import jdk.jpackage.test.TKit; import jdk.jpackage.test.Functional; +import jdk.jpackage.test.Annotations.*; import jdk.jpackage.test.JPackageCommand; /* * @test - * @summary jpackage create image to verify --icon + * @summary jpackage create image with custom icon * @library ../helpers * @build jdk.jpackage.test.* * @modules jdk.jpackage/jdk.jpackage.internal - * @run main/othervm -Xmx512m IconTest + * @compile IconTest.java + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=IconTest */ + public class IconTest { - public static void main(String[] args) { - TKit.run(args, () -> { - JPackageCommand cmd = JPackageCommand.helloAppImage().addArguments("--icon", GOLDEN_ICON); - cmd.useToolProvider(true).executeAndAssertHelloAppImageCreated(); + @Test + public static void testResourceDir() throws IOException { + TKit.withTempDirectory("resources", tempDir -> { + JPackageCommand cmd = JPackageCommand.helloAppImage() + .addArguments("--resource-dir", tempDir); + + Files.copy(GOLDEN_ICON, tempDir.resolve(appIconFileName(cmd)), + StandardCopyOption.REPLACE_EXISTING); + + testIt(cmd); + }); + } - Path iconPath = ApplicationLayout.platformAppImage().resolveAt( - cmd.appImage()).destktopIntegrationDirectory().resolve( - cmd.launcherPathInAppImage().getFileName().toString().replaceAll( - "\\.[^.]*$", "") + ICON_SUFFIX); + @Test + @Parameter("true") + @Parameter("false") + public static void testParameter(boolean relativePath) throws IOException { + final Path iconPath; + if (relativePath) { + iconPath = TKit.createRelativePathCopy(GOLDEN_ICON); + } else { + iconPath = GOLDEN_ICON; + } + + testIt(JPackageCommand.helloAppImage().addArguments("--icon", iconPath)); + } - TKit.assertFileExists(iconPath); - TKit.assertTrue(-1 == Files.mismatch(GOLDEN_ICON, iconPath), - String.format( - "Check application icon file [%s] is a copy of source icon file [%s]", - iconPath, GOLDEN_ICON)); - }); + private static String appIconFileName(JPackageCommand cmd) { + return cmd.appLauncherPath().getFileName().toString().replaceAll( + "\\.[^.]*$", "") + ICON_SUFFIX; + } + + private static void testIt(JPackageCommand cmd) throws IOException { + cmd.executeAndAssertHelloAppImageCreated(); + + Path iconPath = cmd.appLayout().destktopIntegrationDirectory().resolve( + appIconFileName(cmd)); + + TKit.assertFileExists(iconPath); + TKit.assertTrue(-1 == Files.mismatch(GOLDEN_ICON, iconPath), + String.format( + "Check application icon file [%s] is a copy of source icon file [%s]", + iconPath, GOLDEN_ICON)); } private final static String ICON_SUFFIX = Functional.identity(() -> { diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/InstallDirTest.java --- a/test/jdk/tools/jpackage/share/InstallDirTest.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/share/InstallDirTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -33,17 +33,18 @@ import jdk.jpackage.test.Annotations.Parameter; /** - * Test --install-dir parameter. Output of the test should be installdirtest*.* - * package bundle. The output package should provide the same functionality as - * the default package but install test application in specified directory. + * Test --install-dir parameter. Output of the test should be + * commoninstalldirtest*.* package bundle. The output package should provide the + * same functionality as the default package but install test application in + * specified directory. * * Linux: * - * Application should be installed in /opt/jpackage/installdirtest folder. + * Application should be installed in /opt/jpackage/commoninstalldirtest folder. * * Mac: * - * Application should be installed in /Applications/jpackage/installdirtest.app + * Application should be installed in /Applications/jpackage/commoninstalldirtest.app * folder. * * Windows: @@ -116,20 +117,20 @@ private static void testLinuxBad(String installDir, String errorMessageSubstring) { new PackageTest().configureHelloApp() - .setExpectedExitCode(1) - .forTypes(PackageType.LINUX) - .addInitializer(cmd -> { - cmd.addArguments("--install-dir", installDir); - cmd.saveConsoleOutput(true); - }) - .addBundleVerifier((cmd, result) -> { - String errorMessage = JPackageCommand.filterOutput(result. - getOutput().stream()).filter(line -> line.contains( - errorMessageSubstring)).findFirst().orElse(null); - TKit.assertNotNull(errorMessage, String.format( - "Check output contains [%s] substring", - errorMessageSubstring)); - }) - .run(); + .setExpectedExitCode(1) + .forTypes(PackageType.LINUX) + .addInitializer(cmd -> { + cmd.addArguments("--install-dir", installDir); + cmd.saveConsoleOutput(true); + }) + .addBundleVerifier((cmd, result) -> { + String errorMessage = JPackageCommand.filterOutput( + result.getOutput().stream()).filter(line -> line.contains( + errorMessageSubstring)).findFirst().orElse(null); + TKit.assertNotNull(errorMessage, String.format( + "Check output contains [%s] substring", + errorMessageSubstring)); + }) + .run(); } } diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/LicenseTest.java --- a/test/jdk/tools/jpackage/share/LicenseTest.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/share/LicenseTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -38,14 +38,14 @@ import jdk.jpackage.test.TKit; /** - * Test --license-file parameter. Output of the test should be licensetest*.* + * Test --license-file parameter. Output of the test should be commonlicensetest*.* * package bundle. The output package should provide the same functionality as * the default package and also incorporate license information from * test/jdk/tools/jpackage/resources/license.txt file from OpenJDK repo. * * deb: * - * Package should install license file /usr/share/doc/licensetest/copyright + * Package should install license file /opt/commonlicensetest/share/doc/copyright * file. * * rpm: @@ -88,20 +88,8 @@ public static void testCommon() { new PackageTest().configureHelloApp() .addInitializer(cmd -> { - Path licenseCopy = TKit.workDir().resolve(LICENSE_FILE.getFileName()).toAbsolutePath().normalize(); - Files.copy(LICENSE_FILE, licenseCopy, - StandardCopyOption.REPLACE_EXISTING); - final Path basePath = Path.of(".").toAbsolutePath().normalize(); - try { - licenseCopy = basePath.relativize(licenseCopy); - } catch (IllegalArgumentException ex) { - // May happen on Windows: java.lang.IllegalArgumentException: 'other' has different root - TKit.trace(String.format( - "Not using relative path to license file for --license-file parameter. Failed to relativize [%s] at [%s]", - licenseCopy, basePath)); - ex.printStackTrace(); - } - cmd.addArguments("--license-file", licenseCopy); + cmd.addArguments("--license-file", TKit.createRelativePathCopy( + LICENSE_FILE)); }) .forTypes(PackageType.LINUX) .addBundleVerifier(cmd -> { diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/MainClassAttributeTest.java --- a/test/jdk/tools/jpackage/share/MainClassAttributeTest.java Wed Oct 16 09:57:23 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2018, 2019, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.File; -import java.nio.file.Files; - -/* - * @test - * @summary jpackage create image with no main class arguments and with main-class attribute - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @modules jdk.jpackage - * @run main/othervm -Xmx512m MainClassAttributeTest - */ -public class MainClassAttributeTest { - private static final String OUTPUT = "output"; - private static final String app = JPackagePath.getApp(); - private static final String appOutput = JPackagePath.getAppOutputFile(); - - private static final String[] CMD = { - "--package-type", "app-image", - "--input", "input", - "--dest", OUTPUT, - "--name", "test", - "--main-jar", "hello.jar"}; - - private static void validateResult(String[] result) throws Exception { - if (result.length != 2) { - throw new AssertionError( - "Unexpected number of lines: " + result.length); - } - - if (!result[0].trim().equals("jpackage test application")) { - throw new AssertionError("Unexpected result[0]: " + result[0]); - } - - if (!result[1].trim().equals("args.length: 0")) { - throw new AssertionError("Unexpected result[1]: " + result[1]); - } - } - - private static void validate() throws Exception { - int retVal = JPackageHelper.execute(null, app); - if (retVal != 0) { - throw new AssertionError( - "Test application exited with error: " + retVal); - } - - File outfile = new File(appOutput); - if (!outfile.exists()) { - throw new AssertionError(appOutput + " was not created"); - } - - String output = Files.readString(outfile.toPath()); - String[] result = output.split("\n"); - validateResult(result); - } - - private static void testMainClassAttribute() throws Exception { - JPackageHelper.executeCLI(true, CMD); - validate(); - } - - private static void testMainClassAttributeToolProvider() throws Exception { - JPackageHelper.deleteOutputFolder(OUTPUT); - JPackageHelper.executeToolProvider(true, CMD); - validate(); - } - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloImageJarWithMainClass(); - testMainClassAttribute(); - testMainClassAttributeToolProvider(); - } - -} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/MainClassErrorTest.java --- a/test/jdk/tools/jpackage/share/MainClassErrorTest.java Wed Oct 16 09:57:23 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2018, 2019, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.File; -import java.nio.file.Files; - -/* - * @test - * @summary jpackage create image with no main class arguments and with main-class attribute - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @modules jdk.jpackage - * @run main/othervm -Xmx512m MainClassErrorTest - */ -public class MainClassErrorTest { - private static final String OUTPUT = "output"; - private static final String app = JPackagePath.getApp(); - private static final String appOutput = JPackagePath.getAppOutputFile(); - - private static final String[] CMD = { - "--package-type", "app-image", - "--input", "input", - "--dest", OUTPUT, - "--name", "test", - "--main-jar", "hello.jar"}; - - private static void validate(String output) throws Exception { - String[] result = JPackageHelper.splitAndFilter(output); - if (result.length != 2) { - throw new AssertionError( - "Unexpected number of lines: " + result.length); - } - - if (!result[0].trim().contains("main class was not specified")) { - throw new AssertionError("Unexpected result[0]: " + result[0]); - } - - if (!result[1].trim().startsWith("Advice to fix: ")) { - throw new AssertionError("Unexpected result[1]: " + result[1]); - } - } - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloImageJar(); - - JPackageHelper.deleteOutputFolder(OUTPUT); - validate(JPackageHelper.executeCLI(false, CMD)); - - JPackageHelper.deleteOutputFolder(OUTPUT); - validate(JPackageHelper.executeToolProvider(false, CMD)); - } - -} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/ModuleMainClassErrorTest.java --- a/test/jdk/tools/jpackage/share/ModuleMainClassErrorTest.java Wed Oct 16 09:57:23 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2018, 2019, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.File; -import java.nio.file.Files; - -/* - * @test - * @summary jpackage create image with no main class arguments and with main-class attribute - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @modules jdk.jpackage - * @run main/othervm -Xmx512m ModuleMainClassErrorTest - */ -public class ModuleMainClassErrorTest { - private static final String OUTPUT = "output"; - private static final String app = JPackagePath.getApp(); - private static final String appOutput = JPackagePath.getAppOutputFile(); - - private static final String [] CMD1 = { - "--package-type", "app-image", - "--dest", OUTPUT, - "--name", "test", - "--module", "com.hello", - "--module-path", "input"}; - - private static final String [] CMD2 = { - "--package-type", "app-image", - "--dest", OUTPUT, - "--name", "test", - "--module", "com.hello/com.hello.Hello", - "--module-path", "input"}; - - private static void validate(String buildOutput) throws Exception { - - File outfile = new File(appOutput); - int retVal = JPackageHelper.execute(outfile, app); - if (retVal != 0) { - throw new AssertionError( - "Test application exited with error: "); - } - - if (!outfile.exists()) { - throw new AssertionError(appOutput + " was not created"); - } - String output = Files.readString(outfile.toPath()); - String[] result = output.split("\n"); - - if (!result[0].trim().equals("jpackage test application")) { - throw new AssertionError("Unexpected result[0]: " + result[0]); - } - - if (!result[1].trim().equals("args.length: 0")) { - throw new AssertionError("Unexpected result[1]: " + result[1]); - } - } - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloModule(); - - JPackageHelper.deleteOutputFolder(OUTPUT); - JPackageHelper.executeCLI(false, CMD1); - - JPackageHelper.deleteOutputFolder(OUTPUT); - JPackageHelper.executeToolProvider(false, CMD1); - - JPackageHelper.deleteOutputFolder(OUTPUT); - validate(JPackageHelper.executeCLI(true, CMD2)); - - JPackageHelper.deleteOutputFolder(OUTPUT); - validate(JPackageHelper.executeToolProvider(true, CMD2)); - } - -} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/ModulePathTest.java --- a/test/jdk/tools/jpackage/share/ModulePathTest.java Wed Oct 16 09:57:23 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2018, 2019, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - /* - * @test - * @summary jpackage create image module test - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @build Base - * @modules jdk.jpackage - * @run main/othervm -Xmx512m ModulePathTest - */ - -import java.io.File; - -public class ModulePathTest { - private static final String OUTPUT = "output"; - - private static final String [] CMD1 = { - "--package-type", "app-image", - "--dest", OUTPUT, - "--name", "test", - "--module", "com.hello/com.hello.Hello", - "--module-path", "input", - }; - - private static final String [] CMD2 = { - "--package-type", "app-image", - "--dest", OUTPUT, - "--name", "test", - "--module", "com.hello/com.hello.Hello", - "--module-path", "input" + File.pathSeparator + "input-other", - }; - - private static final String [] CMD3 = { - "--package-type", "app-image", - "--dest", OUTPUT, - "--name", "test", - "--module", "com.hello/com.hello.Hello", - "--module-path", "input", - "--module-path", "input-other", - }; - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloModule(); - Base.testCreateAppImageToolProvider(CMD1); - JPackageHelper.deleteOutputFolder(OUTPUT); - Base.testCreateAppImageToolProvider(CMD2); - JPackageHelper.deleteOutputFolder(OUTPUT); - Base.testCreateAppImageToolProvider(CMD3); - } - -} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/ResourceTest.java --- a/test/jdk/tools/jpackage/share/ResourceTest.java Wed Oct 16 09:57:23 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2018, 2019, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.File; -import java.nio.file.Files; - -/* - * @test - * @summary jpackage create image to verify --icon - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @requires ((os.family == "windows") | (os.family == "mac")) - * @modules jdk.jpackage - * @run main/othervm -Xmx512m ResourceTest - */ -public class ResourceTest { - private static final String OUTPUT = "output"; - private static final String app = JPackagePath.getApp("icon"); - private static final String appOutput = JPackagePath.getAppOutputFile(); - private static final String resourceDir = - JPackagePath.getTestSrcRoot() + File.separator + "resources"; - - private static final String[] CMD = { - "--package-type", "app-image", - "--input", "input", - "--name", "icon", - "--main-jar", "hello.jar", - "--main-class", "Hello", - "--resource-dir", resourceDir, - "--dest", OUTPUT}; - - private static void validateResult(String[] result) throws Exception { - if (result.length != 2) { - throw new AssertionError( - "Unexpected number of lines: " + result.length); - } - - if (!result[0].trim().equals("jpackage test application")) { - throw new AssertionError("Unexpected result[0]: " + result[0]); - } - - if (!result[1].trim().equals("args.length: 0")) { - throw new AssertionError("Unexpected result[1]: " + result[1]); - } - } - - private static void validate() throws Exception { - int retVal = JPackageHelper.execute(null, app); - if (retVal != 0) { - throw new AssertionError( - "Test application exited with error: " + retVal); - } - - File outfile = new File(appOutput); - if (!outfile.exists()) { - throw new AssertionError(appOutput + " was not created"); - } - - String output = Files.readString(outfile.toPath()); - String[] result = output.split("\n"); - validateResult(result); - } - - private static void validateIcon() throws Exception { - File origIcon = new File(getIconPath()); - File icon = new File(JPackagePath.getAppIcon("icon")); - if (origIcon.length() != icon.length()) { - System.err.println("file: " + origIcon + " - origIcon.length(): " - + origIcon.length()); - System.err.println("file: " + icon + " - icon.length(): " - + icon.length()); - throw new AssertionError("Icons size does not match"); - } - } - - private static void testIcon() throws Exception { - JPackageHelper.executeCLI(true, CMD); - validate(); - validateIcon(); - } - - private static void testIconToolProvider() throws Exception { - JPackageHelper.deleteOutputFolder(OUTPUT); - JPackageHelper.executeToolProvider(true, CMD); - validate(); - validateIcon(); - } - - private static String getResourcenPath() { - return JPackagePath.getTestSrcRoot() + File.separator + "resources"; - } - - private static String getIconPath() { - String ext = ".ico"; - if (JPackageHelper.isOSX()) { - ext = ".icns"; - } else if (JPackageHelper.isLinux()) { - ext = ".png"; - } - return resourceDir + File.separator + "icon" + ext; - } - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloImageJar(); - testIcon(); - testIconToolProvider(); - } -} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/SimplePackageTest.java --- a/test/jdk/tools/jpackage/share/SimplePackageTest.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/share/SimplePackageTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -23,6 +23,7 @@ import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; +import jdk.jpackage.test.Annotations.Test; /** * Simple platform specific packaging test. Output of the test should be @@ -43,16 +44,17 @@ * @library ../helpers * @build jdk.jpackage.test.* * @modules jdk.jpackage/jdk.jpackage.internal - * @run main/othervm/timeout=360 -Xmx512m SimplePackageTest + * @compile SimplePackageTest.java + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=SimplePackageTest */ public class SimplePackageTest { - public static void main(String[] args) { - TKit.run(args, () -> { - new PackageTest() - .configureHelloApp() - .addBundleDesktopIntegrationVerifier(false) - .run(); - }); + @Test + public static void test() { + new PackageTest() + .configureHelloApp() + .addBundleDesktopIntegrationVerifier(false) + .run(); } } diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/VerboseTest.java --- a/test/jdk/tools/jpackage/share/VerboseTest.java Wed Oct 16 09:57:23 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2018, 2019, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @summary jpackage create image verbose test - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @modules jdk.jpackage - * @run main/othervm -Xmx512m VerboseTest - */ -public class VerboseTest { - private static final String OUTPUT = "output"; - private static final String[] CMD = { - "--package-type", "app-image", - "--input", "input", - "--dest", OUTPUT, - "--name", "test", - "--main-jar", "hello.jar", - "--main-class", "Hello", - }; - - private static final String[] CMD_VERBOSE = { - "--package-type", "app-image", - "--input", "input", - "--dest", OUTPUT, - "--name", "test", - "--main-jar", "hello.jar", - "--main-class", "Hello", - "--verbose"}; - - private static void validate(String result, String resultVerbose) - throws Exception { - String[] r = result.split("\n"); - String[] rv = resultVerbose.split("\n"); - - if (r.length >= rv.length) { - System.err.println("r.length: " + r.length); - System.err.println(result); - System.err.println("rv.length: " + rv.length); - System.err.println(resultVerbose); - throw new AssertionError( - "non-verbose output is less or equal to verbose output"); - } - } - - private static void testCreateAppImage() throws Exception { - String result = JPackageHelper.executeCLI(true, CMD); - JPackageHelper.deleteOutputFolder(OUTPUT); - String resultVerbose = JPackageHelper.executeCLI(true, CMD_VERBOSE); - validate(result, resultVerbose); - } - - private static void testCreateAppImageToolProvider() throws Exception { - JPackageHelper.deleteOutputFolder(OUTPUT); - String result = JPackageHelper.executeToolProvider(true, CMD); - JPackageHelper.deleteOutputFolder(OUTPUT); - String resultVerbose = - JPackageHelper.executeToolProvider(true, CMD_VERBOSE); - validate(result, resultVerbose); - } - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloImageJar(); - testCreateAppImage(); - testCreateAppImageToolProvider(); - } - -} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/WithSpaceTest.java --- a/test/jdk/tools/jpackage/share/WithSpaceTest.java Wed Oct 16 09:57:23 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2018, 2019, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.File; - - /* - * @test - * @summary jpackage create image test - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @build Base - * @modules jdk.jpackage - * @run main/othervm -Xmx512m WithSpaceTest - */ -public class WithSpaceTest { - private static final String OUTPUT = "output"; - - private static final String [] CMD1 = { - "--package-type", "app-image", - "--input", "input dir", - "--dest", OUTPUT, - "--name", "test", - "--main-jar", "hello.jar", - "--main-class", "Hello", - }; - - private static final String [] CMD2 = { - "--package-type", "app-image", - "--input", "input dir2", - "--dest", OUTPUT, - "--name", "test", - "--main-jar", "sub dir/hello.jar", - "--main-class", "Hello", - }; - - public static void main(String[] args) throws Exception { - - JPackageHelper.deleteOutputFolder(OUTPUT); - JPackageHelper.createHelloImageJar("input dir"); - Base.testCreateAppImage(CMD1); - - JPackageHelper.deleteOutputFolder(OUTPUT); - JPackageHelper.createHelloImageJar( - "input dir2" + File.separator + "sub dir"); - - Base.testCreateAppImageToolProvider(CMD2); - JPackageHelper.deleteOutputFolder(OUTPUT); - } -} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/jdk/jpackage/tests/AppVersionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/AppVersionTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2019, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jpackage.tests; + +import java.util.Collection; +import java.util.List; +import jdk.jpackage.test.Annotations.Parameters; +import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.JPackageCommand; +import jdk.jpackage.test.TKit; + +/* + * @test + * @summary jpackage application version testing + * @library ../../../../helpers + * @build jdk.jpackage.test.* + * @modules jdk.jpackage/jdk.jpackage.internal + * @compile AppVersionTest.java + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=jdk.jpackage.tests.AppVersionTest + */ + +public final class AppVersionTest { + + @Parameters + public static Collection input() { + return List.of(new Object[][]{ + // Default jpackage version + {"1.0", "Hello", null}, + {"1.0", "com.other/com.other.Hello", null}, + // Version should be picked from --app-version + {"3.1", "Hello", new String[]{"--app-version", "3.1"}}, + {"3.2", "com.other/com.other.Hello", new String[]{"--app-version", + "3.2"}}, + // Version should be picked from the last --app-version + {"3.3", "Hello", new String[]{"--app-version", "4", "--app-version", + "3.3"}}, + {"7.8", "com.other/com.other.Hello", new String[]{"--app-version", + "4", "--app-version", "7.8"}}, + // Pick version from jar + {"3.10.17", "com.other/com.other.Hello@3.10.17", null}, + // Ignore version in jar if --app-version given + {"7.5.81", "com.other/com.other.Hello@3.10.17", new String[]{ + "--app-version", "7.5.81"}} + }); + } + + public AppVersionTest(String expectedVersion, String javaAppDesc, + String[] jpackageArgs) { + this.expectedVersion = expectedVersion; + + cmd = JPackageCommand.helloAppImage(javaAppDesc); + if (jpackageArgs != null) { + cmd.addArguments(jpackageArgs); + } + } + + @Test + public void test() { + cmd.executeAndAssertHelloAppImageCreated(); + String actualVersion = cmd.readLaunherCfgFile().getValue("Application", + "app.version"); + TKit.assertEquals(expectedVersion, actualVersion, + "Check application version"); + } + + private final String expectedVersion; + private final JPackageCommand cmd; +} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/jdk/jpackage/tests/BasicTest.java --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/BasicTest.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/BasicTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -28,13 +28,12 @@ import java.nio.file.Path; import java.util.List; import java.util.ArrayList; +import java.util.function.Function; +import java.util.function.Predicate; import java.util.regex.Pattern; import java.util.stream.Collectors; -import jdk.jpackage.test.Executor; -import jdk.jpackage.test.JPackageCommand; -import jdk.jpackage.test.TKit; -import jdk.jpackage.test.JavaTool; -import jdk.jpackage.test.HelloApp; +import java.util.stream.Stream; +import jdk.jpackage.test.*; import jdk.jpackage.test.Annotations.*; /* @@ -42,13 +41,13 @@ * @summary jpackage basic testing * @library ../../../../helpers * @build jdk.jpackage.test.* - * @modules jdk.jpackage + * @modules jdk.jpackage/jdk.jpackage.internal * @compile BasicTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=jdk.jpackage.tests.BasicTest */ -public class BasicTest { +public final class BasicTest { @Test public void testNoArgs() { List output = JPackageCommand.filterOutput( @@ -69,11 +68,101 @@ } @Test + public void testHelp() { + List hOutput = getJPackageToolProvider() + .addArgument("-h").executeAndGetOutput(); + List helpOutput = getJPackageToolProvider() + .addArgument("--help").executeAndGetOutput(); + + TKit.assertStringListEquals(hOutput, helpOutput, + "Check -h and --help parameters produce the same output"); + + final String windowsPrefix = "--win-"; + final String linuxPrefix = "--linux-"; + final String osxPrefix = "--mac-"; + + final String expectedPrefix; + final List unexpectedPrefixes; + + if (TKit.isWindows()) { + expectedPrefix = windowsPrefix; + unexpectedPrefixes = List.of(osxPrefix, linuxPrefix); + } else if (TKit.isLinux()) { + expectedPrefix = linuxPrefix; + unexpectedPrefixes = List.of(windowsPrefix, osxPrefix); + } else if (TKit.isOSX()) { + expectedPrefix = osxPrefix; + unexpectedPrefixes = List.of(linuxPrefix, windowsPrefix); + } else { + throw TKit.throwUnknownPlatformError(); + } + + Function> createPattern = (prefix) -> { + return Pattern.compile("^ " + prefix).asPredicate(); + }; + + Function, Long> countStrings = (prefixes) -> { + return hOutput.stream().filter( + prefixes.stream().map(createPattern).reduce(x -> false, + Predicate::or)).peek(TKit::trace).count(); + }; + + TKit.trace("Check parameters in help text"); + TKit.assertNotEquals(0, countStrings.apply(List.of(expectedPrefix)), + "Check help text contains plaform specific parameters"); + TKit.assertEquals(0, countStrings.apply(unexpectedPrefixes), + "Check help text doesn't contain unexpected parameters"); + } + + @Test + public void testVerbose() { + JPackageCommand cmd = JPackageCommand.helloAppImage() + .setFakeRuntime().executePrerequisiteActions(); + + List expectedVerboseOutputStrings = new ArrayList<>(); + expectedVerboseOutputStrings.add("Creating app package:"); + if (TKit.isWindows()) { + expectedVerboseOutputStrings.add("Result application bundle:"); + expectedVerboseOutputStrings.add( + "Succeeded in building Windows Application Image package"); + } else if (TKit.isLinux()) { + expectedVerboseOutputStrings.add( + "Succeeded in building Linux Application Image package"); + } else if (TKit.isOSX()) { + expectedVerboseOutputStrings.add("Preparing Info.plist:"); + expectedVerboseOutputStrings.add( + "Succeeded in building Mac Application Image package"); + } else { + TKit.throwUnknownPlatformError(); + } + + TKit.deleteDirectoryContentsRecursive(cmd.outputDir()); + List nonVerboseOutput = cmd.createExecutor().executeAndGetOutput(); + + TKit.deleteDirectoryContentsRecursive(cmd.outputDir()); + List verboseOutput = cmd.createExecutor().addArgument( + "--verbose").executeAndGetOutput(); + + TKit.assertTrue(nonVerboseOutput.size() < verboseOutput.size(), + "Check verbose output is longer than regular"); + + expectedVerboseOutputStrings.forEach(str -> { + TKit.assertTextStream(str).label("regular output") + .predicate(String::contains).negate() + .apply(nonVerboseOutput.stream()); + }); + + expectedVerboseOutputStrings.forEach(str -> { + TKit.assertTextStream(str).label("verbose output") + .apply(verboseOutput.stream()); + }); + } + + @Test public void testNoName() { final String mainClassName = "Greetings"; - JPackageCommand cmd = new JPackageCommand() - .helloAppImage(mainClassName) + JPackageCommand cmd = JPackageCommand.helloAppImage(mainClassName) .removeArgumentWithValue("--name"); Path expectedImageDir = cmd.outputDir().resolve(mainClassName); @@ -84,51 +173,60 @@ cmd.executeAndAssertHelloAppImageCreated(); TKit.assertEquals(expectedImageDir.toAbsolutePath().normalize().toString(), - cmd.appImage().toAbsolutePath().normalize().toString(), + cmd.outputBundle().toAbsolutePath().normalize().toString(), String.format( "Check [%s] directory is filled with application image data", expectedImageDir)); } @Test - public void testApp() { - new JPackageCommand() - .helloAppImage() + // Regular app + @Parameter("Hello") + // Modular app + @Parameter("com.other/com.other.Hello") + public void testApp(String javaAppDesc) { + JPackageCommand.helloAppImage(javaAppDesc) .executeAndAssertHelloAppImageCreated(); } @Test - public void testModularApp() { - new JPackageCommand() - .helloAppImage("com.other/com.other.Hello") + public void testWhitespaceInPaths() { + JPackageCommand.helloAppImage("a/b c.jar:Hello") + .setArgumentValue("--input", TKit.workDir().resolve("The quick brown fox")) + .setArgumentValue("--dest", TKit.workDir().resolve("jumps over the lazy dog")) .executeAndAssertHelloAppImageCreated(); } @Test @Parameter("ALL-MODULE-PATH") @Parameter("ALL-DEFAULT") - @Parameter("jdk.desktop,jdk.jartool") - public void testAddModules(String addModulesArg) { - JPackageCommand cmd = new JPackageCommand() - .helloAppImage("com.other/com.other.Hello"); - if (!addModulesArg.isEmpty()) { - cmd.addArguments("--add-modules", addModulesArg); - } + @Parameter("java.desktop") + @Parameter("java.desktop,jdk.jartool") + @Parameter({ "java.desktop", "jdk.jartool" }) + public void testAddModules(String... addModulesArg) { + JPackageCommand cmd = JPackageCommand + .helloAppImage("goodbye.jar:com.other/com.other.Hello"); + Stream.of(addModulesArg).map(v -> Stream.of("--add-modules", v)).flatMap( + s -> s).forEachOrdered(cmd::addArgument); cmd.executeAndAssertHelloAppImageCreated(); } /** * Test --temp option. Doesn't make much sense for app image as temporary - * directory is used only on Windows. + * directory is used only on Windows. Test it in packaging mode. * @throws IOException */ -// @Test + @Test public void testTemp() throws IOException { - JPackageCommand cmd = new JPackageCommand().helloAppImage(); + JPackageCommand cmd = JPackageCommand.helloAppImage() + .removeArgumentWithValue("--package-type") + .addArguments("--verbose") + .setFakeRuntime(); + TKit.withTempDirectory("temp-root", tempDir -> { cmd.addArguments("--temp", tempDir); - cmd.executeAndAssertHelloAppImageCreated(); + cmd.execute().assertExitCodeIsZero(); // Check jpackage actually used the supplied directory. TKit.assertNotEquals(0, tempDir.toFile().list().length, @@ -144,7 +242,7 @@ @Test public void testAtFile() throws IOException { - JPackageCommand cmd = new JPackageCommand().helloAppImage(); + JPackageCommand cmd = JPackageCommand.helloAppImage(); // Init options file with the list of options configured // for JPackageCommand instance. @@ -211,8 +309,7 @@ cmd.addArguments("--runtime-image", runtimeDir); cmd.executeAndAssertHelloAppImageCreated(); - final Path appImageRuntimePath = cmd.appImage().resolve( - cmd.appRuntimeDirectoryInAppImage()); + final Path appImageRuntimePath = cmd.appRuntimeDirectory(); // // This is an overkill to list modules in jlink output as we have @@ -251,8 +348,6 @@ } private static Executor getToolProvider(JavaTool tool) { - return new Executor() - .dumpOutput().saveOutput() - .setToolProvider(tool.asToolProvider()); + return new Executor().dumpOutput().saveOutput().setToolProvider(tool); } } diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/jdk/jpackage/tests/MainClassTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/MainClassTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2019, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jpackage.tests; + +import java.io.IOException; +import java.nio.file.Files; +import java.util.Collection; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.jar.JarFile; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.nio.file.Path; +import java.util.function.Predicate; +import java.util.jar.JarEntry; +import jdk.jpackage.test.Annotations.Parameters; +import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.*; +import jdk.jpackage.test.Functional.ThrowingConsumer; +import static jdk.jpackage.tests.MainClassTest.Script.MainClassType.*; + + +/* + * @test + * @summary test different settings of main class name for jpackage + * @library ../../../../helpers + * @build jdk.jpackage.test.* + * @modules jdk.jpackage/jdk.jpackage.internal + * @compile MainClassTest.java + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=jdk.jpackage.tests.MainClassTest + * --jpt-space-subst=_ + * --jpt-exclude=modular=y;_main-class=n;_jar-main-class=b;_jlink=y + * --jpt-exclude=modular=y;_main-class=n;_jar-main-class=n;_jlink=n + */ + +public final class MainClassTest { + + static final class Script { + Script() { + appDesc = JavaAppDesc.parse("test.Hello"); + } + + Script modular(boolean v) { + appDesc.setModuleName(v ? null : "com.other"); + return this; + } + + Script withJLink(boolean v) { + withJLink = v; + return this; + } + + Script withMainClass(MainClassType v) { + mainClass = v; + return this; + } + + Script withJarMainClass(MainClassType v) { + appDesc.setJarWithMainClass(v != NotSet); + jarMainClass = v; + return this; + } + + Script expectedErrorMessage(String v) { + expectedErrorMessage = v; + return this; + } + + @Override + public String toString() { + return Stream.of( + format("modular", appDesc.moduleName() != null ? 'y' : 'n'), + format("main-class", mainClass), + format("jar-main-class", jarMainClass), + format("jlink", withJLink ? 'y' : 'n'), + format("error", expectedErrorMessage) + ).filter(Objects::nonNull).collect(Collectors.joining("; ")); + } + + private static String format(String key, Object value) { + if (value == null) { + return null; + } + return String.join("=", key, value.toString()); + } + + enum MainClassType { + NotSet("n"), + SetWrong("b"), + SetRight("y"); + + MainClassType(String label) { + this.label = label; + } + + @Override + public String toString() { + return label; + } + + private final String label; + }; + + private JavaAppDesc appDesc; + private boolean withJLink; + private MainClassType mainClass; + private MainClassType jarMainClass; + private String expectedErrorMessage; + } + + public MainClassTest(Script script) { + this.script = script; + + nonExistingMainClass = Stream.of( + script.appDesc.packageName(), "ThereIsNoSuchClass").filter( + Objects::nonNull).collect(Collectors.joining(".")); + + cmd = JPackageCommand.helloAppImage(script.appDesc); + if (!script.withJLink) { + cmd.setFakeRuntime(); + } + + final String moduleName = script.appDesc.moduleName(); + switch (script.mainClass) { + case NotSet: + if (moduleName != null) { + // Don't specify class name, only module name. + cmd.setArgumentValue("--module", moduleName); + } else { + cmd.removeArgumentWithValue("--main-class"); + } + break; + + case SetWrong: + if (moduleName != null) { + cmd.setArgumentValue("--module", + String.join("/", moduleName, nonExistingMainClass)); + } else { + cmd.setArgumentValue("--main-class", nonExistingMainClass); + } + } + } + + @Parameters + public static Collection scripts() { + final var withMainClass = Set.of(SetWrong, SetRight); + + List scripts = new ArrayList<>(); + for (var withJLink : List.of(true, false)) { + for (var modular : List.of(true, false)) { + for (var mainClass : Script.MainClassType.values()) { + for (var jarMainClass : Script.MainClassType.values()) { + if (!withJLink && (jarMainClass == SetWrong || mainClass + == SetWrong)) { + // Without runtime can't run app to verify it will fail, so + // there is no point in such testing. + continue; + } + + Script script = new Script() + .modular(modular) + .withJLink(withJLink) + .withMainClass(mainClass) + .withJarMainClass(jarMainClass); + + if (withMainClass.contains(jarMainClass) + || withMainClass.contains(mainClass)) { + } else if (modular) { + script.expectedErrorMessage( + "A main class was not specified nor was one found in the jar"); + } else { + script.expectedErrorMessage( + "Error: Main application class is missing"); + } + + scripts.add(new Script[]{script}); + } + } + } + } + return scripts; + } + + @Test + public void test() throws IOException { + if (script.jarMainClass == SetWrong) { + initJarWithWrongMainClass(); + } + + if (script.expectedErrorMessage != null) { + // This is the case when main class is not found nor in jar + // file nor on command line. + List output = cmd + .saveConsoleOutput(true) + .execute() + .assertExitCodeIs(1) + .getOutput(); + TKit.assertTextStream(script.expectedErrorMessage).apply(output.stream()); + return; + } + + // Get here only if main class is specified. + boolean appShouldSucceed = false; + + // Should succeed if valid main class is set on the command line. + appShouldSucceed |= (script.mainClass == SetRight); + + // Should succeed if main class is not set on the command line but set + // to valid value in the jar. + appShouldSucceed |= (script.mainClass == NotSet && script.jarMainClass == SetRight); + + if (appShouldSucceed) { + cmd.executeAndAssertHelloAppImageCreated(); + } else { + cmd.executeAndAssertImageCreated(); + if (!cmd.isFakeRuntime(String.format("Not running [%s]", + cmd.appLauncherPath()))) { + List output = new Executor() + .setDirectory(cmd.outputDir()) + .setExecutable(cmd.appLauncherPath()) + .dumpOutput().saveOutput() + .execute().assertExitCodeIs(1).getOutput(); + TKit.assertTextStream(String.format( + "Error: Could not find or load main class %s", + nonExistingMainClass)).apply(output.stream()); + } + } + } + + private void initJarWithWrongMainClass() { + // Call JPackageCommand.executePrerequisiteActions() to build app's jar. + // executePrerequisiteActions() is called by JPackageCommand instance + // only once. + cmd.executePrerequisiteActions(); + + Path jarFile; + if (script.appDesc.moduleName() != null) { + jarFile = Path.of(cmd.getArgumentValue("--module-path"), + script.appDesc.jarFileName()); + } else { + jarFile = cmd.inputDir().resolve(cmd.getArgumentValue("--main-jar")); + } + + // Create jar file with the main class attribute in manifest set to + // non-existing class. + TKit.withTempDirectory("repack-jar", workDir -> { + Path manifestFile = workDir.resolve("META-INF/MANIFEST.MF"); + try (var jar = new JarFile(jarFile.toFile())) { + jar.stream() + .filter(Predicate.not(JarEntry::isDirectory)) + .sequential().forEachOrdered(ThrowingConsumer.toConsumer( + jarEntry -> { + try (var in = jar.getInputStream(jarEntry)) { + Path fileName = workDir.resolve(jarEntry.getName()); + Files.createDirectories(fileName.getParent()); + Files.copy(in, fileName); + } + })); + } + + Files.delete(jarFile); + + // Adjust manifest. + TKit.createTextFile(manifestFile, Files.readAllLines( + manifestFile).stream().map(line -> line.replace( + script.appDesc.className(), nonExistingMainClass))); + + new Executor().setToolProvider(JavaTool.JAR) + .addArguments("-c", "-M", "-f", jarFile.toString()) + .addArguments("-C", workDir.toString(), ".") + .execute().assertExitCodeIsZero(); + }); + } + + private final JPackageCommand cmd; + private final Script script; + private final String nonExistingMainClass; +} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2019, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jpackage.tests; + +import java.io.File; +import java.nio.file.Path; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import jdk.jpackage.test.Annotations.Parameters; +import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.JPackageCommand; +import jdk.jpackage.test.TKit; + + +/* + * @test + * @summary jpackage with --module-path testing + * @library ../../../../helpers + * @build jdk.jpackage.test.* + * @modules jdk.jpackage/jdk.jpackage.internal + * @compile ModulePathTest.java + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=jdk.jpackage.tests.ModulePathTest + */ + +public final class ModulePathTest { + + @Parameters + public static Collection data() { + return List.of(new String[][]{ + {GOOD_PATH, EMPTY_DIR, NON_EXISTING_DIR}, + {EMPTY_DIR, NON_EXISTING_DIR, GOOD_PATH}, + {GOOD_PATH + "/a/b/c/d", GOOD_PATH}, + {String.join(File.pathSeparator, EMPTY_DIR, NON_EXISTING_DIR, + GOOD_PATH)}, + {String.join(File.pathSeparator, EMPTY_DIR, NON_EXISTING_DIR), + String.join(File.pathSeparator, EMPTY_DIR, NON_EXISTING_DIR, + GOOD_PATH)}, + {}, + {EMPTY_DIR} + }); + } + + public ModulePathTest(String... modulePathArgs) { + this.modulePathArgs = List.of(modulePathArgs); + } + + @Test + public void test() { + final String moduleName = "com.foo"; + JPackageCommand cmd = JPackageCommand.helloAppImage( + "benvenuto.jar:" + moduleName + "/com.foo.Hello"); + // Build app jar file. + cmd.executePrerequisiteActions(); + + // Ignore runtime that can be set for all tests. Usually if default + // runtime is set, it is fake one to save time on running jlink and + // copying megabytes of data from Java home to application image. + // We need proper runtime for this test. + cmd.ignoreDefaultRuntime(true); + + // --module-path should be set in JPackageCommand.helloAppImage call + String goodModulePath = Objects.requireNonNull(cmd.getArgumentValue( + "--module-path")); + cmd.removeArgumentWithValue("--module-path"); + TKit.withTempDirectory("empty-dir", emptyDir -> { + Path nonExistingDir = TKit.withTempDirectory("non-existing-dir", + unused -> { + }); + + Function substitute = str -> { + String v = str; + v = v.replace(GOOD_PATH, goodModulePath); + v = v.replace(EMPTY_DIR, emptyDir.toString()); + v = v.replace(NON_EXISTING_DIR, nonExistingDir.toString()); + return v; + }; + + boolean withGoodPath = modulePathArgs.stream().anyMatch( + s -> s.contains(GOOD_PATH)); + + cmd.addArguments(modulePathArgs.stream().map(arg -> Stream.of( + "--module-path", substitute.apply(arg))).flatMap(s -> s).collect( + Collectors.toList())); + + if (withGoodPath) { + cmd.executeAndAssertHelloAppImageCreated(); + } else { + final String expectedErrorMessage; + if (modulePathArgs.isEmpty()) { + expectedErrorMessage = "Error: Missing argument: --runtime-image or --module-path"; + } else { + expectedErrorMessage = String.format( + "Error: Module %s not found", moduleName); + } + + List output = cmd + .saveConsoleOutput(true) + .execute() + .assertExitCodeIs(1) + .getOutput(); + TKit.assertTextStream(expectedErrorMessage).apply(output.stream()); + } + }); + } + + private final List modulePathArgs; + + private final static String GOOD_PATH = "@GoodPath@"; + private final static String EMPTY_DIR = "@EmptyDir@"; + private final static String NON_EXISTING_DIR = "@NonExistingDir@"; +} diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/windows/WinConsoleTest.java --- a/test/jdk/tools/jpackage/windows/WinConsoleTest.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/windows/WinConsoleTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -36,7 +36,7 @@ * @library ../helpers * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @modules jdk.jpackage + * @modules jdk.jpackage/jdk.jpackage.internal * @compile WinConsoleTest.java * * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main @@ -57,8 +57,7 @@ cmd.removeArgument("--win-console"); } cmd.executeAndAssertHelloAppImageCreated(); - checkSubsystem(cmd.appImage().resolve(cmd.launcherPathInAppImage()), - withWinConsole); + checkSubsystem(cmd.appLauncherPath(), withWinConsole); } private static void checkSubsystem(Path path, boolean isConsole) throws diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/windows/WinMenuGroupTest.java --- a/test/jdk/tools/jpackage/windows/WinMenuGroupTest.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/windows/WinMenuGroupTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -24,6 +24,7 @@ import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; +import jdk.jpackage.test.Annotations.Test; /** * Test --win-menu and --win-menu-group parameters. @@ -42,18 +43,19 @@ * @build jdk.jpackage.test.* * @requires (os.family == "windows") * @modules jdk.jpackage/jdk.jpackage.internal - * @run main/othervm/timeout=360 -Xmx512m WinMenuGroupTest + * @compile WinMenuGroupTest.java + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=WinMenuGroupTest */ public class WinMenuGroupTest { - public static void main(String[] args) { - TKit.run(args, () -> { - new PackageTest() - .forTypes(PackageType.WINDOWS) - .configureHelloApp() - .addInitializer(cmd -> cmd.addArguments( - "--win-menu", "--win-menu-group", "WinMenuGroupTest_MenuGroup")) - .run(); - }); + @Test + public static void test() { + new PackageTest() + .forTypes(PackageType.WINDOWS) + .configureHelloApp() + .addInitializer(cmd -> cmd.addArguments( + "--win-menu", "--win-menu-group", "WinMenuGroupTest_MenuGroup")) + .run(); } } diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/windows/WinMenuTest.java --- a/test/jdk/tools/jpackage/windows/WinMenuTest.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/windows/WinMenuTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -24,6 +24,7 @@ import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; +import jdk.jpackage.test.Annotations.Test; /** * Test --win-menu parameter. Output of the test should be WinMenuTest-1.0.exe @@ -39,16 +40,17 @@ * @build jdk.jpackage.test.* * @requires (os.family == "windows") * @modules jdk.jpackage/jdk.jpackage.internal - * @run main/othervm/timeout=360 -Xmx512m WinMenuTest + * @compile WinMenuTest.java + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=WinMenuTest */ public class WinMenuTest { - public static void main(String[] args) { - TKit.run(args, () -> { - new PackageTest() - .forTypes(PackageType.WINDOWS) - .configureHelloApp() - .addInitializer(cmd -> cmd.addArgument("--win-menu")).run(); - }); + @Test + public static void test() { + new PackageTest() + .forTypes(PackageType.WINDOWS) + .configureHelloApp() + .addInitializer(cmd -> cmd.addArgument("--win-menu")).run(); } } diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/windows/WinPerUserInstallTest.java --- a/test/jdk/tools/jpackage/windows/WinPerUserInstallTest.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/windows/WinPerUserInstallTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -24,6 +24,7 @@ import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; +import jdk.jpackage.test.Annotations.Test; /** * Test --win-per-user-install, --win-menu, --win-menu-group parameters. @@ -41,20 +42,21 @@ * @build jdk.jpackage.test.* * @requires (os.family == "windows") * @modules jdk.jpackage/jdk.jpackage.internal - * @run main/othervm/timeout=360 -Xmx512m WinPerUserInstallTest + * @compile WinPerUserInstallTest.java + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=WinPerUserInstallTest */ public class WinPerUserInstallTest { - public static void main(String[] args) { - TKit.run(args, () -> { - new PackageTest() - .forTypes(PackageType.WINDOWS) - .configureHelloApp() - .addInitializer(cmd -> cmd.addArguments( - "--win-menu", - "--win-menu-group", "WinPerUserInstallTest_MenuGroup", - "--win-per-user-install")) - .run(); - }); + @Test + public static void test() { + new PackageTest() + .forTypes(PackageType.WINDOWS) + .configureHelloApp() + .addInitializer(cmd -> cmd.addArguments( + "--win-menu", + "--win-menu-group", "WinPerUserInstallTest_MenuGroup", + "--win-per-user-install")) + .run(); } } diff -r 2c43b89b1679 -r 3bf53ffa9ae7 test/jdk/tools/jpackage/windows/WinShortcutTest.java --- a/test/jdk/tools/jpackage/windows/WinShortcutTest.java Wed Oct 16 09:57:23 2019 -0400 +++ b/test/jdk/tools/jpackage/windows/WinShortcutTest.java Wed Oct 16 10:32:08 2019 -0400 @@ -24,6 +24,7 @@ import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; +import jdk.jpackage.test.Annotations.Test; /** * Test --win-shortcut parameter. Output of the test should be @@ -40,17 +41,18 @@ * @build jdk.jpackage.test.* * @requires (os.family == "windows") * @modules jdk.jpackage/jdk.jpackage.internal - * @run main/othervm/timeout=360 -Xmx512m WinShortcutTest + * @compile WinShortcutTest.java + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=WinShortcutTest */ public class WinShortcutTest { - public static void main(String[] args) { - TKit.run(args, () -> { - new PackageTest() - .forTypes(PackageType.WINDOWS) - .configureHelloApp() - .addInitializer(cmd -> cmd.addArgument("--win-shortcut")) - .run(); - }); + @Test + public static void test() { + new PackageTest() + .forTypes(PackageType.WINDOWS) + .configureHelloApp() + .addInitializer(cmd -> cmd.addArgument("--win-shortcut")) + .run(); } }