# HG changeset patch # User herrick # Date 1569885079 14400 # Node ID f09bf58c1f17e0846becdf005101af00149a5212 # Parent 73f8e557549ab71f09b67ddd77ea2991a5fc6f78 8231605: Improve test helpers Submitted-by: asemenyuk Reviewed-by: herrick diff -r 73f8e557549a -r f09bf58c1f17 src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java --- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java Mon Sep 30 15:59:50 2019 -0400 +++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java Mon Sep 30 19:11:19 2019 -0400 @@ -67,7 +67,7 @@ private static ApplicationLayout createAppLayout(Map params, Path imageOutDir) { - return ApplicationLayout.linuxApp().resolveAt( + return ApplicationLayout.linuxAppImage().resolveAt( imageOutDir.resolve(APP_NAME.fetchFrom(params))); } @@ -105,13 +105,13 @@ @Override protected String getCfgAppDir() { return Path.of("$APPDIR").resolve( - ApplicationLayout.linuxApp().appDirectory()).toString() + File.separator; + ApplicationLayout.linuxAppImage().appDirectory()).toString() + File.separator; } @Override protected String getCfgRuntimeDir() { return Path.of("$APPDIR").resolve( - ApplicationLayout.linuxApp().runtimeDirectory()).toString(); + ApplicationLayout.linuxAppImage().runtimeDirectory()).toString(); } @Override diff -r 73f8e557549a -r f09bf58c1f17 src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxPackageBundler.java --- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxPackageBundler.java Mon Sep 30 15:59:50 2019 -0400 +++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxPackageBundler.java Mon Sep 30 19:11:19 2019 -0400 @@ -254,7 +254,7 @@ if (StandardBundlerParam.isRuntimeInstaller(params)) { return ApplicationLayout.javaRuntime(); } - return ApplicationLayout.linuxApp(); + return ApplicationLayout.linuxAppImage(); } private static void validateFileAssociations( diff -r 73f8e557549a -r f09bf58c1f17 src/jdk.jpackage/share/classes/jdk/jpackage/internal/ApplicationLayout.java --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ApplicationLayout.java Mon Sep 30 15:59:50 2019 -0400 +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ApplicationLayout.java Mon Sep 30 19:11:19 2019 -0400 @@ -31,7 +31,7 @@ /** * Application directory layout. */ -final class ApplicationLayout implements PathGroup.Facade { +public final class ApplicationLayout implements PathGroup.Facade { enum PathRole { RUNTIME, APP, LAUNCHERS, DESKTOP, APP_MODS, DLLS } @@ -57,46 +57,46 @@ /** * Path to launchers directory. */ - Path launchersDirectory() { + public Path launchersDirectory() { return pathGroup().getPath(PathRole.LAUNCHERS); } /** * Path to directory with dynamic libraries. */ - Path dllDirectory() { + public Path dllDirectory() { return pathGroup().getPath(PathRole.DLLS); } /** * Path to application data directory. */ - Path appDirectory() { + public Path appDirectory() { return pathGroup().getPath(PathRole.APP); } /** * Path to Java runtime directory. */ - Path runtimeDirectory() { + public Path runtimeDirectory() { return pathGroup().getPath(PathRole.RUNTIME); } /** * Path to application mods directory. */ - Path appModsDirectory() { + public Path appModsDirectory() { return pathGroup().getPath(PathRole.APP_MODS); } /** * Path to directory with application's desktop integration files. */ - Path destktopIntegrationDirectory() { + public Path destktopIntegrationDirectory() { return pathGroup().getPath(PathRole.DESKTOP); } - static ApplicationLayout linuxApp() { + static ApplicationLayout linuxAppImage() { return new ApplicationLayout(Map.of( PathRole.LAUNCHERS, Path.of("bin"), PathRole.APP, Path.of("lib/app"), @@ -107,21 +107,44 @@ )); } - static ApplicationLayout windowsApp() { + static ApplicationLayout windowsAppImage() { return new ApplicationLayout(Map.of( PathRole.LAUNCHERS, Path.of(""), PathRole.APP, Path.of("app"), PathRole.RUNTIME, Path.of("runtime"), - PathRole.DESKTOP, Path.of("") + PathRole.DESKTOP, Path.of(""), + PathRole.DLLS, Path.of(""), + PathRole.APP_MODS, Path.of("app/mods") + )); + } + + static ApplicationLayout macAppImage() { + return new ApplicationLayout(Map.of( + PathRole.LAUNCHERS, Path.of("Contents/MacOS"), + PathRole.APP, Path.of("Contents/Java"), + PathRole.RUNTIME, Path.of("Contents/runtime"), + PathRole.DESKTOP, Path.of("Contents/Resources"), + PathRole.DLLS, Path.of("Contents/MacOS"), + PathRole.APP_MODS, Path.of("Contents/Java/mods") )); } - static ApplicationLayout platformApp() { - if (Platform.getPlatform() == Platform.WINDOWS) { - return windowsApp(); + + + public static ApplicationLayout platformAppImage() { + if (Platform.isWindows()) { + return windowsAppImage(); } - return linuxApp(); + if (Platform.isLinux()) { + return linuxAppImage(); + } + + if (Platform.isMac()) { + return macAppImage(); + } + + throw new IllegalArgumentException("Unknown platform"); } static ApplicationLayout javaRuntime() { diff -r 73f8e557549a -r f09bf58c1f17 src/jdk.jpackage/share/classes/jdk/jpackage/internal/Platform.java --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Platform.java Mon Sep 30 15:59:50 2019 -0400 +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Platform.java Mon Sep 30 19:11:19 2019 -0400 @@ -102,4 +102,16 @@ static int getMinorVersion() { return minorVersion; } + + static boolean isWindows() { + return getPlatform() == WINDOWS; + } + + static boolean isMac() { + return getPlatform() == MAC; + } + + static boolean isLinux() { + return getPlatform() == LINUX; + } } diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Annotations.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Annotations.java Mon Sep 30 19:11:19 2019 -0400 @@ -0,0 +1,52 @@ +/* + * 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.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +public class Annotations { + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public @interface Test { + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + @Repeatable(Parameters.class) + public @interface Parameter { + + String value(); + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public @interface Parameters { + + Parameter[] value(); + } +} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CommandArguments.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CommandArguments.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CommandArguments.java Mon Sep 30 19:11:19 2019 -0400 @@ -28,12 +28,11 @@ import java.util.List; import java.util.stream.Collectors; -class CommandArguments { +public class CommandArguments { CommandArguments() { args = new ArrayList<>(); } - List args; final public T addArgument(String v) { args.add(v); @@ -58,6 +57,10 @@ Collectors.toList())); } + final public List getAllArguments() { + return List.copyOf(args); + } + protected void verifyMutable() { if (!isMutable()) { throw new UnsupportedOperationException( @@ -68,4 +71,6 @@ protected boolean isMutable() { return true; } + + protected List args; } diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java Mon Sep 30 19:11:19 2019 -0400 @@ -22,28 +22,37 @@ */ package jdk.jpackage.test; +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.nio.file.Files; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.StringReader; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; -import java.util.regex.Matcher; +import java.util.Set; import java.util.regex.Pattern; import java.util.spi.ToolProvider; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.jpackage.test.Functional.ThrowingSupplier; public final class Executor extends CommandArguments { public Executor() { - saveOutputType = SaveOutputType.NONE; + saveOutputType = new HashSet<>(Set.of(SaveOutputType.NONE)); } public Executor setExecutable(String v) { + return setExecutable(Path.of(v)); + } + + public Executor setExecutable(Path v) { executable = v; if (executable != null) { toolProvider = null; @@ -53,6 +62,7 @@ public Executor setToolProvider(ToolProvider v) { toolProvider = v; + filterOutJcovOutput = true; if (toolProvider != null) { executable = null; } @@ -65,21 +75,72 @@ } public Executor setExecutable(JavaTool v) { - return setExecutable(v.getPath().getAbsolutePath()); + filterOutJcovOutput = true; + return setExecutable(v.getPath()); } + /** + * Configures this instance to save full output that command will produce. + * This function is mutual exclusive with + * saveFirstLineOfOutput() function. + * + * @return this + */ public Executor saveOutput() { - saveOutputType = SaveOutputType.FULL; + saveOutputType.remove(SaveOutputType.FIRST_LINE); + saveOutputType.add(SaveOutputType.FULL); return this; } - public Executor saveFirstLineOfOutput() { - saveOutputType = SaveOutputType.FIRST_LINE; + /** + * Configures how to save output that command will produce. If + * v is true, the function call is equivalent to + * saveOutput() call. If v is false, + * the function will result in not preserving command output. + * + * @return this + */ + public Executor saveOutput(boolean v) { + if (v) { + saveOutput(); + } else { + saveOutputType.remove(SaveOutputType.FIRST_LINE); + saveOutputType.remove(SaveOutputType.FULL); + } return this; } - public Executor dumpOtput() { - saveOutputType = SaveOutputType.DUMP; + /** + * Configures this instance to save only the first line out output that + * command will produce. This function is mutual exclusive with + * saveOutput() function. + * + * @return this + */ + public Executor saveFirstLineOfOutput() { + saveOutputType.add(SaveOutputType.FIRST_LINE); + saveOutputType.remove(SaveOutputType.FULL); + return this; + } + + /** + * Configures this instance to dump all output that command will produce to + * System.out and System.err. Can be used together with saveOutput() and + * saveFirstLineOfOutput() to save command output and also copy it in the + * default output streams. + * + * @return this + */ + public Executor dumpOutput() { + return dumpOutput(true); + } + + public Executor dumpOutput(boolean v) { + if (v) { + saveOutputType.add(SaveOutputType.DUMP); + } else { + saveOutputType.remove(SaveOutputType.DUMP); + } return this; } @@ -102,7 +163,7 @@ } public Result assertExitCodeIs(int expectedExitCode) { - Test.assertEquals(expectedExitCode, exitCode, String.format( + TKit.assertEquals(expectedExitCode, exitCode, String.format( "Check command %s exited with %d code", getPrintableCommandLine(), expectedExitCode)); return this; @@ -117,21 +178,17 @@ } public Result execute() { - if (toolProvider != null) { - return runToolProvider(); - } + return ThrowingSupplier.toSupplier(() -> { + if (toolProvider != null) { + return runToolProvider(); + } - try { if (executable != null) { return runExecutable(); } - } catch (RuntimeException e) { - throw e; - } catch (IOException | InterruptedException e) { - throw new RuntimeException(e); - } - throw new IllegalStateException("No command to execute"); + throw new IllegalStateException("No command to execute"); + }).get(); } public String executeAndGetFirstLineOfOutput() { @@ -142,69 +199,119 @@ return saveOutput().execute().assertExitCodeIsZero().getOutput(); } + private boolean withSavedOutput() { + return saveOutputType.contains(SaveOutputType.FULL) || saveOutputType.contains( + SaveOutputType.FIRST_LINE); + } + private Result runExecutable() throws IOException, InterruptedException { List command = new ArrayList<>(); - command.add(executable); + command.add(executable.toString()); command.addAll(args); - Path outputFile = null; ProcessBuilder builder = new ProcessBuilder(command); StringBuilder sb = new StringBuilder(getPrintableCommandLine()); - if (saveOutputType != SaveOutputType.NONE) { + if (withSavedOutput()) { builder.redirectErrorStream(true); - - if (saveOutputType == SaveOutputType.DUMP) { - builder.inheritIO(); - sb.append("; redirect output to stdout"); - } else { - outputFile = Test.createTempFile(".out"); - builder.redirectOutput(outputFile.toFile()); - sb.append(String.format("; redirect output to [%s]", outputFile)); - } + sb.append("; save output"); + } else if (saveOutputType.contains(SaveOutputType.DUMP)) { + builder.inheritIO(); + sb.append("; inherit I/O"); } if (directory != null) { builder.directory(directory.toFile()); sb.append(String.format("; in directory [%s]", directory)); } - try { - Test.trace("Execute " + sb.toString() + "..."); - Process process = builder.start(); - Result reply = new Result(process.waitFor()); - Test.trace("Done. Exit code: " + reply.exitCode); - if (saveOutputType == SaveOutputType.FIRST_LINE) { - // If the command produced no ouput, save null in 'result.output' list. - reply.output = Arrays.asList( - Files.readAllLines(outputFile).stream().findFirst().orElse( - null)); - } else if (saveOutputType == SaveOutputType.FULL) { - reply.output = Collections.unmodifiableList(Files.readAllLines( - outputFile)); - } - return reply; - } finally { - if (outputFile != null) { - Files.deleteIfExists(outputFile); + TKit.trace("Execute " + sb.toString() + "..."); + Process process = builder.start(); + + List outputLines = null; + if (withSavedOutput()) { + try (BufferedReader outReader = new BufferedReader( + new InputStreamReader(process.getInputStream()))) { + if (saveOutputType.contains(SaveOutputType.DUMP) || saveOutputType.contains( + SaveOutputType.FULL)) { + outputLines = outReader.lines().collect(Collectors.toList()); + } else { + outputLines = Arrays.asList( + outReader.lines().findFirst().orElse(null)); + } + } finally { + if (saveOutputType.contains(SaveOutputType.DUMP) && outputLines != null) { + outputLines.stream().forEach(System.out::println); + if (saveOutputType.contains(SaveOutputType.FIRST_LINE)) { + // Pick the first line of saved output if there is one + for (String line: outputLines) { + outputLines = List.of(line); + break; + } + } + } } } + + Result reply = new Result(process.waitFor()); + TKit.trace("Done. Exit code: " + reply.exitCode); + + if (outputLines != null) { + reply.output = Collections.unmodifiableList(outputLines); + } + return reply; + } + + private Result runToolProvider(PrintStream out, PrintStream err) { + TKit.trace("Execute " + getPrintableCommandLine() + "..."); + Result reply = new Result(toolProvider.run(out, err, args.toArray( + String[]::new))); + TKit.trace("Done. Exit code: " + reply.exitCode); + return reply; } - private Result runToolProvider() { - StringWriter writer = new StringWriter(); - PrintWriter pw = new PrintWriter(writer); + + private Result runToolProvider() throws IOException { + if (!withSavedOutput()) { + if (saveOutputType.contains(SaveOutputType.DUMP)) { + return runToolProvider(System.out, System.err); + } - Test.trace("Execute " + getPrintableCommandLine() + "..."); - Result reply = new Result(toolProvider.run(pw, pw, args.toArray( - String[]::new))); - Test.trace("Done. Exit code: " + reply.exitCode); + PrintStream nullPrintStream = new PrintStream(new OutputStream() { + @Override + public void write(int b) { + // Nop + } + }); + return runToolProvider(nullPrintStream, nullPrintStream); + } - List lines = List.of(writer.toString().split("\\R", -1)); + try (ByteArrayOutputStream buf = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(buf)) { + Result reply = runToolProvider(ps, ps); + ps.flush(); + try (BufferedReader bufReader = new BufferedReader(new StringReader( + buf.toString()))) { + if (saveOutputType.contains(SaveOutputType.FIRST_LINE)) { + String firstLine = filterJcovOutput(bufReader.lines()).findFirst().orElse( + null); + if (firstLine != null) { + reply.output = List.of(firstLine); + } + } else if (saveOutputType.contains(SaveOutputType.FULL)) { + reply.output = filterJcovOutput(bufReader.lines()).collect( + Collectors.toUnmodifiableList()); + } - if (saveOutputType == SaveOutputType.FIRST_LINE) { - reply.output = Stream.of(lines).findFirst().get(); - } else if (saveOutputType == SaveOutputType.FULL) { - reply.output = Collections.unmodifiableList(lines); + if (saveOutputType.contains(SaveOutputType.DUMP)) { + Stream lines; + if (saveOutputType.contains(SaveOutputType.FULL)) { + lines = reply.output.stream(); + } else { + lines = bufReader.lines(); + } + lines.forEach(System.out::println); + } + } + return reply; } - return reply; } public String getPrintableCommandLine() { @@ -216,7 +323,7 @@ format = "tool provider " + format; exec = toolProvider.name(); } else { - exec = executable; + exec = executable.toString(); } return String.format(format, printCommandLine(exec, args), @@ -232,10 +339,18 @@ Collectors.joining(" ")); } + private Stream filterJcovOutput(Stream lines) { + if (filterOutJcovOutput) { + return lines.filter(line -> !line.startsWith("Picked up")); + } + return lines; + } + private ToolProvider toolProvider; - private String executable; - private SaveOutputType saveOutputType; + private Path executable; + private Set saveOutputType; private Path directory; + private boolean filterOutJcovOutput; private static enum SaveOutputType { NONE, FULL, FIRST_LINE, DUMP diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java Mon Sep 30 19:11:19 2019 -0400 @@ -34,14 +34,14 @@ } public void createFile() { - Test.createPropertiesFile(file, + TKit.createPropertiesFile(file, Map.entry("extension", suffixName), Map.entry("mime-type", getMime()), Map.entry("description", description)); } final public FileAssociations setFilename(String v) { - file = Test.workDir().resolve(v + ".properties"); + file = TKit.workDir().resolve(v + ".properties"); return this; } diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Functional.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Functional.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Functional.java Mon Sep 30 19:11:19 2019 -0400 @@ -23,9 +23,9 @@ package jdk.jpackage.test; import java.lang.reflect.InvocationTargetException; -import java.util.Optional; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Predicate; import java.util.function.Supplier; @@ -110,6 +110,18 @@ return v; } + public static Function identityFunction(Function v) { + return v; + } + + public static Predicate identity(Predicate v) { + return v; + } + + public static Predicate identityPredicate(Predicate v) { + return v; + } + public static class ExceptionBox extends RuntimeException { public ExceptionBox(Throwable throwable) { super(throwable); diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java Mon Sep 30 19:11:19 2019 -0400 @@ -26,70 +26,227 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Collections; -import java.util.Enumeration; +import java.util.ArrayList; import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import jdk.jpackage.test.Functional.ThrowingFunction; +import jdk.jpackage.test.Functional.ThrowingSupplier; public class HelloApp { - private static final String MAIN_CLASS = "Hello"; - private static final String JAR_FILENAME = "hello.jar"; - private static final Consumer CREATE_JAR_ACTION = (cmd) -> { - new JarBuilder() - .setOutputJar(cmd.inputDir().resolve(JAR_FILENAME).toFile()) - .setMainClass(MAIN_CLASS) - .addSourceFile(Test.TEST_SRC_ROOT.resolve( - Path.of("apps", "image", MAIN_CLASS + ".java"))) - .create(); - }; + 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; + } + + private JarBuilder prepareSources(Path srcDir) throws IOException { + final String className = qualifiedClassName.substring( + qualifiedClassName.lastIndexOf('.') + 1); + final String packageName = packageName(); + + final Path srcFile = srcDir.resolve(Path.of(String.join( + File.separator, qualifiedClassName.split("\\.")) + ".java")); + Files.createDirectories(srcFile.getParent()); + + JarBuilder jarBuilder = createJarBuilder().addSourceFile(srcFile); + if (moduleName != null) { + Path moduleInfoFile = srcDir.resolve("module-info.java"); + TKit.createTextFile(moduleInfoFile, List.of( + String.format("module %s {", moduleName), + String.format(" exports %s;", packageName), + "}" + )); + jarBuilder.addSourceFile(moduleInfoFile); + if (moduleVersion != null) { + jarBuilder.setModuleVersion(moduleVersion); + } + } + + // Add package directive and replace class name in java source file. + // Works with simple test Hello.java. + // Don't expect too much from these regexps! + Pattern classDeclaration = Pattern.compile("(^.*\\bclass\\s+)Hello(.*$)"); + Pattern importDirective = Pattern.compile( + "(?<=import (?:static )?+)[^;]+"); + AtomicBoolean classDeclared = new AtomicBoolean(); + AtomicBoolean packageInserted = new AtomicBoolean(packageName == null); + + var packageInserter = Functional.identityFunction((line) -> { + packageInserted.setPlain(true); + return String.format("package %s;%s%s", packageName, + System.lineSeparator(), line); + }); - static void addTo(JPackageCommand cmd) { - cmd.addAction(CREATE_JAR_ACTION); - cmd.addArguments("--main-jar", JAR_FILENAME); - cmd.addArguments("--main-class", MAIN_CLASS); - if (PackageType.WINDOWS.contains(cmd.packageType())) { + Files.write(srcFile, Files.readAllLines(HELLO_JAVA).stream().map(line -> { + if (classDeclared.getPlain()) { + return line; + } + + Matcher m; + if (!packageInserted.getPlain() && importDirective.matcher(line).find()) { + line = packageInserter.apply(line); + } else if ((m = classDeclaration.matcher(line)).find()) { + classDeclared.setPlain(true); + line = m.group(1) + className + m.group(2); + if (!packageInserted.getPlain()) { + line = packageInserter.apply(line); + } + } + return line; + }).collect(Collectors.toList())); + + return jarBuilder; + } + + private JarBuilder createJarBuilder() { + return new JarBuilder().setMainClass(qualifiedClassName); + } + + private void addTo(JPackageCommand cmd) { + if (moduleName != null && packageName() == null) { + throw new IllegalArgumentException(String.format( + "Module [%s] with default package", moduleName)); + } + + if (moduleName == null && CLASS_NAME.equals(qualifiedClassName)) { + // Use Hello.java as is. + cmd.addAction((self) -> { + File jarFile = self.inputDir().resolve(jarFileName).toFile(); + createJarBuilder().setOutputJar(jarFile).addSourceFile( + HELLO_JAVA).create(); + }); + } else { + cmd.addAction((self) -> { + final Path jarFile; + if (moduleName == null) { + jarFile = self.inputDir().resolve(jarFileName); + } else { + // `--module-path` option should be set by the moment + // when this action is being executed. + jarFile = Path.of(self.getArgumentValue("--module-path", + () -> self.inputDir().toString()), jarFileName); + Files.createDirectories(jarFile.getParent()); + } + + TKit.withTempDirectory("src", + workDir -> prepareSources(workDir).setOutputJar( + jarFile.toFile()).create()); + }); + } + + if (moduleName == null) { + cmd.addArguments("--main-jar", jarFileName); + cmd.addArguments("--main-class", qualifiedClassName); + } else { + cmd.addArguments("--module-path", TKit.workDir().resolve( + "input-modules")); + cmd.addArguments("--module", String.join("/", moduleName, + qualifiedClassName)); + // For modular app assume nothing will go in input directory and thus + // nobody will create input directory, so remove corresponding option + // from jpackage command line. + cmd.removeArgumentWithValue("--input"); + } + if (TKit.isWindows()) { cmd.addArguments("--win-console"); } } - static void verifyOutputFile(Path outputFile, String... args) { + 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 void verifyOutputFile(Path outputFile, List args) { if (!outputFile.isAbsolute()) { verifyOutputFile(outputFile.toAbsolutePath().normalize(), args); return; } - Test.assertFileExists(outputFile, true); + TKit.assertFileExists(outputFile); - List output = null; - try { - output = Files.readAllLines(outputFile); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - - final int expectedNumberOfLines = 2 + args.length; - Test.assertEquals(expectedNumberOfLines, output.size(), String.format( - "Check file [%s] contains %d text lines", outputFile, - expectedNumberOfLines)); + List contents = ThrowingSupplier.toSupplier( + () -> Files.readAllLines(outputFile)).get(); - Test.assertEquals("jpackage test application", output.get(0), - String.format( - "Check contents of the first text line in [%s] file", - outputFile)); + List expected = new ArrayList<>(List.of( + "jpackage test application", + String.format("args.length: %d", args.size()) + )); + expected.addAll(args); - Test.assertEquals(String.format("args.length: %d", args.length), - output.get(1), String.format( - "Check contents of the second text line in [%s] file", - outputFile)); - - Enumeration argsEnum = Collections.enumeration(List.of(args)); - AtomicInteger counter = new AtomicInteger(2); - output.stream().skip(2).sequential().forEach(line -> Test.assertEquals( - argsEnum.nextElement(), line, String.format( - "Check contents of %d text line in [%s] file", - counter.incrementAndGet(), outputFile))); + TKit.assertStringListEquals(expected, contents, String.format( + "Check contents of [%s] file", outputFile)); } public static void executeLauncherAndVerifyOutput(JPackageCommand cmd) { @@ -115,20 +272,33 @@ public static void executeAndVerifyOutput(Path helloAppLauncher, String... defaultLauncherArgs) { - File outputFile = Test.workDir().resolve(OUTPUT_FILENAME).toFile(); - try { - Files.deleteIfExists(outputFile.toPath()); - } catch (IOException ex) { - throw new RuntimeException(ex); - } + executeAndVerifyOutput(helloAppLauncher, List.of(defaultLauncherArgs)); + } + + public static void executeAndVerifyOutput(Path helloAppLauncher, + List defaultLauncherArgs) { + // Output file will be created in the current directory. + Path outputFile = Path.of(OUTPUT_FILENAME); + ThrowingFunction.toFunction(Files::deleteIfExists).apply(outputFile); new Executor() - .setDirectory(outputFile.getParentFile().toPath()) - .setExecutable(helloAppLauncher.toString()) + .setDirectory(outputFile.getParent()) + .setExecutable(helloAppLauncher) .execute() .assertExitCodeIsZero(); - verifyOutputFile(outputFile.toPath(), defaultLauncherArgs); + verifyOutputFile(outputFile, defaultLauncherArgs); } final static String OUTPUT_FILENAME = "appOutput.txt"; + + private String qualifiedClassName; + private String moduleName; + private String jarFileName; + private String moduleVersion; + + private static final Path HELLO_JAVA = TKit.TEST_SRC_ROOT.resolve( + "apps/image/Hello.java"); + + private final static String CLASS_NAME = HELLO_JAVA.getFileName().toString().split( + "\\.", 2)[0]; } diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java Mon Sep 30 19:11:19 2019 -0400 @@ -27,16 +27,14 @@ import java.nio.file.Files; import java.nio.file.Path; import java.security.SecureRandom; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; +import java.util.*; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import jdk.jpackage.test.Functional.ThrowingConsumer; /** * jpackage command line with prerequisite actions. Prerequisite actions can be @@ -87,8 +85,14 @@ return setArgumentValue(argName, newValue.toString()); } + public JPackageCommand removeArgumentWithValue(String argName) { + return setArgumentValue(argName, (String)null); + } + public JPackageCommand removeArgument(String argName) { - return setArgumentValue(argName, (String)null); + args = args.stream().filter(arg -> !arg.equals(argName)).collect( + Collectors.toList()); + return this; } public boolean hasArgument(String argName) { @@ -149,17 +153,21 @@ } 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 + // this is operator's fault. return getArgumentValue("--package-type", - () -> PackageType.DEFAULT, - (v) -> PACKAGE_TYPES.get(v)); + () -> { + throw new IllegalStateException("Package type not set"); + }, PACKAGE_TYPES::get); } public Path outputDir() { - return getArgumentValue("--dest", () -> Test.defaultOutputDir(), Path::of); + return getArgumentValue("--dest", () -> Path.of("."), Path::of); } public Path inputDir() { - return getArgumentValue("--input", () -> Test.defaultInputDir(),Path::of); + return getArgumentValue("--input", () -> null, Path::of); } public String version() { @@ -178,8 +186,8 @@ } public JPackageCommand setDefaultInputOutput() { - addArguments("--input", Test.defaultInputDir()); - addArguments("--dest", Test.defaultOutputDir()); + addArguments("--input", TKit.defaultInputDir()); + addArguments("--dest", TKit.defaultOutputDir()); return this; } @@ -187,10 +195,10 @@ verifyMutable(); try { - Path fakeRuntimeDir = Test.workDir().resolve("fake_runtime"); + Path fakeRuntimeDir = TKit.workDir().resolve("fake_runtime"); Files.createDirectories(fakeRuntimeDir); - if (Test.isWindows() || Test.isLinux()) { + if (TKit.isWindows() || TKit.isLinux()) { // Needed to make WindowsAppBundler happy as it copies MSVC dlls // from `bin` directory. // Need to make the code in rpm spec happy as it assumes there is @@ -218,17 +226,29 @@ return this; } - JPackageCommand addAction(Consumer action) { + JPackageCommand addAction(ThrowingConsumer action) { verifyMutable(); - actions.add(action); + actions.add(ThrowingConsumer.toConsumer(action)); return this; } public static JPackageCommand helloAppImage() { + return helloAppImage(null); + } + + /** + * Creates new JPackageCommand instance configured with the test Java app. + * For the explanation of `javaAppDesc` parameter, see documentation for + * HelloApp.addTo() method. + * + * @param javaAppDesc Java application description + * @return this + */ + public static JPackageCommand helloAppImage(String javaAppDesc) { JPackageCommand cmd = new JPackageCommand(); cmd.setDefaultInputOutput().setDefaultAppName(); PackageType.IMAGE.applyTo(cmd); - HelloApp.addTo(cmd); + HelloApp.addTo(cmd, javaAppDesc); return cmd; } @@ -239,8 +259,7 @@ } JPackageCommand setDefaultAppName() { - addArguments("--name", Test.enclosingMainMethodClass().getSimpleName()); - return this; + return addArguments("--name", TKit.getCurrentDefaultAppName()); } public Path outputBundle() { @@ -292,7 +311,7 @@ return MacHelper.getInstallationDirectory(this); } - throw new IllegalArgumentException("Unexpected package type"); + throw throwUnexpectedPackageTypeError(); } /** @@ -336,24 +355,24 @@ return appInstallationDirectory().resolve(Path.of("Contents", "MacOS", name())); } - throw new IllegalArgumentException("Unexpected package type"); + 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. + * 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() { - final PackageType type = packageType(); - if (PackageType.IMAGE != type) { - throw new IllegalArgumentException("Unexpected package type"); + verifyIsOfType(PackageType.IMAGE); + String dirName = name(); + if (TKit.isOSX()) { + dirName = dirName + ".app"; } - - return outputDir().resolve(name()); + return outputDir().resolve(dirName); } /** @@ -365,24 +384,21 @@ * @throws IllegalArgumentException is command is doing platform packaging */ public Path launcherPathInAppImage() { - final PackageType type = packageType(); - if (PackageType.IMAGE != type) { - throw new IllegalArgumentException("Unexpected package type"); - } + verifyIsOfType(PackageType.IMAGE); - if (Test.isLinux()) { + if (TKit.isLinux()) { return Path.of("bin", name()); } - if (Test.isOSX()) { + if (TKit.isOSX()) { return Path.of("Contents", "MacOS", name()); } - if (Test.isWindows()) { + if (TKit.isWindows()) { return Path.of(name() + ".exe"); } - throw new IllegalArgumentException("Unexpected package type"); + throw TKit.throwUnknownPlatformError(); } /** @@ -392,18 +408,18 @@ * packaging */ public Path appRuntimeDirectoryInAppImage() { - final PackageType type = packageType(); - if (PackageType.IMAGE != type) { - throw new IllegalArgumentException("Unexpected package type"); - } - - return appRuntimePath(type); + verifyIsOfType(PackageType.IMAGE); + return appRuntimePath(packageType()); } private static Path appRuntimePath(PackageType type) { - if (PackageType.LINUX.contains(type)) { + if (TKit.isLinux()) { return Path.of("lib/runtime"); } + if (TKit.isOSX()) { + return Path.of("Contents/runtime"); + } + return Path.of("runtime"); } @@ -417,22 +433,22 @@ } private static boolean isFakeRuntime(Path runtimeDir, String msg) { - final List criticalRuntimeFiles; - if (Test.isWindows()) { - criticalRuntimeFiles = List.of(Path.of("bin\\server\\jvm.dll")); - } else if (Test.isLinux()) { - criticalRuntimeFiles = List.of(Path.of("lib/server/libjvm.so")); - } else if (Test.isOSX()) { - criticalRuntimeFiles = List.of(Path.of("lib/server/libjvm.dylib")); + final Collection criticalRuntimeFiles; + if (TKit.isWindows()) { + criticalRuntimeFiles = WindowsHelper.CRITICAL_RUNTIME_FILES; + } else if (TKit.isLinux()) { + criticalRuntimeFiles = LinuxHelper.CRITICAL_RUNTIME_FILES; + } else if (TKit.isOSX()) { + criticalRuntimeFiles = MacHelper.CRITICAL_RUNTIME_FILES; } else { - throw new IllegalArgumentException("Unknwon platform"); + throw TKit.throwUnknownPlatformError(); } if (criticalRuntimeFiles.stream().filter( v -> runtimeDir.resolve(v).toFile().exists()).findFirst().orElse( null) == null) { // Fake runtime - Test.trace(String.format( + TKit.trace(String.format( "%s because application runtime directory [%s] is incomplete", msg, runtimeDir)); return true; @@ -440,18 +456,85 @@ return false; } - public Executor.Result execute() { + public static void useToolProviderByDefault() { + defaultWithToolProvider = true; + } + + public static void useExecutableByDefault() { + defaultWithToolProvider = false; + } + + public JPackageCommand useToolProvider(boolean v) { + verifyMutable(); + withToolProvider = v; + return this; + } + + public JPackageCommand saveConsoleOutput(boolean v) { + verifyMutable(); + saveConsoleOutput = v; + return this; + } + + public JPackageCommand dumpOutput(boolean v) { verifyMutable(); - if (actions != null) { - actions.stream().forEach(r -> r.accept(this)); + suppressOutput = !v; + return this; + } + + public boolean isWithToolProvider() { + return Optional.ofNullable(withToolProvider).orElse( + defaultWithToolProvider); + } + + public void executePrerequisiteActions() { + verifyMutable(); + if (!actionsExecuted) { + actionsExecuted = true; + if (actions != null) { + actions.stream().forEach(r -> r.accept(this)); + } + } + } + + public Executor.Result execute() { + executePrerequisiteActions(); + + if (packageType() == PackageType.IMAGE) { + TKit.deleteDirectoryContentsRecursive(outputDir()); } - return new Executor() - .setExecutable(JavaTool.JPACKAGE) - .dumpOtput() + Executor exec = new Executor() + .saveOutput(saveConsoleOutput).dumpOutput(!suppressOutput) .addArguments(new JPackageCommand().addArguments( - args).adjustArgumentsBeforeExecution().args) - .execute(); + args).adjustArgumentsBeforeExecution().args); + + if (isWithToolProvider()) { + exec.setToolProvider(JavaTool.JPACKAGE.asToolProvider()); + } else { + exec.setExecutable(JavaTool.JPACKAGE); + } + return exec.execute(); + } + + public JPackageCommand executeAndAssertHelloAppImageCreated() { + executeAndAssertImageCreated(); + HelloApp.executeLauncherAndVerifyOutput(this); + return this; + } + + public JPackageCommand executeAndAssertImageCreated() { + execute().assertExitCodeIsZero(); + return assertImageCreated(); + } + + public JPackageCommand assertImageCreated() { + verifyIsOfType(PackageType.IMAGE); + TKit.assertExecutableFileExists(appImage().resolve( + launcherPathInAppImage())); + TKit.assertDirectoryExists(appImage().resolve( + appRuntimeDirectoryInAppImage())); + return this; } private JPackageCommand adjustArgumentsBeforeExecution() { @@ -459,13 +542,17 @@ addArguments("--runtime-image", DEFAULT_RUNTIME_IMAGE); } - if (!hasArgument("--verbose") && Test.VERBOSE_JPACKAGE) { + if (!hasArgument("--verbose") && TKit.VERBOSE_JPACKAGE) { addArgument("--verbose"); } return this; } + private static RuntimeException throwUnexpectedPackageTypeError() { + throw new IllegalArgumentException("Unexpected package type"); + } + String getPrintableCommandLine() { return new Executor() .setExecutable(JavaTool.JPACKAGE) @@ -479,43 +566,80 @@ public void verifyIsOfType(PackageType ... types) { if (!Arrays.asList(types).contains(packageType())) { - throw new IllegalArgumentException("Unexpected package type"); + throwUnexpectedPackageTypeError(); } } + public static String escapeAndJoin(String... args) { + return escapeAndJoin(List.of(args)); + } + + public static String escapeAndJoin(List args) { + Pattern whitespaceRegexp = Pattern.compile("\\s"); + + return args.stream().map(v -> { + String str = v; + // Escape quotes. + str = str.replace("\"", "\\\""); + // Escape backslashes. + str = str.replace("\\", "\\\\"); + // If value contains whitespace characters, put the value in quotes + if (whitespaceRegexp.matcher(str).find()) { + str = "\"" + str + "\""; + } + return str; + }).collect(Collectors.joining(" ")); + } + + public static Path relativePathInRuntime(JavaTool tool) { + Path path = tool.relativePathInJavaHome(); + if (TKit.isOSX()) { + path = Path.of("Contents/Home").resolve(path); + } + return path; + } + + public static Stream filterOutput(Stream jpackageOutput) { + // Skip "WARNING: Using experimental tool jpackage" first line of output + return jpackageOutput.skip(1); + } + + public static List filterOutput(List jpackageOutput) { + return filterOutput(jpackageOutput.stream()).collect(Collectors.toList()); + } + @Override protected boolean isMutable() { return !immutable; } + private Boolean withToolProvider; + private boolean saveConsoleOutput; + private boolean suppressOutput; + private boolean immutable; + private boolean actionsExecuted; private final List> actions; - private boolean immutable; + private static boolean defaultWithToolProvider; - private final static Map PACKAGE_TYPES - = new Supplier>() { - @Override - public Map get() { - Map reply = new HashMap<>(); - for (PackageType type : PackageType.values()) { - reply.put(type.getName(), type); - } - return reply; + private final static Map PACKAGE_TYPES = Functional.identity( + () -> { + Map reply = new HashMap<>(); + for (PackageType type : PackageType.values()) { + reply.put(type.getName(), type); } - }.get(); + return reply; + }).get(); - public final static Path DEFAULT_RUNTIME_IMAGE; - - static { + public final static Path DEFAULT_RUNTIME_IMAGE = Functional.identity(() -> { // Set the property to the path of run-time image to speed up // building app images and platform bundles by avoiding running jlink // The value of the property will be automativcally appended to // jpackage command line if the command line doesn't have // `--runtime-image` parameter set. - String val = Test.getConfigProperty("runtime-image"); + String val = TKit.getConfigProperty("runtime-image"); if (val != null) { - DEFAULT_RUNTIME_IMAGE = Path.of(val); - } else { - DEFAULT_RUNTIME_IMAGE = null; + return Path.of(val); } - } + return null; + }).get(); } diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JarBuilder.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JarBuilder.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JarBuilder.java Mon Sep 30 19:11:19 2019 -0400 @@ -29,7 +29,6 @@ import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import java.util.ArrayList; import java.util.List; -import jdk.jpackage.internal.IOUtils; /** @@ -56,19 +55,13 @@ return this; } - public void create() { - try { - createImpl(); - } catch (RuntimeException e) { - throw e; - } catch (Exception e) { - throw new RuntimeException(e); - } + public JarBuilder setModuleVersion(String v) { + moduleVersion = v; + return this; } - private void createImpl() throws Exception { - Path workDir = Test.createTempDirectory(); - try { + public void create() { + TKit.withTempDirectory("jar-workdir", workDir -> { Executor.Result javacReply = new Executor() .setExecutable(JavaTool.JAVAC) .addArguments("-d", workDir.toString()) @@ -78,6 +71,10 @@ Executor jarExe = new Executor(); jarExe.setExecutable(JavaTool.JAR).addArguments("-c", "-v", "-f", tmpJar.toString()); + if (moduleVersion != null) { + jarExe.addArguments(String.format("--module-version=%s", + moduleVersion)); + } if (mainClass != null) { jarExe.addArguments("-e", mainClass); } @@ -86,11 +83,10 @@ javacReply.assertExitCodeIsZero(); outputJar.getParentFile().mkdirs(); Files.copy(tmpJar, outputJar.toPath(), REPLACE_EXISTING); - } finally { - IOUtils.deleteRecursive(workDir.toFile()); - } + }); } private List sourceFiles; private File outputJar; private String mainClass; + private String moduleVersion; } diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JavaTool.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JavaTool.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JavaTool.java Mon Sep 30 19:11:19 2019 -0400 @@ -25,33 +25,38 @@ package jdk.jpackage.test; -import java.io.File; import java.nio.file.Path; import java.util.spi.ToolProvider; public enum JavaTool { - JAVAC("javac"), JPACKAGE("jpackage"), JAR("jar"); + JAVA("java"), JAVAC("javac"), JPACKAGE("jpackage"), JAR("jar"), JLINK("jlink"); JavaTool(String name) { this.name = name; - path = Path.of(System.getProperty("java.home"), "bin", name).toFile(); - if (Test.isWindows()) { - path = new File(path.toString() + ".exe"); - } - if (!path.exists()) { - throw new RuntimeException("Unable to find tool [" - + name + "] at path=[" + path.getAbsolutePath() + "]"); + this.path = Path.of(System.getProperty("java.home")).resolve( + relativePathInJavaHome()).toAbsolutePath().normalize(); + if (!path.toFile().exists()) { + throw new RuntimeException(String.format( + "Unable to find tool [%s] at path=[%s]", name, path)); } } - File getPath() { + Path getPath() { return path; } - ToolProvider asToolProvider() { + public ToolProvider asToolProvider() { return ToolProvider.findFirst(name).orElse(null); } - private File path; + Path relativePathInJavaHome() { + Path path = Path.of("bin", name); + if (TKit.isWindows()) { + path = path.getParent().resolve(path.getFileName().toString() + ".exe"); + } + return path; + } + + private Path path; private String name; } diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java Mon Sep 30 19:11:19 2019 -0400 @@ -31,6 +31,7 @@ import java.util.Map; import java.util.Set; import java.util.function.Function; +import java.util.stream.Collectors; import java.util.stream.Stream; public class LinuxHelper { @@ -99,6 +100,48 @@ return lines.map(Path::of); } + public static List getPrerequisitePackages(JPackageCommand cmd) { + cmd.verifyIsOfType(PackageType.LINUX); + var packageType = cmd.packageType(); + switch (packageType) { + case LINUX_DEB: + return Stream.of(getDebBundleProperty(cmd.outputBundle(), + "Depends").split(",")).map(String::strip).collect( + Collectors.toList()); + + case LINUX_RPM: + return new Executor().setExecutable("rpm") + .addArguments("-qp", "-R", cmd.outputBundle().toString()) + .executeAndGetOutput(); + } + // Unreachable + return null; + } + + public static String getBundleProperty(JPackageCommand cmd, + String propertyName) { + return getBundleProperty(cmd, + Map.of(PackageType.LINUX_DEB, propertyName, + PackageType.LINUX_RPM, propertyName)); + } + + public static String getBundleProperty(JPackageCommand cmd, + Map propertyName) { + cmd.verifyIsOfType(PackageType.LINUX); + var packageType = cmd.packageType(); + switch (packageType) { + case LINUX_DEB: + return getDebBundleProperty(cmd.outputBundle(), propertyName.get( + packageType)); + + case LINUX_RPM: + return getRpmBundleProperty(cmd.outputBundle(), propertyName.get( + packageType)); + } + // Unrechable + return null; + } + static Path getLauncherPath(JPackageCommand cmd) { cmd.verifyIsOfType(PackageType.LINUX); @@ -107,7 +150,7 @@ return getPackageFiles(cmd).filter(path -> path.toString().endsWith( launcherRelativePath)).findFirst().or(() -> { - Test.assertUnexpected(String.format( + TKit.assertUnexpected(String.format( "Failed to find %s in %s package", launcherName, getPackageName(cmd))); return null; @@ -160,32 +203,28 @@ }; test.addBundleVerifier(cmd -> { - Test.withTempDirectory(tempDir -> { - try { - // Extract control Debian package files into temporary directory - new Executor() - .setExecutable("dpkg") - .addArguments( - "-e", - cmd.outputBundle().toString(), - tempDir.toString() - ).execute().assertExitCodeIsZero(); - - Path controlFile = Path.of("postinst"); + TKit.withTempDirectory("dpkg-control-files", tempDir -> { + // Extract control Debian package files into temporary directory + new Executor() + .setExecutable("dpkg") + .addArguments( + "-e", + cmd.outputBundle().toString(), + tempDir.toString() + ).execute().assertExitCodeIsZero(); - // Lookup for xdg commands in postinstall script - String lineWithXsdCommand = verifier.apply( - Files.readAllLines(tempDir.resolve(controlFile))); - String assertMsg = String.format( - "Check if %s@%s control file uses xdg commands", - cmd.outputBundle(), controlFile); - if (integrated) { - Test.assertNotNull(lineWithXsdCommand, assertMsg); - } else { - Test.assertNull(lineWithXsdCommand, assertMsg); - } - } catch (IOException ex) { - throw new RuntimeException(ex); + Path controlFile = Path.of("postinst"); + + // Lookup for xdg commands in postinstall script + String lineWithXsdCommand = verifier.apply( + Files.readAllLines(tempDir.resolve(controlFile))); + String assertMsg = String.format( + "Check if %s@%s control file uses xdg commands", + cmd.outputBundle(), controlFile); + if (integrated) { + TKit.assertNotNull(lineWithXsdCommand, assertMsg); + } else { + TKit.assertNull(lineWithXsdCommand, assertMsg); } }); }); @@ -220,12 +259,10 @@ static void addFileAssociationsVerifier(PackageTest test, FileAssociations fa) { test.addInstallVerifier(cmd -> { - Test.withTempFile(fa.getSuffix(), testFile -> { - initFileAssociationsTestFile(testFile); - + PackageTest.withTestFileAssociationsFile(fa, testFile -> { String mimeType = queryFileMimeType(testFile); - Test.assertEquals(fa.getMime(), mimeType, String.format( + TKit.assertEquals(fa.getMime(), mimeType, String.format( "Check mime type of [%s] file", testFile)); String desktopFileName = queryMimeTypeDefaultHandler(mimeType); @@ -233,21 +270,17 @@ Path desktopFile = getSystemDesktopFilesFolder().resolve( desktopFileName); - Test.assertFileExists(desktopFile, true); + TKit.assertFileExists(desktopFile); - Test.trace(String.format("Reading [%s] file...", desktopFile)); - String mimeHandler = null; - try { - mimeHandler = Files.readAllLines(desktopFile).stream().peek( - v -> Test.trace(v)).filter( - v -> v.startsWith("Exec=")).map( - v -> v.split("=", 2)[1]).findFirst().orElseThrow(); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - Test.trace(String.format("Done")); + TKit.trace(String.format("Reading [%s] file...", desktopFile)); + String mimeHandler = Files.readAllLines(desktopFile).stream().peek( + v -> TKit.trace(v)).filter( + v -> v.startsWith("Exec=")).map( + v -> v.split("=", 2)[1]).findFirst().orElseThrow(); - Test.assertEquals(cmd.launcherInstallationPath().toString(), + TKit.trace(String.format("Done")); + + TKit.assertEquals(cmd.launcherInstallationPath().toString(), mimeHandler, String.format( "Check mime type handler is the main application launcher")); @@ -255,17 +288,15 @@ }); test.addUninstallVerifier(cmd -> { - Test.withTempFile(fa.getSuffix(), testFile -> { - initFileAssociationsTestFile(testFile); - + PackageTest.withTestFileAssociationsFile(fa, testFile -> { String mimeType = queryFileMimeType(testFile); - Test.assertNotEquals(fa.getMime(), mimeType, String.format( + TKit.assertNotEquals(fa.getMime(), mimeType, String.format( "Check mime type of [%s] file", testFile)); String desktopFileName = queryMimeTypeDefaultHandler(fa.getMime()); - Test.assertNull(desktopFileName, String.format( + TKit.assertNull(desktopFileName, String.format( "Check there is no default handler for [%s] mime type", fa.getMime())); }); @@ -311,5 +342,8 @@ return arch; } + static final Set CRITICAL_RUNTIME_FILES = Set.of(Path.of( + "lib/server/libjvm.so")); + static private Map archs; } diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java Mon Sep 30 19:11:19 2019 -0400 @@ -23,6 +23,7 @@ package jdk.jpackage.test; import java.nio.file.Path; +import java.util.Set; public class MacHelper { @@ -41,6 +42,10 @@ private static String getPackageName(JPackageCommand cmd) { return cmd.getArgumentValue("--mac-package-name", - () -> cmd.name().toLowerCase()); + () -> cmd.name()); } + + static final Set CRITICAL_RUNTIME_FILES = Set.of(Path.of( + "Contents/Home/lib/server/libjvm.dylib")); + } diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Main.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Main.java Mon Sep 30 19:11:19 2019 -0400 @@ -0,0 +1,97 @@ +/* + * 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.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import static jdk.jpackage.test.TestBuilder.CMDLINE_ARG_PREFIX; + + +public final class Main { + public static void main(String args[]) throws Throwable { + boolean listTests = false; + 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)); + } + + if ((CMDLINE_ARG_PREFIX + "list").equals(arg)) { + listTests = true; + continue; + } + + boolean success = false; + try { + testBuilder.processCmdLineArg(arg); + success = true; + } catch (Throwable throwable) { + TKit.unbox(throwable); + } finally { + if (!success) { + TKit.log( + String.format("Error processing parameter=[%s]", + arg)); + } + } + } + } + + // 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()); + + if (listTests) { + // Just list the tests + tests.stream().forEach(test -> System.out.println(test.fullName())); + return; + } + + TKit.runTests(tests); + + final long failedCount = tests.stream().filter(Functional.identity( + TestInstance::passed).negate()).count(); + final long passedCount = tests.size() - failedCount; + + TKit.log(String.format("[==========] %d tests ran", tests.size())); + TKit.log(String.format("[ PASSED ] %d %s", passedCount, + passedCount == 1 ? "test" : "tests")); + if (failedCount != 0) { + TKit.log(String.format("[ FAILED ] %d %s, listed below", + failedCount, + failedCount == 1 ? "test" : "tests")); + tests.stream().filter( + Functional.identity(TestInstance::passed).negate()).forEach( + test -> TKit.log(String.format("[ FAILED ] %s", + test.fullName()))); + + final String errorMessage = String.format("%d FAILED %s", + failedCount, failedCount == 1 ? "TEST" : "TESTS"); + TKit.log(errorMessage); + throw new RuntimeException(errorMessage); + } + } +} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java Mon Sep 30 19:11:19 2019 -0400 @@ -0,0 +1,62 @@ +/* + * 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.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +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) { + this.method = method; + this.args = args; + } + + TestDesc createDescription() { + return TestDesc.create(method, args); + } + + Constructor getRequiredConstructor() throws NoSuchMethodException { + return MethodCall.getRequiredConstructor(method); + } + + static Constructor getRequiredConstructor(Method method) throws + NoSuchMethodException { + if ((method.getModifiers() & Modifier.STATIC) == 0) { + return method.getDeclaringClass().getConstructor(); + } + return null; + } + + @Override + public void accept(Object thiz) throws Throwable { + method.invoke(thiz, args); + } + + private final Object[] args; + private final Method method; +} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -26,22 +26,14 @@ import java.io.File; import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; -import static jdk.jpackage.test.PackageType.LINUX_DEB; -import static jdk.jpackage.test.PackageType.LINUX_RPM; import jdk.jpackage.test.Functional.ThrowingConsumer; +import static jdk.jpackage.test.PackageType.*; /** * Instance of PackageTest is for configuring and running a single jpackage @@ -123,30 +115,15 @@ public PackageTest addBundlePropertyVerifier(String propertyName, BiConsumer pred) { return addBundleVerifier(cmd -> { - String propertyValue = null; - switch (cmd.packageType()) { - case LINUX_DEB: - propertyValue = LinuxHelper.getDebBundleProperty( - cmd.outputBundle(), propertyName); - break; - - case LINUX_RPM: - propertyValue = LinuxHelper.getRpmBundleProperty( - cmd.outputBundle(), propertyName); - break; - - default: - throw new UnsupportedOperationException(); - } - - pred.accept(propertyName, propertyValue); + pred.accept(propertyName, + LinuxHelper.getBundleProperty(cmd, propertyName)); }); } public PackageTest addBundlePropertyVerifier(String propertyName, String expectedPropertyValue) { return addBundlePropertyVerifier(propertyName, (unused, v) -> { - Test.assertEquals(expectedPropertyValue, v, String.format( + TKit.assertEquals(expectedPropertyValue, v, String.format( "Check value of %s property is [%s]", propertyName, v)); }); } @@ -172,29 +149,36 @@ return this; } + static void withTestFileAssociationsFile(FileAssociations fa, ThrowingConsumer consumer) { + final String testFileDefaultName = String.join(".", "test", fa.getSuffix()); + TKit.withTempFile(testFileDefaultName, fa.getSuffix(), testFile -> { + if (TKit.isLinux()) { + LinuxHelper.initFileAssociationsTestFile(testFile); + } + consumer.accept(testFile); + }); + } + public PackageTest addHelloAppFileAssociationsVerifier(FileAssociations fa, String... faLauncherDefaultArgs) { - addInitializer(cmd -> HelloApp.addTo(cmd), "HelloApp"); + addInitializer(cmd -> HelloApp.addTo(cmd, null), "HelloApp"); addInstallVerifier(cmd -> { if (cmd.isFakeRuntimeInstalled( "Not running file associations test")) { return; } - Test.withTempFile(fa.getSuffix(), testFile -> { + withTestFileAssociationsFile(fa, testFile -> { testFile = testFile.toAbsolutePath().normalize(); - if (PackageType.LINUX.contains(cmd.packageType())) { - LinuxHelper.initFileAssociationsTestFile(testFile); - } final Path appOutput = Path.of(HelloApp.OUTPUT_FILENAME); Files.deleteIfExists(appOutput); - Test.trace(String.format("Use desktop to open [%s] file", + TKit.trace(String.format("Use desktop to open [%s] file", testFile)); Desktop.getDesktop().open(testFile.toFile()); - Test.waitForFileCreated(appOutput, 7); + TKit.waitForFileCreated(appOutput, 7); List expectedArgs = new ArrayList<>(List.of( faLauncherDefaultArgs)); @@ -203,7 +187,7 @@ // Wait a little bit after file has been created to // make sure there are no pending writes into it. Thread.sleep(3000); - HelloApp.verifyOutputFile(appOutput, expectedArgs.toArray(String[]::new)); + HelloApp.verifyOutputFile(appOutput, expectedArgs); }); }); @@ -214,7 +198,7 @@ return this; } - private void forTypes(Collection types, Runnable action) { + PackageTest forTypes(Collection types, Runnable action) { Set oldTypes = Set.of(currentTypes.toArray( PackageType[]::new)); try { @@ -223,14 +207,19 @@ } finally { forTypes(oldTypes); } + return this; } - private void forTypes(PackageType type, Runnable action) { - forTypes(List.of(type), action); + PackageTest forTypes(PackageType type, Runnable action) { + return forTypes(List.of(type), action); } public PackageTest configureHelloApp() { - addInitializer(cmd -> HelloApp.addTo(cmd), "HelloApp"); + return configureHelloApp(null); + } + + public PackageTest configureHelloApp(String encodedName) { + addInitializer(cmd -> HelloApp.addTo(cmd, encodedName)); addInstallVerifier(HelloApp::executeLauncherAndVerifyOutput); return this; } @@ -312,8 +301,11 @@ case CREATE: Executor.Result result = cmd.execute(); result.assertExitCodeIs(expectedJPackageExitCode); - Test.assertFileExists(cmd.outputBundle(), - expectedJPackageExitCode == 0); + if (expectedJPackageExitCode == 0) { + TKit.assertFileExists(cmd.outputBundle()); + } else { + TKit.assertPathExists(cmd.outputBundle(), false); + } verifyPackageBundle(cmd.createImmutableCopy(), result); break; @@ -330,7 +322,7 @@ private void verifyPackageBundle(JPackageCommand cmd, Executor.Result result) { if (PackageType.LINUX.contains(cmd.packageType())) { - Test.assertNotEquals(0L, LinuxHelper.getInstalledPackageSizeKB( + TKit.assertNotEquals(0L, LinuxHelper.getInstalledPackageSizeKB( cmd), String.format( "Check installed size of [%s] package in KB is not zero", LinuxHelper.getPackageName(cmd))); @@ -339,13 +331,13 @@ } private void verifyPackageInstalled(JPackageCommand cmd) { - Test.trace(String.format("Verify installed: %s", + TKit.trace(String.format("Verify installed: %s", cmd.getPrintableCommandLine())); if (cmd.isRuntime()) { - Test.assertDirectoryExists( + TKit.assertPathExists( cmd.appRuntimeInstallationDirectory(), false); } else { - Test.assertExecutableFileExists(cmd.launcherInstallationPath(), true); + TKit.assertExecutableFileExists(cmd.launcherInstallationPath()); } if (PackageType.WINDOWS.contains(cmd.packageType())) { @@ -356,11 +348,11 @@ } private void verifyPackageUninstalled(JPackageCommand cmd) { - Test.trace(String.format("Verify uninstalled: %s", + TKit.trace(String.format("Verify uninstalled: %s", cmd.getPrintableCommandLine())); if (!cmd.isRuntime()) { - Test.assertPathExists(cmd.launcherInstallationPath(), false); - Test.assertPathExists(cmd.appInstallationDirectory(), false); + TKit.assertPathExists(cmd.launcherInstallationPath(), false); + TKit.assertPathExists(cmd.appInstallationDirectory(), false); } if (PackageType.WINDOWS.contains(cmd.packageType())) { @@ -410,16 +402,15 @@ static { final String propertyName = "output"; - String val = Test.getConfigProperty(propertyName); + String val = TKit.getConfigProperty(propertyName); if (val == null) { bundleOutputDir = null; } else { bundleOutputDir = new File(val).getAbsoluteFile(); if (!bundleOutputDir.isDirectory()) { - throw new IllegalArgumentException(String.format( - "Invalid value of %s sytem property: [%s]. Should be existing directory", - Test.getConfigPropertyName(propertyName), + throw new IllegalArgumentException(String.format("Invalid value of %s sytem property: [%s]. Should be existing directory", + TKit.getConfigPropertyName(propertyName), bundleOutputDir)); } } @@ -427,12 +418,10 @@ static { final String propertyName = "action"; - String action = Optional.ofNullable(Test.getConfigProperty(propertyName)).orElse( + String action = Optional.ofNullable(TKit.getConfigProperty(propertyName)).orElse( Action.CREATE.toString()).toLowerCase(); DEFAULT_ACTION = Stream.of(Action.values()).filter( - a -> a.toString().equals(action)).findFirst().orElseThrow( - () -> new IllegalArgumentException(String.format( - "Unrecognized value of %s property: [%s]", - Test.getConfigPropertyName(propertyName), action))); + a -> a.toString().equals(action)).findFirst().orElseThrow(() -> new IllegalArgumentException(String.format("Unrecognized value of %s property: [%s]", + TKit.getConfigPropertyName(propertyName), action))); } } diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java Mon Sep 30 19:11:19 2019 -0400 @@ -26,7 +26,6 @@ import java.lang.reflect.Method; import java.util.Optional; import java.util.Set; -import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -35,15 +34,15 @@ */ public enum PackageType { WIN_MSI(".msi", - Test.isWindows() ? "jdk.jpackage.internal.WinMsiBundler" : null), + TKit.isWindows() ? "jdk.jpackage.internal.WinMsiBundler" : null), WIN_EXE(".exe", - Test.isWindows() ? "jdk.jpackage.internal.WinMsiBundler" : null), + TKit.isWindows() ? "jdk.jpackage.internal.WinMsiBundler" : null), LINUX_DEB(".deb", - Test.isLinux() ? "jdk.jpackage.internal.LinuxDebBundler" : null), + TKit.isLinux() ? "jdk.jpackage.internal.LinuxDebBundler" : null), LINUX_RPM(".rpm", - Test.isLinux() ? "jdk.jpackage.internal.LinuxRpmBundler" : null), - MAC_DMG(".dmg", Test.isOSX() ? "jdk.jpackage.internal.MacDmgBundler" : null), - MAC_PKG(".pkg", Test.isOSX() ? "jdk.jpackage.internal.MacPkgBundler" : null), + TKit.isLinux() ? "jdk.jpackage.internal.LinuxRpmBundler" : null), + MAC_DMG(".dmg", TKit.isOSX() ? "jdk.jpackage.internal.MacDmgBundler" : null), + MAC_PKG(".pkg", TKit.isOSX() ? "jdk.jpackage.internal.MacPkgBundler" : null), IMAGE("app-image", null, null); PackageType(String packageName, String bundleSuffix, String bundlerClass) { @@ -56,7 +55,7 @@ } if (suffix != null && supported) { - Test.trace(String.format("Bundler %s supported", getName())); + TKit.trace(String.format("Bundler %s supported", getName())); } } @@ -95,16 +94,17 @@ try { Class clazz = Class.forName(bundlerClass); Method supported = clazz.getMethod("supported", boolean.class); - return ((Boolean) supported.invoke(clazz.newInstance(), true)); - } catch (ClassNotFoundException ex) { - return false; + return ((Boolean) supported.invoke( + clazz.getConstructor().newInstance(), true)); + } catch (ClassNotFoundException | IllegalAccessException ex) { } catch (InstantiationException | NoSuchMethodException - | IllegalAccessException | InvocationTargetException ex) { - throw new RuntimeException(ex); + | InvocationTargetException ex) { + Functional.rethrowUnchecked(ex); } + return false; } - private String name; + private final String name; private final String suffix; private final boolean supported; @@ -115,27 +115,11 @@ Stream.concat(LINUX.stream(), WINDOWS.stream()), MAC.stream()).collect(Collectors.toUnmodifiableSet()); - public final static PackageType DEFAULT = ((Supplier) () -> { - if (Test.isLinux()) { - return LINUX.stream().filter(v -> v.isSupported()).findFirst().orElseThrow(); - } - - if (Test.isWindows()) { - return WIN_EXE; - } - - if (Test.isOSX()) { - return MAC_DMG; - } - - throw new IllegalStateException("Unknwon platform"); - }).get(); - private final static class Inner { private final static Set DISABLED_PACKAGERS = Stream.of( Optional.ofNullable( - Test.getConfigProperty("disabledPackagers")).orElse( + TKit.getConfigProperty("disabledPackagers")).orElse( "").split(",")).collect(Collectors.toUnmodifiableSet()); } } diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java Mon Sep 30 19:11:19 2019 -0400 @@ -0,0 +1,652 @@ +/* + * 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.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 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.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; + +final public class TKit { + + public static final Path TEST_SRC_ROOT = Functional.identity(() -> { + Path root = Path.of(System.getProperty("test.src")); + + for (int i = 0; i != 10; ++i) { + if (root.resolve("apps").toFile().isDirectory()) { + return root.toAbsolutePath(); + } + root = root.resolve(".."); + } + + throw new RuntimeException("Failed to locate apps directory"); + }).get(); + + public static void run(String args[], ThrowingRunnable testBody) { + if (currentTest != null) { + throw new IllegalStateException( + "Unexpeced nested or concurrent Test.run() call"); + } + + TestInstance test = new TestInstance(testBody); + ThrowingRunnable.toRunnable(() -> runTests(List.of(test))).run(); + if (!test.passed()) { + throw new RuntimeException(); + } + } + + static void runTests(List tests) { + if (currentTest != null) { + throw new IllegalStateException( + "Unexpeced nested or concurrent Test.run() call"); + } + + try (PrintStream logStream = openLogStream()) { + extraLogStream = logStream; + tests.stream().forEach(test -> { + currentTest = test; + try { + ignoreExceptions(test).run(); + } finally { + currentTest = null; + if (extraLogStream != null) { + extraLogStream.flush(); + } + } + }); + } finally { + extraLogStream = null; + } + } + + static Runnable ignoreExceptions(ThrowingRunnable action) { + return () -> { + try { + try { + action.run(); + } catch (Throwable ex) { + unbox(ex); + } + } catch (Throwable throwable) { + if (extraLogStream != null) { + throwable.printStackTrace(extraLogStream); + } + throwable.printStackTrace(); + } + }; + } + + static void unbox(Throwable throwable) throws Throwable { + try { + throw throwable; + } catch (ExceptionBox | InvocationTargetException ex) { + unbox(ex.getCause()); + } + } + + public static Path workDir() { + Path result = Path.of("."); + String testFunctionName = currentTest.functionName(); + if (testFunctionName != null) { + result = result.resolve(testFunctionName); + } + return result; + } + + static Path defaultInputDir() { + return workDir().resolve("input"); + } + + static Path defaultOutputDir() { + return workDir().resolve("output"); + } + + static String getCurrentDefaultAppName() { + // Construct app name from swapping and joining test base name + // and test function name. + // Say the test name is `FooTest.testBasic`. Then app name would be `BasicFooTest`. + String appNamePrefix = currentTest.functionName(); + if (appNamePrefix != null && appNamePrefix.startsWith("test")) { + appNamePrefix = appNamePrefix.substring("test".length()); + } + return Stream.of(appNamePrefix, currentTest.baseName()).filter( + v -> v != null && !v.isEmpty()).collect(Collectors.joining()); + } + + public static boolean isWindows() { + return (OS.contains("win")); + } + + public static boolean isOSX() { + return (OS.contains("mac")); + } + + public static boolean isLinux() { + return ((OS.contains("nix") || OS.contains("nux"))); + } + + static void log(String v) { + System.out.println(v); + if (extraLogStream != null) { + extraLogStream.println(v); + } + } + + public static void createTextFile(Path propsFilename, Collection 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(); + trace("Done"); + } + + public static void createPropertiesFile(Path propsFilename, + Collection> props) { + trace(String.format("Create [%s] properties file...", + propsFilename.toAbsolutePath().normalize())); + ThrowingRunnable.toRunnable(() -> Files.write(propsFilename, + props.stream().map(e -> String.join("=", e.getKey(), + e.getValue())).peek(TKit::trace).collect(Collectors.toList()))).run(); + trace("Done"); + } + + public static void createPropertiesFile(Path propsFilename, + Map.Entry... props) { + createPropertiesFile(propsFilename, List.of(props)); + } + + public static void createPropertiesFile(Path propsFilename, + Map props) { + createPropertiesFile(propsFilename, props.entrySet()); + } + + public static void trace(String v) { + if (TRACE) { + log("TRACE: " + v); + } + } + + private static void traceAssert(String v) { + if (TRACE_ASSERTS) { + log("TRACE: " + v); + } + } + + public static void error(String v) { + log("ERROR: " + v); + throw new AssertionError(v); + } + + private final static String TEMP_FILE_PREFIX = null; + + private static Path createUniqueFileName(String defaultName) { + final String[] nameComponents; + + int separatorIdx = defaultName.lastIndexOf('.'); + final String baseName; + if (separatorIdx == -1) { + baseName = defaultName; + nameComponents = new String[]{baseName}; + } else { + baseName = defaultName.substring(0, separatorIdx); + nameComponents = new String[]{baseName, defaultName.substring( + separatorIdx + 1)}; + } + + final Path basedir = workDir(); + int i = 0; + for (; i < 100; ++i) { + Path path = basedir.resolve(String.join(".", nameComponents)); + if (!path.toFile().exists()) { + return path; + } + nameComponents[0] = String.format("%s.%d", baseName, i); + } + throw new IllegalStateException(String.format( + "Failed to create unique file name from [%s] basename after %d attempts", + baseName, i)); + } + + public static Path createTempDirectory(String role) throws IOException { + if (role == null) { + return Files.createTempDirectory(workDir(), TEMP_FILE_PREFIX); + } + return Files.createDirectory(createUniqueFileName(role)); + } + + public static Path createTempFile(String role, String suffix) throws + IOException { + if (role == null) { + return Files.createTempFile(workDir(), TEMP_FILE_PREFIX, suffix); + } + return Files.createFile(createUniqueFileName(role)); + } + + public static void withTempFile(String role, String suffix, + ThrowingConsumer action) { + final Path tempFile = ThrowingSupplier.toSupplier(() -> createTempFile( + role, suffix)).get(); + boolean keepIt = true; + try { + ThrowingConsumer.toConsumer(action).accept(tempFile); + keepIt = false; + } finally { + if (tempFile != null && !keepIt) { + ThrowingRunnable.toRunnable(() -> Files.deleteIfExists(tempFile)).run(); + } + } + } + + public static void withTempDirectory(String role, + ThrowingConsumer action) { + final Path tempDir = ThrowingSupplier.toSupplier( + () -> createTempDirectory(role)).get(); + boolean keepIt = true; + try { + ThrowingConsumer.toConsumer(action).accept(tempDir); + keepIt = false; + } finally { + if (tempDir != null && tempDir.toFile().isDirectory() && !keepIt) { + deleteDirectoryRecursive(tempDir, ""); + } + } + } + + /** + * Deletes contents of the given directory recursively. Shortcut for + * deleteDirectoryContentsRecursive(path, null) + * + * @param path path to directory to clean + */ + public static void deleteDirectoryContentsRecursive(Path path) { + deleteDirectoryContentsRecursive(path, null); + } + + /** + * Deletes contents of the given directory recursively. If path is not a + * directory, request is silently ignored. + * + * @param path path to directory to clean + * @param msg log message. If null, the default log message is used. If + * empty string, no log message will be saved. + */ + 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(); + } + } + + /** + * Deletes the given directory recursively. Shortcut for + * deleteDirectoryRecursive(path, null) + * + * @param path path to directory to delete + */ + public static void deleteDirectoryRecursive(Path path) { + deleteDirectoryRecursive(path, null); + } + + /** + * Deletes the given directory recursively. If path is not a + * directory, request is silently ignored. + * + * @param path path to directory to delete + * @param msg log message. If null, the default log message is used. If + * empty string, no log message will be saved. + */ + 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); + } + } + + public static RuntimeException throwUnknownPlatformError() { + if (isWindows() || isLinux() || isOSX()) { + throw new IllegalStateException( + "Platform is known. throwUnknownPlatformError() called by mistake"); + } + throw new IllegalStateException("Unknown platform"); + } + + static void waitForFileCreated(Path fileToWaitFor, + long timeoutSeconds) throws IOException { + + trace(String.format("Wait for file [%s] to be available", fileToWaitFor)); + + WatchService ws = FileSystems.getDefault().newWatchService(); + + Path watchDirectory = fileToWaitFor.toAbsolutePath().getParent(); + watchDirectory.register(ws, ENTRY_CREATE, ENTRY_MODIFY); + + long waitUntil = System.currentTimeMillis() + timeoutSeconds * 1000; + for (;;) { + long timeout = waitUntil - System.currentTimeMillis(); + assertTrue(timeout > 0, String.format( + "Check timeout value %d is positive", timeout)); + + WatchKey key = ThrowingSupplier.toSupplier(() -> ws.poll(timeout, + TimeUnit.MILLISECONDS)).get(); + if (key == null) { + if (fileToWaitFor.toFile().exists()) { + trace(String.format( + "File [%s] is available after poll timeout expired", + fileToWaitFor)); + return; + } + assertUnexpected(String.format("Timeout expired", timeout)); + } + + for (WatchEvent event : key.pollEvents()) { + if (event.kind() == StandardWatchEventKinds.OVERFLOW) { + continue; + } + Path contextPath = (Path) event.context(); + if (Files.isSameFile(watchDirectory.resolve(contextPath), + fileToWaitFor)) { + trace(String.format("File [%s] is available", fileToWaitFor)); + return; + } + } + + if (!key.reset()) { + assertUnexpected("Watch key invalidated"); + } + } + } + + private static String concatMessages(String msg, String msg2) { + if (msg2 != null && !msg2.isBlank()) { + return msg + ": " + msg2; + } + return msg; + } + + public static void assertEquals(long expected, long actual, String msg) { + currentTest.notifyAssert(); + if (expected != actual) { + error(concatMessages(String.format( + "Expected [%d]. Actual [%d]", expected, actual), + msg)); + } + + traceAssert(String.format("assertEquals(%d): %s", expected, msg)); + } + + public static void assertNotEquals(long expected, long actual, String msg) { + currentTest.notifyAssert(); + if (expected == actual) { + error(concatMessages(String.format("Unexpected [%d] value", actual), + msg)); + } + + traceAssert(String.format("assertNotEquals(%d, %d): %s", expected, + actual, msg)); + } + + public static void assertEquals(String expected, String actual, String msg) { + currentTest.notifyAssert(); + if ((actual != null && !actual.equals(expected)) + || (expected != null && !expected.equals(actual))) { + error(concatMessages(String.format( + "Expected [%s]. Actual [%s]", expected, actual), + msg)); + } + + traceAssert(String.format("assertEquals(%s): %s", expected, msg)); + } + + public static void assertNotEquals(String expected, String actual, String msg) { + currentTest.notifyAssert(); + if ((actual != null && !actual.equals(expected)) + || (expected != null && !expected.equals(actual))) { + + traceAssert(String.format("assertNotEquals(%s, %s): %s", expected, + actual, msg)); + return; + } + + error(concatMessages(String.format("Unexpected [%s] value", actual), msg)); + } + + public static void assertNull(Object value, String msg) { + currentTest.notifyAssert(); + if (value != null) { + error(concatMessages(String.format("Unexpected not null value [%s]", + value), msg)); + } + + traceAssert(String.format("assertNull(): %s", msg)); + } + + public static void assertNotNull(Object value, String msg) { + currentTest.notifyAssert(); + if (value == null) { + error(concatMessages("Unexpected null value", msg)); + } + + traceAssert(String.format("assertNotNull(%s): %s", value, msg)); + } + + public static void assertTrue(boolean actual, String msg) { + currentTest.notifyAssert(); + if (!actual) { + error(concatMessages("Unexpected FALSE", msg)); + } + + traceAssert(String.format("assertTrue(): %s", msg)); + } + + public static void assertFalse(boolean actual, String msg) { + currentTest.notifyAssert(); + if (actual) { + error(concatMessages("Unexpected TRUE", msg)); + } + + traceAssert(String.format("assertFalse(): %s", msg)); + } + + public static void assertPathExists(Path path, boolean exists) { + if (exists) { + assertTrue(path.toFile().exists(), String.format( + "Check [%s] path exists", path)); + } else { + assertFalse(path.toFile().exists(), String.format( + "Check [%s] path doesn't exist", path)); + } + } + + public static void assertDirectoryExists(Path path) { + assertPathExists(path, true); + assertTrue(path.toFile().isDirectory(), String.format( + "Check [%s] is a directory", path)); + } + + public static void assertFileExists(Path path) { + assertPathExists(path, true); + assertTrue(path.toFile().isFile(), String.format("Check [%s] is a file", + path)); + } + + public static void assertExecutableFileExists(Path path) { + assertFileExists(path); + assertTrue(path.toFile().canExecute(), String.format( + "Check [%s] file is executable", path)); + } + + public static void assertReadableFileExists(Path path) { + assertFileExists(path); + assertTrue(path.toFile().canRead(), String.format( + "Check [%s] file is readable", path)); + } + + public static void assertUnexpected(String msg) { + currentTest.notifyAssert(); + error(concatMessages("Unexpected", msg)); + } + + public static void assertStringListEquals(List expected, + List actual, String msg) { + currentTest.notifyAssert(); + + traceAssert(String.format("assertStringListEquals(): %s", msg)); + + String idxFieldFormat = Functional.identity(() -> { + int listSize = expected.size(); + int width = 0; + while (listSize != 0) { + listSize = listSize / 10; + width++; + } + return "%" + width + "d"; + }).get(); + + AtomicInteger counter = new AtomicInteger(0); + Iterator actualIt = actual.iterator(); + expected.stream().sequential().filter(expectedStr -> actualIt.hasNext()).forEach(expectedStr -> { + int idx = counter.incrementAndGet(); + String actualStr = actualIt.next(); + + if ((actualStr != null && !actualStr.equals(expectedStr)) + || (expectedStr != null && !expectedStr.equals(actualStr))) { + error(concatMessages(String.format( + "(" + idxFieldFormat + ") Expected [%s]. Actual [%s]", + idx, expectedStr, actualStr), msg)); + } + + traceAssert(String.format( + "assertStringListEquals(" + idxFieldFormat + ", %s)", idx, + expectedStr)); + }); + + if (expected.size() < actual.size()) { + // Actual string list is longer than expected + error(concatMessages(String.format( + "Actual list is longer than expected by %d elements", + actual.size() - expected.size()), msg)); + } + + if (actual.size() < expected.size()) { + // Actual string list is shorter than expected + error(concatMessages(String.format( + "Actual list is longer than expected by %d elements", + expected.size() - actual.size()), msg)); + } + } + + private static PrintStream openLogStream() { + if (LOG_FILE == null) { + return null; + } + + return ThrowingSupplier.toSupplier(() -> new PrintStream( + new FileOutputStream(LOG_FILE.toFile(), true))).get(); + } + + private static TestInstance currentTest; + private static PrintStream extraLogStream; + + private static final boolean TRACE; + private static final boolean TRACE_ASSERTS; + + static final boolean VERBOSE_JPACKAGE; + static final boolean VERBOSE_TEST_SETUP; + + static String getConfigProperty(String propertyName) { + return System.getProperty(getConfigPropertyName(propertyName)); + } + + static String getConfigPropertyName(String propertyName) { + return "jpackage.test." + propertyName; + } + + static final Path LOG_FILE = Functional.identity(() -> { + String val = getConfigProperty("logfile"); + if (val == null) { + return null; + } + return Path.of(val); + }).get(); + + static { + String val = getConfigProperty("suppress-logging"); + if (val == null) { + TRACE = true; + TRACE_ASSERTS = true; + VERBOSE_JPACKAGE = true; + VERBOSE_TEST_SETUP = true; + } else if ("all".equals(val.toLowerCase())) { + 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"); + } + } + + private static final String OS = System.getProperty("os.name").toLowerCase(); +} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Test.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Test.java Mon Sep 30 15:59:50 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,554 +0,0 @@ -/* - * 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.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardWatchEventKinds; -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.Collection; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import jdk.jpackage.test.Functional.ThrowingConsumer; -import jdk.jpackage.test.Functional.ThrowingRunnable; -import jdk.jpackage.test.Functional.ThrowingSupplier; - -final public class Test { - - public static final Path TEST_SRC_ROOT = new Supplier() { - @Override - public Path get() { - Path root = Path.of(System.getProperty("test.src")); - - for (int i = 0; i != 10; ++i) { - if (root.resolve("apps").toFile().isDirectory()) { - return root.toAbsolutePath(); - } - root = root.resolve(".."); - } - - throw new RuntimeException("Failed to locate apps directory"); - } - }.get(); - - private static class Instance implements AutoCloseable { - Instance(String args[]) { - assertCount = 0; - - name = enclosingMainMethodClass().getSimpleName(); - extraLogStream = openLogStream(); - - currentTest = this; - - log(String.format("[ RUN ] %s", name)); - } - - @Override - public void close() { - log(String.format("%s %s; checks=%d", - success ? "[ OK ]" : "[ FAILED ]", name, assertCount)); - - if (extraLogStream != null) { - extraLogStream.close(); - } - } - - void notifyAssert() { - assertCount++; - } - - void notifySuccess() { - success = true; - } - - private int assertCount; - private boolean success; - private final String name; - private final PrintStream extraLogStream; - } - - public static void run(String args[], TestBody action) { - if (currentTest != null) { - throw new IllegalStateException( - "Unexpeced nested or concurrent Test.run() call"); - } - - try (Instance instance = new Instance(args)) { - action.run(); - instance.notifySuccess(); - } catch (Exception ex) { - throw new RuntimeException(ex); - } finally { - currentTest = null; - } - } - - public static interface TestBody { - public void run() throws Exception; - } - - public static Path workDir() { - return Path.of("."); - } - - static Path defaultInputDir() { - return workDir().resolve("input"); - } - - static Path defaultOutputDir() { - return workDir().resolve("output"); - } - - static Class enclosingMainMethodClass() { - StackTraceElement st[] = Thread.currentThread().getStackTrace(); - for (StackTraceElement ste : st) { - if ("main".equals(ste.getMethodName())) { - try { - return Class.forName(ste.getClassName()); - } catch (ClassNotFoundException ex) { - throw new RuntimeException(ex); - } - } - } - return null; - } - - static boolean isWindows() { - return (OS.contains("win")); - } - - static boolean isOSX() { - return (OS.contains("mac")); - } - - static boolean isLinux() { - return ((OS.contains("nix") || OS.contains("nux"))); - } - - static private void log(String v) { - System.out.println(v); - if (currentTest != null && currentTest.extraLogStream != null) { - currentTest.extraLogStream.println(v); - } - } - - public static Class getTestClass () { - return enclosingMainMethodClass(); - } - - public static void createPropertiesFile(Path propsFilename, - Collection> props) { - trace(String.format("Create [%s] properties file...", - propsFilename.toAbsolutePath().normalize())); - try { - Files.write(propsFilename, props.stream().peek(e -> trace( - String.format("%s=%s", e.getKey(), e.getValue()))).map( - e -> String.format("%s=%s", e.getKey(), e.getValue())).collect( - Collectors.toList())); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - trace("Done"); - } - - public static void createPropertiesFile(Path propsFilename, - Map.Entry... props) { - createPropertiesFile(propsFilename, List.of(props)); - } - - public static void createPropertiesFile(Path propsFilename, - Map props) { - createPropertiesFile(propsFilename, props.entrySet()); - } - - public static void trace(String v) { - if (TRACE) { - log("TRACE: " + v); - } - } - - private static void traceAssert(String v) { - if (TRACE_ASSERTS) { - log("TRACE: " + v); - } - } - - public static void error(String v) { - log("ERROR: " + v); - throw new AssertionError(v); - } - - private static final String TEMP_FILE_PREFIX = null; - - public static Path createTempDirectory() throws IOException { - return Files.createTempDirectory(workDir(), TEMP_FILE_PREFIX); - } - - public static Path createTempFile(String suffix) throws IOException { - return Files.createTempFile(workDir(), TEMP_FILE_PREFIX, suffix); - } - - public static void withTempFile(String suffix, ThrowingConsumer action) { - final Path tempFile = ThrowingSupplier.toSupplier(() -> createTempFile( - suffix)).get(); - boolean keepIt = true; - try { - ThrowingConsumer.toConsumer(action).accept(tempFile); - keepIt = false; - } finally { - if (tempFile != null && !keepIt) { - ThrowingRunnable.toRunnable(() -> Files.deleteIfExists(tempFile)).run(); - } - } - } - - public static void withTempDirectory(ThrowingConsumer action) { - final Path tempDir = ThrowingSupplier.toSupplier( - () -> createTempDirectory()).get(); - boolean keepIt = true; - try { - ThrowingConsumer.toConsumer(action).accept(tempDir); - keepIt = false; - } finally { - if (tempDir != null && tempDir.toFile().isDirectory() && !keepIt) { - deleteDirectoryRecursive(tempDir); - } - } - } - - static void deleteDirectoryRecursive(Path path) { - ThrowingRunnable.toRunnable(() -> Files.walk(path).sorted( - Comparator.reverseOrder()).map(Path::toFile).forEach( - File::delete)).run(); - } - - static void waitForFileCreated(Path fileToWaitFor, - long timeoutSeconds) throws IOException { - - trace(String.format("Wait for file [%s] to be available", fileToWaitFor)); - - WatchService ws = FileSystems.getDefault().newWatchService(); - - Path watchDirectory = fileToWaitFor.toAbsolutePath().getParent(); - watchDirectory.register(ws, ENTRY_CREATE, ENTRY_MODIFY); - - long waitUntil = System.currentTimeMillis() + timeoutSeconds * 1000; - for (;;) { - long timeout = waitUntil - System.currentTimeMillis(); - assertTrue(timeout > 0, String.format( - "Check timeout value %d is positive", timeout)); - - WatchKey key = null; - try { - key = ws.poll(timeout, TimeUnit.MILLISECONDS); - } catch (InterruptedException ex) { - throw new RuntimeException(ex); - } - - if (key == null) { - if (fileToWaitFor.toFile().exists()) { - trace(String.format( - "File [%s] is available after poll timeout expired", - fileToWaitFor)); - return; - } - assertUnexpected(String.format("Timeout expired", timeout)); - } - - for (WatchEvent event : key.pollEvents()) { - if (event.kind() == StandardWatchEventKinds.OVERFLOW) { - continue; - } - Path contextPath = (Path) event.context(); - if (Files.isSameFile(watchDirectory.resolve(contextPath), - fileToWaitFor)) { - trace(String.format("File [%s] is available", fileToWaitFor)); - return; - } - } - - if (!key.reset()) { - assertUnexpected("Watch key invalidated"); - } - } - } - - private static String concatMessages(String msg, String msg2) { - if (msg2 != null && !msg2.isBlank()) { - return msg + ": " + msg2; - } - return msg; - } - - public static void assertEquals(long expected, long actual, String msg) { - currentTest.notifyAssert(); - if (expected != actual) { - error(concatMessages(String.format( - "Expected [%d]. Actual [%d]", expected, actual), - msg)); - } - - traceAssert(String.format("assertEquals(%d): %s", expected, msg)); - } - - public static void assertNotEquals(long expected, long actual, String msg) { - currentTest.notifyAssert(); - if (expected == actual) { - error(concatMessages(String.format("Unexpected [%d] value", actual), - msg)); - } - - traceAssert(String.format("assertNotEquals(%d, %d): %s", expected, - actual, msg)); - } - - public static void assertEquals(String expected, String actual, String msg) { - currentTest.notifyAssert(); - if ((actual != null && !actual.equals(expected)) - || (expected != null && !expected.equals(actual))) { - error(concatMessages(String.format( - "Expected [%s]. Actual [%s]", expected, actual), - msg)); - } - - traceAssert(String.format("assertEquals(%s): %s", expected, msg)); - } - - public static void assertNotEquals(String expected, String actual, String msg) { - currentTest.notifyAssert(); - if ((actual != null && !actual.equals(expected)) - || (expected != null && !expected.equals(actual))) { - - traceAssert(String.format("assertNotEquals(%s, %s): %s", expected, - actual, msg)); - return; - } - - error(concatMessages(String.format("Unexpected [%s] value", actual), msg)); - } - - public static void assertNull(Object value, String msg) { - currentTest.notifyAssert(); - if (value != null) { - error(concatMessages(String.format("Unexpected not null value [%s]", - value), msg)); - } - - traceAssert(String.format("assertNull(): %s", msg)); - } - - public static void assertNotNull(Object value, String msg) { - currentTest.notifyAssert(); - if (value == null) { - error(concatMessages("Unexpected null value", msg)); - } - - traceAssert(String.format("assertNotNull(%s): %s", value, msg)); - } - - public static void assertTrue(boolean actual, String msg) { - currentTest.notifyAssert(); - if (!actual) { - error(concatMessages("Unexpected FALSE", msg)); - } - - traceAssert(String.format("assertTrue(): %s", msg)); - } - - public static void assertFalse(boolean actual, String msg) { - currentTest.notifyAssert(); - if (actual) { - error(concatMessages("Unexpected TRUE", msg)); - } - - traceAssert(String.format("assertFalse(): %s", msg)); - } - - public static void assertPathExists(Path path, boolean exists) { - if (exists) { - assertTrue(path.toFile().exists(), String.format( - "Check [%s] path exists", path)); - } else { - assertFalse(path.toFile().exists(), String.format( - "Check [%s] path doesn't exist", path)); - } - } - - public static void assertDirectoryExists(Path path, boolean exists) { - assertPathExists(path, exists); - if (exists) { - assertTrue(path.toFile().isDirectory(), String.format( - "Check [%s] is a directory", path)); - } - } - - public static void assertFileExists(Path path, boolean exists) { - assertPathExists(path, exists); - if (exists) { - assertTrue(path.toFile().isFile(), String.format( - "Check [%s] is a file", path)); - } - } - - public static void assertExecutableFileExists(Path path, boolean exists) { - assertFileExists(path, exists); - if (exists) { - assertTrue(path.toFile().canExecute(), String.format( - "Check [%s] file is executable", path)); - } - } - - public static void assertReadableFileExists(Path path) { - assertFileExists(path, true); - assertTrue(path.toFile().canRead(), String.format( - "Check [%s] file is readable", path)); - } - - public static void assertUnexpected(String msg) { - currentTest.notifyAssert(); - error(concatMessages("Unexpected", msg)); - } - - public static void assertStringListEquals(List expected, - List actual, String msg) { - currentTest.notifyAssert(); - - if (expected.size() < actual.size()) { - // Actual string list is longer than expected - error(concatMessages(String.format( - "Actual list is longer than expected by %d elements", - actual.size() - expected.size()), msg)); - } - - if (actual.size() < expected.size()) { - // Actual string list is shorter than expected - error(concatMessages(String.format( - "Actual list is longer than expected by %d elements", - expected.size() - actual.size()), msg)); - } - - traceAssert(String.format("assertStringListEquals(): %s", msg)); - - String idxFieldFormat = Functional.identity(() -> { - int listSize = expected.size(); - int width = 0; - while (listSize != 0) { - listSize = listSize / 10; - width++; - } - return "%" + width + "d"; - }).get(); - - AtomicInteger counter = new AtomicInteger(0); - Iterator actualIt = actual.iterator(); - expected.stream().sequential().filter(expectedStr -> actualIt.hasNext()).forEach(expectedStr -> { - int idx = counter.incrementAndGet(); - String actualStr = actualIt.next(); - - if ((actualStr != null && !actualStr.equals(expectedStr)) - || (expectedStr != null && !expectedStr.equals(actualStr))) { - error(concatMessages(String.format( - "(" + idxFieldFormat + ") Expected [%s]. Actual [%s]", - idx, expectedStr, actualStr), msg)); - } - - traceAssert(String.format( - "assertStringListEquals(" + idxFieldFormat + ", %s)", idx, - expectedStr)); - }); - } - - private static PrintStream openLogStream() { - if (LOG_FILE == null) { - return null; - } - - try { - return new PrintStream(new FileOutputStream(LOG_FILE.toFile(), true)); - } catch (FileNotFoundException ex) { - throw new RuntimeException(ex); - } - } - - private static Instance currentTest; - - private static final boolean TRACE; - private static final boolean TRACE_ASSERTS; - - static final boolean VERBOSE_JPACKAGE; - - static String getConfigProperty(String propertyName) { - return System.getProperty(getConfigPropertyName(propertyName)); - } - - static String getConfigPropertyName(String propertyName) { - return "jpackage.test." + propertyName; - } - - static final Path LOG_FILE = Functional.identity(() -> { - String val = getConfigProperty("logfile"); - if (val == null) { - return null; - } - return Path.of(val); - }).get(); - - static { - String val = getConfigProperty("suppress-logging"); - if (val == null) { - TRACE = true; - TRACE_ASSERTS = true; - VERBOSE_JPACKAGE = true; - } else if ("all".equals(val.toLowerCase())) { - TRACE = false; - TRACE_ASSERTS = false; - VERBOSE_JPACKAGE = 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")); - } - } - - private static final String OS = System.getProperty("os.name").toLowerCase(); -} \ No newline at end of file diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java Mon Sep 30 19:11:19 2019 -0400 @@ -0,0 +1,344 @@ +/* + * 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.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import jdk.jpackage.test.Annotations.Parameter; +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); + } + + TestBuilder(Consumer testConsumer) { + argProcessors = Map.of(CMDLINE_ARG_PREFIX + "after-run", + arg -> getJavaMethodsFromArg(arg).forEach( + (method) -> afterActions.add(wrap(method, dryRun))), + CMDLINE_ARG_PREFIX + "before-run", + arg -> getJavaMethodsFromArg(arg).forEach( + (method) -> beforeActions.add(wrap(method, dryRun))), + CMDLINE_ARG_PREFIX + "run", + arg -> flushTestGroup(getJavaMethodsFromArg(arg).map( + TestBuilder::toMethodCalls).flatMap(List::stream).collect( + Collectors.toList())), + CMDLINE_ARG_PREFIX + "dry-run", + arg -> dryRun = true); + this.testConsumer = testConsumer; + clear(); + } + + void processCmdLineArg(String arg) throws Throwable { + int separatorIdx = arg.indexOf('='); + final String argName; + final String argValue; + if (separatorIdx != -1) { + argName = arg.substring(0, separatorIdx); + argValue = arg.substring(separatorIdx + 1); + } else { + argName = arg; + argValue = null; + } + try { + ThrowingConsumer argProcessor = argProcessors.get(argName); + if (argProcessor == null) { + throw new ParseException("Unrecognized"); + } + argProcessor.accept(argValue); + } catch (ParseException ex) { + ex.setContext(arg); + throw ex; + } + } + + private void flushTestGroup(List newTestGroup) { + if (testGroup != null) { + testGroup.forEach(testBody -> createTestInstance(testBody)); + clear(); + } + testGroup = newTestGroup; + } + + private void createTestInstance(MethodCall testBody) { + ThrowingFunction testContructor; + if (dryRun) { + testContructor = (unused) -> null; + testBody = DRY_RUN_TEST_BODY; + } else { + testContructor = TestBuilder::constructTest; + } + + TestInstance test = new TestInstance(testContructor, testBody, + beforeActions, afterActions); + trace(String.format("[%s] test constructed", 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<>(); + testGroup = null; + } + + private static Class probeClass(String name) { + try { + return Class.forName(name); + } catch (ClassNotFoundException ex) { + return null; + } + } + + private static Stream cmdLineArgValueToMethodNames(String v) { + List result = new ArrayList<>(); + String defaultClassName = null; + for (String token : v.split(",")) { + Class testSet = probeClass(token); + if (testSet != null) { + // Test set class specified. Pull in all public methods + // from the class with @Test annotation removing name duplicates. + // Overloads will be handled at the next phase of processing. + defaultClassName = token; + Stream.of(testSet.getMethods()).filter( + m -> m.isAnnotationPresent(Test.class)).map( + Method::getName).distinct().forEach( + name -> result.add(String.join(".", token, name))); + continue; + } + + final String qualifiedMethodName; + final int lastDotIdx = token.lastIndexOf('.'); + if (lastDotIdx != -1) { + qualifiedMethodName = token; + defaultClassName = token.substring(0, lastDotIdx); + } else if (defaultClassName == null) { + throw new ParseException("Default class name not found in"); + } else { + qualifiedMethodName = String.join(".", defaultClassName, token); + } + result.add(qualifiedMethodName); + } + return result.stream(); + } + + private static boolean filterMethod(String expectedMethodName, Method method) { + if (!method.getName().equals(expectedMethodName)) { + return false; + } + switch (method.getParameterCount()) { + case 0: + return !isParametrized(method); + case 1: + return isParametrized(method); + } + return false; + } + + private static boolean isParametrized(Method method) { + return method.isAnnotationPresent(Parameters.class) || method.isAnnotationPresent( + Parameter.class); + } + + private static List getJavaMethodFromString( + String qualifiedMethodName) { + int lastDotIdx = qualifiedMethodName.lastIndexOf('.'); + if (lastDotIdx == -1) { + throw new ParseException("Class name not found in"); + } + String className = qualifiedMethodName.substring(0, lastDotIdx); + String methodName = qualifiedMethodName.substring(lastDotIdx + 1); + Class methodClass; + try { + methodClass = Class.forName(className); + } catch (ClassNotFoundException ex) { + throw new ParseException(String.format("Class [%s] not found;", + className)); + } + // Get the list of all public methods as need to deal with overloads. + List methods = Stream.of(methodClass.getMethods()).filter( + (m) -> filterMethod(methodName, m)).collect(Collectors.toList()); + if (methods.isEmpty()) { + new ParseException(String.format( + "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; + } + + private static Stream getJavaMethodsFromArg(String argValue) { + return cmdLineArgValueToMethodNames(argValue).map( + ThrowingFunction.toFunction( + TestBuilder::getJavaMethodFromString)).flatMap( + List::stream).sequential(); + } + + private static Parameter[] getParameters(Method method) { + if (method.isAnnotationPresent(Parameters.class)) { + return ((Parameters) method.getAnnotation(Parameters.class)).value(); + } + + if (method.isAnnotationPresent(Parameter.class)) { + return new Parameter[]{(Parameter) method.getAnnotation( + Parameter.class)}; + } + + // Unexpected + return null; + } + + private static List toMethodCalls(Method method) { + if (!isParametrized(method)) { + return List.of(new MethodCall(method)); + } + Parameter[] annotations = getParameters(method); + if (annotations.length == 0) { + return List.of(new MethodCall(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()); + } + + private static Object fromString(String value, Class toType) { + Function converter = conv.get(toType); + if (converter == null) { + throw new RuntimeException(String.format( + "Failed to find a conversion of [%s] string to %s type", + value, toType)); + } + return converter.apply(value); + } + + // Wraps Method.invike() into ThrowingRunnable.run() + private static ThrowingConsumer wrap(Method method, boolean dryRun) { + return (test) -> { + Class methodClass = method.getDeclaringClass(); + String methodName = String.join(".", methodClass.getName(), + method.getName()); + TKit.log(String.format("[ CALL ] %s()", methodName)); + if (!dryRun) { + if (methodClass.isInstance(test)) { + method.invoke(test); + } else { + method.invoke(null); + } + } + }; + } + + private static class ParseException extends IllegalArgumentException { + + ParseException(String msg) { + super(msg); + } + + void setContext(String badCmdLineArg) { + this.badCmdLineArg = badCmdLineArg; + } + + @Override + public String getMessage() { + String msg = super.getMessage(); + if (badCmdLineArg != null) { + msg = String.format("%s parameter=[%s]", msg, badCmdLineArg); + } + return msg; + } + private String badCmdLineArg; + } + + private static void trace(String msg) { + if (TKit.VERBOSE_TEST_SETUP) { + TKit.log(msg); + } + } + + private final Map> argProcessors; + private Consumer testConsumer; + private List testGroup; + private List beforeActions; + private List afterActions; + private boolean dryRun; + + private final static Map> conv = Map.of( + boolean.class, Boolean::valueOf, + Boolean.class, Boolean::valueOf, + int.class, Integer::valueOf, + Integer.class, Integer::valueOf, + long.class, Long::valueOf, + Long.class, Long::valueOf, + String.class, String::valueOf); + + final static String CMDLINE_ARG_PREFIX = "--jpt-"; +} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java Mon Sep 30 19:11:19 2019 -0400 @@ -0,0 +1,160 @@ +/* + * 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.lang.reflect.Method; +import java.nio.file.Files; +import java.util.Collections; +import java.util.List; +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 { + + static class TestDesc { + private TestDesc() { + } + + String testFullName() { + StringBuilder sb = new StringBuilder(); + sb.append(clazz.getSimpleName()); + if (functionName != null) { + sb.append('.'); + sb.append(functionName); + if (args != null) { + sb.append('(').append(args).append(')'); + } + } + return sb.toString(); + } + + private Class clazz; + private String functionName; + private String args; + + private static TestDesc create() { + TestDesc desc = new TestDesc(); + desc.clazz = enclosingMainMethodClass(); + return desc; + } + + static TestDesc create(Method m, Object... args) { + TestDesc desc = new TestDesc(); + desc.clazz = m.getDeclaringClass(); + desc.functionName = m.getName(); + if (args.length != 0) { + desc.args = Stream.of(args).map(Object::toString).collect( + Collectors.joining(",")); + } + return desc; + } + } + + TestInstance(ThrowingRunnable testBody) { + assertCount = 0; + this.testConstructor = (unused) -> null; + this.testBody = (unused) -> testBody.run(); + this.beforeActions = Collections.emptyList(); + this.afterActions = Collections.emptyList(); + this.testDesc = TestDesc.create(); + } + + TestInstance(ThrowingFunction testConstructor, MethodCall testBody, + List beforeActions, + List afterActions) { + assertCount = 0; + this.testConstructor = testConstructor; + this.testBody = testBody; + this.beforeActions = beforeActions; + this.afterActions = afterActions; + this.testDesc = testBody.createDescription(); + } + + void notifyAssert() { + assertCount++; + } + + boolean passed() { + return success; + } + + String functionName() { + return testDesc.functionName; + } + + String baseName() { + return testDesc.clazz.getSimpleName(); + } + + String fullName() { + return testDesc.testFullName(); + } + + @Override + public void run() throws Throwable { + final String fullName = testDesc.testFullName(); + TKit.log(String.format("[ RUN ] %s", fullName)); + try { + Object testInstance = testConstructor.apply(testBody); + beforeActions.forEach((a) -> ThrowingConsumer.toConsumer(a).accept( + testInstance)); + Files.createDirectories(TKit.workDir()); + try { + testBody.accept(testInstance); + } finally { + afterActions.forEach(a -> TKit.ignoreExceptions(() -> a.accept( + testInstance))); + } + success = true; + } finally { + TKit.log(String.format("%s %s; checks=%d", + success ? "[ OK ]" : "[ FAILED ]", fullName, + assertCount)); + } + } + + private static Class enclosingMainMethodClass() { + StackTraceElement st[] = Thread.currentThread().getStackTrace(); + for (StackTraceElement ste : st) { + if ("main".equals(ste.getMethodName())) { + return Functional.ThrowingSupplier.toSupplier(() -> Class.forName( + ste.getClassName())).get(); + } + } + return null; + } + + private int assertCount; + private boolean success; + private final TestDesc testDesc; + private final ThrowingFunction testConstructor; + private final ThrowingConsumer testBody; + private final List beforeActions; + private final List afterActions; +} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java Mon Sep 30 19:11:19 2019 -0400 @@ -25,9 +25,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -83,16 +81,24 @@ return Path.of(cmd.name() + ".lnk"); } + private void verifyShortcut(Path path, boolean exists) { + if (exists) { + TKit.assertFileExists(path); + } else { + TKit.assertPathExists(path, false); + } + } + private void verifySystemDesktopShortcut(boolean exists) { Path dir = Path.of(queryRegistryValueCache( SYSTEM_SHELL_FOLDERS_REGKEY, "Common Desktop")); - Test.assertFileExists(dir.resolve(desktopShortcutPath()), exists); + verifyShortcut(dir.resolve(desktopShortcutPath()), exists); } private void verifyUserLocalDesktopShortcut(boolean exists) { Path dir = Path.of( queryRegistryValueCache(USER_SHELL_FOLDERS_REGKEY, "Desktop")); - Test.assertFileExists(dir.resolve(desktopShortcutPath()), exists); + verifyShortcut(dir.resolve(desktopShortcutPath()), exists); } private void verifyStartMenuShortcut() { @@ -119,13 +125,13 @@ private void verifySystemStartMenuShortcut(boolean exists) { Path dir = Path.of(queryRegistryValueCache( SYSTEM_SHELL_FOLDERS_REGKEY, "Common Programs")); - Test.assertFileExists(dir.resolve(startMenuShortcutPath()), exists); + verifyShortcut(dir.resolve(startMenuShortcutPath()), exists); } private void verifyUserLocalStartMenuShortcut(boolean exists) { Path dir = Path.of(queryRegistryValueCache( USER_SHELL_FOLDERS_REGKEY, "Programs")); - Test.assertFileExists(dir.resolve(startMenuShortcutPath()), exists); + verifyShortcut(dir.resolve(startMenuShortcutPath()), exists); } private void verifyFileAssociationsRegistry() { @@ -136,7 +142,7 @@ private void verifyFileAssociationsRegistry(Path faFile) { boolean appInstalled = cmd.launcherInstallationPath().toFile().exists(); try { - Test.trace(String.format( + TKit.trace(String.format( "Get file association properties from [%s] file", faFile)); Map faProps = Files.readAllLines(faFile).stream().filter( @@ -150,10 +156,10 @@ entry -> entry.getValue())); String suffix = faProps.get("extension"); String contentType = faProps.get("mime-type"); - Test.assertNotNull(suffix, String.format( + TKit.assertNotNull(suffix, String.format( "Check file association suffix [%s] is found in [%s] property file", suffix, faFile)); - Test.assertNotNull(contentType, String.format( + TKit.assertNotNull(contentType, String.format( "Check file association content type [%s] is found in [%s] property file", contentType, faFile)); verifyFileAssociations(appInstalled, "." + suffix, contentType); @@ -172,14 +178,14 @@ "Extension"); if (exists) { - Test.assertEquals(suffix, suffixFromRegistry, + TKit.assertEquals(suffix, suffixFromRegistry, "Check suffix in registry is as expected"); - Test.assertEquals(contentType, contentTypeFromRegistry, + TKit.assertEquals(contentType, contentTypeFromRegistry, "Check content type in registry is as expected"); } else { - Test.assertNull(suffixFromRegistry, + TKit.assertNull(suffixFromRegistry, "Check suffix in registry not found"); - Test.assertNull(contentTypeFromRegistry, + TKit.assertNull(contentTypeFromRegistry, "Check content type in registry not found"); } } @@ -200,7 +206,7 @@ () -> new RuntimeException(String.format( "Failed to find [%s] string in the output", lookupString))); - Test.trace(String.format( + TKit.trace(String.format( "Registry value [%s] at [%s] path not found", valueName, keyPath)); return null; @@ -211,7 +217,7 @@ // Common Desktop REG_SZ C:\Users\Public\Desktop value = value.split(" REG_SZ ")[1]; - Test.trace(String.format("Registry value [%s] at [%s] path is [%s]", + TKit.trace(String.format("Registry value [%s] at [%s] path is [%s]", valueName, keyPath, value)); return value; @@ -229,6 +235,9 @@ return value; } + static final Set CRITICAL_RUNTIME_FILES = Set.of(Path.of( + "bin\\server\\jvm.dll")); + // jtreg resets %ProgramFiles% environment variable by some reason. private final static Path PROGRAM_FILES = Path.of(Optional.ofNullable( System.getenv("ProgramFiles")).orElse("C:\\Program Files")); diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/junit/jdk/jpackage/internal/ApplicationLayoutTest.java --- a/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/ApplicationLayoutTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/ApplicationLayoutTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -57,7 +57,7 @@ @Test public void testLinux() throws IOException { fillLinuxAppImage(); - testApplicationLayout(ApplicationLayout.linuxApp()); + testApplicationLayout(ApplicationLayout.linuxAppImage()); } private void testApplicationLayout(ApplicationLayout layout) throws IOException { diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/linux/AppCategoryTest.java --- a/test/jdk/tools/jpackage/linux/AppCategoryTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/linux/AppCategoryTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -21,7 +21,7 @@ * questions. */ -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; @@ -44,6 +44,7 @@ * @test * @summary jpackage with --linux-app-category * @library ../helpers + * @build jdk.jpackage.test.* * @requires (os.family == "linux") * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m AppCategoryTest @@ -53,7 +54,7 @@ public static void main(String[] args) { final String CATEGORY = "Foo"; - Test.run(args, () -> { + TKit.run(args, () -> { new PackageTest() .forTypes(PackageType.LINUX) .configureHelloApp() diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/linux/LicenseTypeTest.java --- a/test/jdk/tools/jpackage/linux/LicenseTypeTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/linux/LicenseTypeTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -21,7 +21,7 @@ * questions. */ -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; @@ -39,6 +39,7 @@ * @test * @summary jpackage with --linux-rpm-license-type * @library ../helpers + * @build jdk.jpackage.test.* * @requires (os.family == "linux") * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m LicenseTypeTest @@ -48,7 +49,7 @@ public static void main(String[] args) { final String LICENSE_TYPE = "JP_LICENSE_TYPE"; - Test.run(args, () -> { + TKit.run(args, () -> { new PackageTest().forTypes(PackageType.LINUX_RPM).configureHelloApp() .addInitializer(cmd -> { cmd.addArguments("--linux-rpm-license-type", LICENSE_TYPE); diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/linux/LinuxBundleNameTest.java --- a/test/jdk/tools/jpackage/linux/LinuxBundleNameTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/linux/LinuxBundleNameTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -21,7 +21,7 @@ * questions. */ -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; @@ -44,6 +44,7 @@ * @test * @summary jpackage with --linux-package-name * @library ../helpers + * @build jdk.jpackage.test.* * @requires (os.family == "linux") * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m LinuxBundleNameTest @@ -53,7 +54,7 @@ public static void main(String[] args) { final String PACKAGE_NAME = "quickbrownfox2"; - Test.run(args, () -> { + TKit.run(args, () -> { new PackageTest() .forTypes(PackageType.LINUX) .configureHelloApp() diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/linux/MaintainerTest.java --- a/test/jdk/tools/jpackage/linux/MaintainerTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/linux/MaintainerTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -23,7 +23,7 @@ import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; /** @@ -40,6 +40,7 @@ * @test * @summary jpackage with --linux-deb-maintainer * @library ../helpers + * @build jdk.jpackage.test.* * @requires (os.family == "linux") * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m MaintainerTest @@ -49,14 +50,14 @@ public static void main(String[] args) { final String MAINTAINER = "jpackage-test@java.com"; - Test.run(args, () -> { + TKit.run(args, () -> { new PackageTest().forTypes(PackageType.LINUX_DEB).configureHelloApp() .addInitializer(cmd -> { cmd.addArguments("--linux-deb-maintainer", MAINTAINER); }) .addBundlePropertyVerifier("Maintainer", (propName, propValue) -> { String lookupValue = "<" + MAINTAINER + ">"; - Test.assertTrue(propValue.endsWith(lookupValue), + TKit.assertTrue(propValue.endsWith(lookupValue), String.format("Check value of %s property [%s] ends with %s", propName, propValue, lookupValue)); }) diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/linux/PackageDepsTest.java --- a/test/jdk/tools/jpackage/linux/PackageDepsTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/linux/PackageDepsTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -21,7 +21,7 @@ * questions. */ -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; @@ -45,28 +45,28 @@ * @test * @summary jpackage with --linux-package-deps * @library ../helpers + * @build jdk.jpackage.test.* * @requires (os.family == "linux") * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m PackageDepsTest */ public class PackageDepsTest { - // Pick the name of prerequisite package to be alphabetically - // preceeding the main package name. - // This is needed to make Bash script batch installing/uninstalling packages - // produced by jtreg tests install/uninstall packages in the right order. - static class APackageDepsTestPrereq { - - public static void main(String[] args) { - new PackageTest().forTypes(PackageType.LINUX).configureHelloApp().run(); - } - } - public static void main(String[] args) { + // Pick the name of prerequisite package to be alphabetically + // preceeding the main package name. + // This is needed to make Bash script batch installing/uninstalling packages + // produced by jtreg tests install/uninstall packages in the right order. final String PREREQ_PACKAGE_NAME = "apackagedepstestprereq"; - Test.run(args, () -> { - APackageDepsTestPrereq.main(args); + TKit.run(args, () -> { + new PackageTest() + .forTypes(PackageType.LINUX) + .configureHelloApp() + .addInitializer(cmd -> { + cmd.setArgumentValue("--name", PREREQ_PACKAGE_NAME); + }) + .run(); new PackageTest() .forTypes(PackageType.LINUX) diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/linux/ReleaseTest.java --- a/test/jdk/tools/jpackage/linux/ReleaseTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/linux/ReleaseTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -23,7 +23,7 @@ import jdk.jpackage.test.PackageType; import jdk.jpackage.test.PackageTest; -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; /** @@ -43,6 +43,7 @@ * @test * @summary jpackage with --linux-app-release * @library ../helpers + * @build jdk.jpackage.test.* * @requires (os.family == "linux") * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m ReleaseTest @@ -52,7 +53,7 @@ public static void main(String[] args) { final String RELEASE = "Rc3"; - Test.run(args, () -> { + TKit.run(args, () -> { new PackageTest() .forTypes(PackageType.LINUX) .configureHelloApp() @@ -63,7 +64,7 @@ .addBundlePropertyVerifier("Release", RELEASE) .forTypes(PackageType.LINUX_DEB) .addBundlePropertyVerifier("Version", (propName, propValue) -> { - Test.assertTrue(propValue.endsWith("-" + RELEASE), + TKit.assertTrue(propValue.endsWith("-" + RELEASE), String.format("Check value of %s property [%s] ends with %s", propName, propValue, RELEASE)); }) diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/linux/ShortcutHintTest.java --- a/test/jdk/tools/jpackage/linux/ShortcutHintTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/linux/ShortcutHintTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -26,7 +26,8 @@ import jdk.jpackage.test.FileAssociations; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.PackageTest; -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; +import jdk.jpackage.test.Annotations.Test; /** * Test --linux-shortcut parameter. Output of the test should be @@ -48,50 +49,39 @@ * @test * @summary jpackage with --linux-shortcut * @library ../helpers + * @build jdk.jpackage.test.* * @requires (os.family == "linux") * @modules jdk.jpackage/jdk.jpackage.internal - * @run main/othervm/timeout=360 -Xmx512m ShortcutHintTest - * @run main/othervm/timeout=360 -Xmx512m ShortcutHintTest testCustomIcon - * @run main/othervm/timeout=360 -Xmx512m ShortcutHintTest testFileAssociations - * @run main/othervm/timeout=360 -Xmx512m ShortcutHintTest testAdditionaltLaunchers + * @compile ShortcutHintTest.java + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=ShortcutHintTest */ public class ShortcutHintTest { - public static void main(String[] args) { - Test.run(args, () -> { - if (args.length != 0) { - Test.getTestClass().getDeclaredMethod(args[0]).invoke(null); - return; - } - - createTest(null).addInitializer(cmd -> { - cmd.addArgument("--linux-shortcut"); - }).run(); - }); + @Test + public static void testBasic() { + createTest().addInitializer(cmd -> { + cmd.addArgument("--linux-shortcut"); + }).run(); } - private static PackageTest createTest(String name) { - PackageTest reply = new PackageTest() + private static PackageTest createTest() { + return new PackageTest() .forTypes(PackageType.LINUX) .configureHelloApp() .addBundleDesktopIntegrationVerifier(true); - if (name != null) { - reply.addInitializer(cmd -> cmd.setArgumentValue("--name", - String.format("%s8%s", Test.getTestClass().getSimpleName(), - name))); - } - return reply; + } /** * Adding `--icon` to jpackage command line should create desktop shortcut * even though `--linux-shortcut` is omitted. */ - static void testCustomIcon() { - createTest(new Object() { - }.getClass().getEnclosingMethod().getName()).addInitializer(cmd -> { + @Test + public static void testCustomIcon() { + createTest().addInitializer(cmd -> { cmd.setFakeRuntime(); - cmd.addArguments("--icon", Test.TEST_SRC_ROOT.resolve( + cmd.addArguments("--icon", TKit.TEST_SRC_ROOT.resolve( "apps/dukeplug.png")); }).run(); } @@ -100,9 +90,9 @@ * Adding `--file-associations` to jpackage command line should create * desktop shortcut even though `--linux-shortcut` is omitted. */ - static void testFileAssociations() { - createTest(new Object() { - }.getClass().getEnclosingMethod().getName()).addInitializer(cmd -> { + @Test + public static void testFileAssociations() { + createTest().addInitializer(cmd -> { cmd.setFakeRuntime(); FileAssociations fa = new FileAssociations( @@ -116,20 +106,20 @@ * Additional launcher with icon should create desktop shortcut even though * `--linux-shortcut` is omitted. */ - static void testAdditionaltLaunchers() { - createTest(new Object() { - }.getClass().getEnclosingMethod().getName()).addInitializer(cmd -> { + @Test + public static void testAdditionaltLaunchers() { + createTest().addInitializer(cmd -> { cmd.setFakeRuntime(); final String launcherName = "Foo"; - final Path propsFile = Test.workDir().resolve( + final Path propsFile = TKit.workDir().resolve( launcherName + ".properties"); cmd.addArguments("--add-launcher", String.format("%s=%s", launcherName, propsFile)); - Test.createPropertiesFile(propsFile, Map.entry("icon", - Test.TEST_SRC_ROOT.resolve("apps/dukeplug.png").toString())); + TKit.createPropertiesFile(propsFile, Map.entry("icon", + TKit.TEST_SRC_ROOT.resolve("apps/dukeplug.png").toString())); }).run(); } } diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/AdditionalLaunchersTest.java --- a/test/jdk/tools/jpackage/share/AdditionalLaunchersTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/share/AdditionalLaunchersTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -31,7 +31,7 @@ import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.FileAssociations; -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; /** * Test --add-launcher parameter. Output of the test should be @@ -45,13 +45,14 @@ * @test * @summary jpackage with --add-launcher * @library ../helpers + * @build jdk.jpackage.test.* * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m AdditionalLaunchersTest */ public class AdditionalLaunchersTest { public static void main(String[] args) { - Test.run(args, () -> { + TKit.run(args, () -> { FileAssociations fa = new FileAssociations( MethodHandles.lookup().lookupClass().getSimpleName()); @@ -75,7 +76,7 @@ AdditionalLauncher barLauncher = new AdditionalLauncher("Bar").setArguments( "one", "two", "three"); packageTest.forTypes(PackageType.LINUX).addInitializer(cmd -> { - barLauncher.setIcon(Test.TEST_SRC_ROOT.resolve("apps/dukeplug.png")); + barLauncher.setIcon(TKit.TEST_SRC_ROOT.resolve("apps/dukeplug.png")); }); barLauncher.applyTo(packageTest); @@ -109,7 +110,7 @@ } void applyTo(PackageTest test) { - final Path propsFile = Test.workDir().resolve(name + ".properties"); + final Path propsFile = TKit.workDir().resolve(name + ".properties"); test.addInitializer(cmd -> { cmd.addArguments("--add-launcher", String.format("%s=%s", name, @@ -125,13 +126,13 @@ properties.put("icon", icon.toAbsolutePath().toString()); } - Test.createPropertiesFile(propsFile, properties); + TKit.createPropertiesFile(propsFile, properties); }); test.addInstallVerifier(cmd -> { Path launcherPath = replaceFileName( cmd.launcherInstallationPath(), name); - Test.assertExecutableFileExists(launcherPath, true); + TKit.assertExecutableFileExists(launcherPath); if (cmd.isFakeRuntimeInstalled(String.format( "Not running %s launcher", launcherPath))) { @@ -145,7 +146,7 @@ Path launcherPath = replaceFileName( cmd.launcherInstallationPath(), name); - Test.assertExecutableFileExists(launcherPath, false); + TKit.assertPathExists(launcherPath, false); }); } diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/AppImagePackageTest.java --- a/test/jdk/tools/jpackage/share/AppImagePackageTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/share/AppImagePackageTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -22,7 +22,7 @@ */ import java.nio.file.Path; -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.JPackageCommand; @@ -37,13 +37,14 @@ * @test * @summary jpackage with --app-image * @library ../helpers + * @build jdk.jpackage.test.* * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m AppImagePackageTest */ public class AppImagePackageTest { public static void main(String[] args) { - Test.run(args, () -> { + TKit.run(args, () -> { Path appimageOutput = Path.of("appimage"); JPackageCommand appImageCmd = JPackageCommand.helloAppImage() @@ -64,7 +65,7 @@ } cmd.addArguments("--app-image", appimageInput); - cmd.removeArgument("--input"); + cmd.removeArgumentWithValue("--input"); }).addBundleDesktopIntegrationVerifier(false).run(); }); } diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/ArgumentsBase.java --- a/test/jdk/tools/jpackage/share/ArgumentsBase.java Mon Sep 30 15:59:50 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +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; -import java.util.ArrayList; -import java.util.List; - -public class ArgumentsBase { - - private static final String app = JPackagePath.getApp(); - private static final String appOutput = JPackagePath.getAppOutputFile(); - - private static final String ARGUMENT1 = "argument"; - private static final String ARGUMENT2 = "Some Arguments"; - private static final String ARGUMENT3 = "Value \"with\" quotes"; - - private static final String ARGUMENT_CMD1 = "test"; - - private static final List arguments = new ArrayList<>(); - private static final List argumentsCmd = new ArrayList<>(); - - public static void initArguments(boolean toolProvider, String[] cmd) { - if (arguments.isEmpty()) { - arguments.add(ARGUMENT1); - arguments.add(ARGUMENT2); - arguments.add(ARGUMENT3); - } - - if (argumentsCmd.isEmpty()) { - argumentsCmd.add(ARGUMENT_CMD1); - } - - String argumentsMap - = JPackageHelper.listToArgumentsMap(arguments, toolProvider); - cmd[cmd.length - 1] = argumentsMap; - } - - private static void validateResult(String[] result, List args) - throws Exception { - if (result.length != (args.size() + 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: " + args.size())) { - throw new AssertionError("Unexpected result[1]: " + result[1]); - } - - int index = 2; - for (String arg : args) { - if (!result[index].trim().equals(arg)) { - throw new AssertionError( - "Unexpected result[" + index + "]: " + result[index]); - } - index++; - } - } - - private static void validate(String arg, List expectedArgs) - throws Exception { - int retVal; - - if (arg == null) { - retVal = JPackageHelper.execute(null, app); - } else { - retVal = JPackageHelper.execute(null, app, arg); - } - 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, expectedArgs); - } - - public static void testCreateAppImage(String[] cmd) throws Exception { - initArguments(false, cmd); - JPackageHelper.executeCLI(true, cmd); - validate(null, arguments); - validate(ARGUMENT_CMD1, argumentsCmd); - } - - public static void testCreateAppImageToolProvider(String[] cmd) throws Exception { - initArguments(true, cmd); - JPackageHelper.executeToolProvider(true, cmd); - validate(null, arguments); - validate(ARGUMENT_CMD1, argumentsCmd); - } -} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/ArgumentsModuleTest.java --- a/test/jdk/tools/jpackage/share/ArgumentsModuleTest.java Mon Sep 30 15:59:50 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +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 with --arguments test - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @build ArgumentsBase - * @modules jdk.jpackage - * @run main/othervm -Xmx512m ArgumentsModuleTest - */ -public class ArgumentsModuleTest { - private static final String OUTPUT = "output"; - - private static final String[] CMD = { - "--package-type", "app-image", - "--dest", OUTPUT, - "--name", "test", - "--module", "com.hello/com.hello.Hello", - "--module-path", "input", - "--arguments", "TBD"}; - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloModule(); - ArgumentsBase.testCreateAppImage(CMD); - JPackageHelper.deleteOutputFolder(OUTPUT); - ArgumentsBase.testCreateAppImageToolProvider(CMD); - } - -} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/ArgumentsTest.java --- a/test/jdk/tools/jpackage/share/ArgumentsTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/share/ArgumentsTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -21,33 +21,68 @@ * questions. */ +import java.nio.file.Path; +import java.util.List; +import jdk.jpackage.test.TKit; +import jdk.jpackage.test.HelloApp; +import jdk.jpackage.test.Functional.ThrowingConsumer; +import jdk.jpackage.test.JPackageCommand; +import jdk.jpackage.test.Annotations.*; + + +/* + * Tricky arguments used in the test require a bunch of levels of character + * escaping for proper encoding them in a single string to be used as a value of + * `--arguments` option. String with encoded arguments doesn't go through the + * system to jpackage executable as is because OS is interpreting escape + * characters. This is true for Windows at least. + * + * String mapping performed by the system corrupts the string and jpackage exits + * with error. There is no problem with string corruption when jpackage is used + * as tool provider. This is not jpackage issue, so just always run this test + * with jpackage used as tool provider. + * / + /* * @test * @summary jpackage create image with --arguments test * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @build ArgumentsBase + * @build jdk.jpackage.test.* * @modules jdk.jpackage - * @run main/othervm -Xmx512m ArgumentsTest + * @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 { - 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", - "--arguments", "TBD"}; - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloImageJar(); - ArgumentsBase.testCreateAppImage(CMD); - JPackageHelper.deleteOutputFolder(OUTPUT); - ArgumentsBase.testCreateAppImageToolProvider(CMD); + @Test + @Parameter("Goodbye") + @Parameter("com.hello/com.hello.Hello") + public static void testApp(String javaAppDesc) { + testIt(javaAppDesc, null); } + private static void testIt(String javaAppDesc, + ThrowingConsumer initializer) { + + JPackageCommand cmd = JPackageCommand.helloAppImage(javaAppDesc).addArguments( + "--arguments", JPackageCommand.escapeAndJoin(TRICKY_ARGUMENTS)); + if (initializer != null) { + ThrowingConsumer.toConsumer(initializer).accept(cmd); + } + + cmd.executeAndAssertImageCreated(); + + Path launcherPath = cmd.appImage().resolve(cmd.launcherPathInAppImage()); + if (!cmd.isFakeRuntimeInAppImage(String.format( + "Not running [%s] launcher", launcherPath))) { + HelloApp.executeAndVerifyOutput(launcherPath, TRICKY_ARGUMENTS); + } + } + + private final static List TRICKY_ARGUMENTS = List.of( + "argument", + "Some Arguments", + "Value \"with\" quotes" + ); } diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/AtFilenameTest.java --- a/test/jdk/tools/jpackage/share/AtFilenameTest.java Mon Sep 30 15:59:50 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +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 test - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @build Base - * @modules jdk.jpackage - * @run main/othervm -Xmx512m AtFilenameTest - */ -public class AtFilenameTest { - 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", - }; - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloImageJar(); - - doTest(0, 1); // replace just the mode - doTest(0, 11); // replace everything - doTest(1, 10); // replace everything except mode - doTest(4, 2); // replace the name and --main-jar without jar name - - } - - private static void doTest(int index, int len) throws Exception { - String[] cmdWithAtFilename = - JPackageHelper.cmdWithAtFilename(CMD, index, len); - - Base.testCreateAppImageToolProvider(cmdWithAtFilename); - JPackageHelper.deleteOutputFolder(OUTPUT); - } - -} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/FileAssociationsTest.java --- a/test/jdk/tools/jpackage/share/FileAssociationsTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/share/FileAssociationsTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -21,7 +21,7 @@ * questions. */ -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.FileAssociations; @@ -47,12 +47,13 @@ * @test * @summary jpackage with --file-associations * @library ../helpers + * @build jdk.jpackage.test.* * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m FileAssociationsTest */ public class FileAssociationsTest { public static void main(String[] args) { - Test.run(args, () -> { + TKit.run(args, () -> { PackageTest packageTest = new PackageTest(); applyFileAssociations(packageTest, new FileAssociations("jptest1")); diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/IconTest.java --- a/test/jdk/tools/jpackage/share/IconTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/share/IconTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -21,105 +21,56 @@ * questions. */ -import java.io.File; import java.nio.file.Files; +import jdk.jpackage.internal.ApplicationLayout; +import java.nio.file.Path; +import jdk.jpackage.test.TKit; +import jdk.jpackage.test.Functional; +import jdk.jpackage.test.JPackageCommand; /* * @test * @summary jpackage create image to verify --icon * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @modules jdk.jpackage + * @build jdk.jpackage.test.* + * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm -Xmx512m IconTest */ public class IconTest { - 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", - "--name", "test", - "--main-jar", "hello.jar", - "--main-class", "Hello", - "--icon", getIconPath(), - "--dest", OUTPUT}; - - private static void validateResult(String[] result) throws Exception { - if (result.length != 2) { - throw new AssertionError( - "Unexpected number of lines: " + result.length); - } + public static void main(String[] args) { + TKit.run(args, () -> { + JPackageCommand cmd = JPackageCommand.helloAppImage().addArguments("--icon", GOLDEN_ICON); + cmd.useToolProvider(true).executeAndAssertHelloAppImageCreated(); - 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]); - } - } + Path iconPath = ApplicationLayout.platformAppImage().resolveAt( + cmd.appImage()).destktopIntegrationDirectory().resolve( + cmd.launcherPathInAppImage().getFileName().toString().replaceAll( + "\\.[^.]*$", "") + ICON_SUFFIX); - 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); + 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 void validateIcon() throws Exception { - File origIcon = new File(getIconPath()); - File icon = new File(JPackagePath.getAppIcon()); - if (origIcon.length() != icon.length()) { - System.err.println("origIcon.length(): " + origIcon.length()); - System.err.println("icon.length(): " + icon.length()); - throw new AssertionError("Icons size does not match"); + private final static String ICON_SUFFIX = Functional.identity(() -> { + if (TKit.isOSX()) { + return ".icns"; } - } - 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 getIconPath() { - String ext = ".ico"; - if (JPackageHelper.isOSX()) { - ext = ".icns"; - } else if (JPackageHelper.isLinux()) { - ext = ".png"; + if (TKit.isLinux()) { + return ".png"; } - String path = JPackagePath.getTestSrcRoot() + File.separator + "resources" - + File.separator + "icon" + ext; - - return path; - } + if (TKit.isWindows()) { + return ".ico"; + } - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloImageJar(); - testIcon(); - testIconToolProvider(); - } + throw TKit.throwUnknownPlatformError(); + }).get(); + private final static Path GOLDEN_ICON = TKit.TEST_SRC_ROOT.resolve(Path.of( + "resources", "icon" + ICON_SUFFIX)); } diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/InstallDirTest.java --- a/test/jdk/tools/jpackage/share/InstallDirTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/share/InstallDirTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -25,9 +25,10 @@ import java.util.HashMap; import java.util.Map; import java.util.function.Supplier; -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; +import jdk.jpackage.test.Functional; /** * Test --install-dir parameter. Output of the test should be installdirtest*.* @@ -53,32 +54,28 @@ * @test * @summary jpackage with --install-dir * @library ../helpers + * @build jdk.jpackage.test.* * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m InstallDirTest */ public class InstallDirTest { public static void main(String[] args) { - final Map INSTALL_DIRS = new Supplier>() { - @Override - public Map get() { - Map reply = new HashMap<>(); - reply.put(PackageType.WIN_MSI, Path.of( - "TestVendor\\InstallDirTest1234")); - reply.put(PackageType.WIN_EXE, reply.get(PackageType.WIN_MSI)); + final Map INSTALL_DIRS = Functional.identity(() -> { + Map reply = new HashMap<>(); + reply.put(PackageType.WIN_MSI, Path.of("TestVendor\\InstallDirTest1234")); + reply.put(PackageType.WIN_EXE, reply.get(PackageType.WIN_MSI)); + + reply.put(PackageType.LINUX_DEB, Path.of("/opt/jpackage")); + reply.put(PackageType.LINUX_RPM, reply.get(PackageType.LINUX_DEB)); - reply.put(PackageType.LINUX_DEB, Path.of("/opt/jpackage")); - reply.put(PackageType.LINUX_RPM, - reply.get(PackageType.LINUX_DEB)); + reply.put(PackageType.MAC_PKG, Path.of("/Application/jpackage")); + reply.put(PackageType.MAC_DMG, reply.get(PackageType.MAC_PKG)); - reply.put(PackageType.MAC_PKG, Path.of("/Application/jpackage")); - reply.put(PackageType.MAC_DMG, reply.get(PackageType.MAC_PKG)); + return reply; + }).get(); - return reply; - } - }.get(); - - Test.run(args, () -> { + TKit.run(args, () -> { new PackageTest().configureHelloApp() .addInitializer(cmd -> { cmd.addArguments("--install-dir", INSTALL_DIRS.get( diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/JLinkModuleTest.java --- a/test/jdk/tools/jpackage/share/JLinkModuleTest.java Mon Sep 30 15:59:50 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * 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 java.util.ArrayList; - - /* - * @test - * @summary jpackage create image modular jar test - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @build Base - * @modules jdk.jpackage - * @run main/othervm -Xmx512m JLinkModuleTest - */ -public class JLinkModuleTest { - private static final String OUTPUT = "output"; - private static final String RUNTIME = "runtime"; - - private static final String [] CMD = { - "--package-type", "app-image", - "--dest", OUTPUT, - "--name", "test", - "--module", "com.other/com.other.Other", - "--runtime-image", RUNTIME, - }; - - public static void main(String[] args) throws Exception { - JPackageHelper.createOtherModule(); - - ArrayList jlargs = new ArrayList<>(); - jlargs.add("--add-modules"); - jlargs.add("com.other"); - jlargs.add("--module-path"); - jlargs.add("module"); - jlargs.add("--strip-debug"); - jlargs.add("--no-header-files"); - jlargs.add("--no-man-pages"); - jlargs.add("--strip-native-commands"); - JPackageHelper.createRuntime(jlargs); - - - JPackageHelper.deleteOutputFolder(OUTPUT); - Base.testCreateAppImage(CMD); - - } - -} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/LicenseTest.java --- a/test/jdk/tools/jpackage/share/LicenseTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/share/LicenseTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -34,7 +34,7 @@ import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.LinuxHelper; import jdk.jpackage.test.Executor; -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; /** * Test --license-file parameter. Output of the test should be licensetest*.* @@ -64,8 +64,11 @@ * @test * @summary jpackage with --license-file * @library ../helpers + * @build jdk.jpackage.test.* + * @compile LicenseTest.java * @modules jdk.jpackage/jdk.jpackage.internal - * @run main/othervm/timeout=360 -Xmx512m LicenseTest testCommon + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=LicenseTest.testCommon */ /* @@ -73,20 +76,14 @@ * @summary jpackage with --license-file * @library ../helpers * @modules jdk.jpackage/jdk.jpackage.internal + * @compile LicenseTest.java * @requires (os.family == "linux") - * @run main/othervm/timeout=360 -Xmx512m LicenseTest testCustomDebianCopyright - * @run main/othervm/timeout=360 -Xmx512m LicenseTest testCustomDebianCopyrightSubst + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=LicenseTest.testCustomDebianCopyright + * --jpt-run=LicenseTest.testCustomDebianCopyrightSubst */ public class LicenseTest { - public static void main(String[] args) { - Test.run(args, () -> { - String testFuncName = args[0]; - Test.trace(String.format("Running %s...", testFuncName)); - Test.getTestClass().getDeclaredMethod(testFuncName).invoke(null); - }); - } - public static void testCommon() { new PackageTest().configureHelloApp() .addInitializer(cmd -> { @@ -97,7 +94,7 @@ verifyLicenseFileInLinuxPackage(cmd, linuxLicenseFile(cmd)); }) .addInstallVerifier(cmd -> { - Test.assertReadableFileExists(linuxLicenseFile(cmd)); + TKit.assertReadableFileExists(linuxLicenseFile(cmd)); }) .addUninstallVerifier(cmd -> { verifyLicenseFileNotInstalledLinux(linuxLicenseFile(cmd)); @@ -153,7 +150,7 @@ private static void verifyLicenseFileInLinuxPackage(JPackageCommand cmd, Path expectedLicensePath) { - Test.assertTrue(LinuxHelper.getPackageFiles(cmd).filter(path -> path.equals( + TKit.assertTrue(LinuxHelper.getPackageFiles(cmd).filter(path -> path.equals( expectedLicensePath)).findFirst().orElse(null) != null, String.format("Check license file [%s] is in %s package", expectedLicensePath, LinuxHelper.getPackageName(cmd))); @@ -161,7 +158,7 @@ private static void verifyLicenseFileInstalledRpm(Path licenseFile) throws IOException { - Test.assertStringListEquals(Files.readAllLines(LICENSE_FILE), + TKit.assertStringListEquals(Files.readAllLines(LICENSE_FILE), Files.readAllLines(licenseFile), String.format( "Check contents of package license file [%s] are the same as contents of source license file [%s]", licenseFile, LICENSE_FILE)); @@ -178,17 +175,17 @@ actualLines = DEBIAN_COPYRIGT_FILE_STRIPPER.apply(actualLines); - Test.assertNotEquals(0, String.join("\n", actualLines).length(), + TKit.assertNotEquals(0, String.join("\n", actualLines).length(), "Check stripped license text is not empty"); - Test.assertStringListEquals(DEBIAN_COPYRIGT_FILE_STRIPPER.apply( + TKit.assertStringListEquals(DEBIAN_COPYRIGT_FILE_STRIPPER.apply( Files.readAllLines(LICENSE_FILE)), actualLines, String.format( "Check subset of package license file [%s] is a match of the source license file [%s]", licenseFile, LICENSE_FILE)); } private static void verifyLicenseFileNotInstalledLinux(Path licenseFile) { - Test.assertPathExists(licenseFile.getParent(), false); + TKit.assertPathExists(licenseFile.getParent(), false); } private static class CustomDebianCopyrightTest { @@ -233,7 +230,7 @@ } void run() { - final Path srcLicenseFile = Test.workDir().resolve("license"); + final Path srcLicenseFile = TKit.workDir().resolve("license"); new PackageTest().configureHelloApp().forTypes(PackageType.LINUX_DEB) .addInitializer(cmd -> { // Create source license file. @@ -255,7 +252,7 @@ }) .addInstallVerifier(cmd -> { Path installedLicenseFile = debLicenseFile(cmd); - Test.assertStringListEquals(expetedLicenseFileText(), + TKit.assertStringListEquals(expetedLicenseFileText(), DEBIAN_COPYRIGT_FILE_STRIPPER.apply(Files.readAllLines( installedLicenseFile)), String.format( "Check contents of package license file [%s] are the same as contents of source license file [%s]", @@ -268,10 +265,10 @@ private String copyright; private String licenseText; - private final Path RESOURCE_DIR = Test.workDir().resolve("resources"); + private final Path RESOURCE_DIR = TKit.workDir().resolve("resources"); } - private static final Path LICENSE_FILE = Test.TEST_SRC_ROOT.resolve( + private static final Path LICENSE_FILE = TKit.TEST_SRC_ROOT.resolve( Path.of("resources", "license.txt")); private static final Function, List> DEBIAN_COPYRIGT_FILE_STRIPPER = (lines) -> Arrays.asList( diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/ModularJarTest.java --- a/test/jdk/tools/jpackage/share/ModularJarTest.java Mon Sep 30 15:59:50 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * 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. - */ - - /* - * @test - * @summary jpackage create image modular jar test - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @build Base - * @modules jdk.jpackage - * @run main/othervm -Xmx512m ModularJarTest - */ -public class ModularJarTest { - private static final String OUTPUT = "output"; - - private static final String [] CMD1 = { - "--package-type", "app-image", - "--input", "input", - "--dest", OUTPUT, - "--name", "test", - "--main-jar", "com.hello.jar", - "--main-class", "com.hello.Hello", - }; - - private static final String [] CMD2 = { - "--package-type", "app-image", - "--dest", OUTPUT, - "--name", "test", - "--module", "com.hello/com.hello.Hello", - "--module-path", "input/com.hello.jar", - }; - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloModule(); - - Base.testCreateAppImage(CMD1); - JPackageHelper.deleteOutputFolder(OUTPUT); - Base.testCreateAppImageToolProvider(CMD1); - - JPackageHelper.deleteOutputFolder(OUTPUT); - Base.testCreateAppImage(CMD2); - JPackageHelper.deleteOutputFolder(OUTPUT); - Base.testCreateAppImageToolProvider(CMD2); - } - -} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/ModuleTest.java --- a/test/jdk/tools/jpackage/share/ModuleTest.java Mon Sep 30 15:59:50 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * 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. - */ - - /* - * @test - * @summary jpackage create image modular jar test - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @build Base - * @modules jdk.jpackage - * @run main/othervm -Xmx512m ModuleTest - */ -public class ModuleTest { - private static final String OUTPUT = "output"; - - private static final String [] CMD1 = { - "--package-type", "app-image", - "--module-path", "module", - "--module", "com.other/com.other.Other", - "--dest", OUTPUT, - "--name", "test", - }; - - private static String [] commands = { - "--package-type", "app-image", - "--module-path", "module", - "--module", "com.other/com.other.Other", - "--dest", OUTPUT, - "--name", "test", - "--add-modules", "TBD", - }; - - private final static String [] paths = { - "ALL-MODULES", - "ALL_MODULE_PATH", - "ALL-SYSTEM", - "ALL-DEFAULT", - }; - - public static void main(String[] args) throws Exception { - JPackageHelper.createOtherModule(); - - JPackageHelper.deleteOutputFolder(OUTPUT); - Base.testCreateAppImage(CMD1); - - for (String path : paths) { - commands[commands.length - 1] = path; - System.out.println("using --add-modules " + path); - JPackageHelper.deleteOutputFolder(OUTPUT); - Base.testCreateAppImageToolProvider(commands); - System.out.println("succeeded"); - } - } - -} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/NoArgTest.java --- a/test/jdk/tools/jpackage/share/NoArgTest.java Mon Sep 30 15:59:50 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +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 no argument test - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @modules jdk.jpackage - * @run main/othervm -Xmx512m NoArgTest - */ -public class NoArgTest { - - private static final String RESULT1 = "Usage: jpackage "; - private static final String[] EXPECTED = - {"--help", "list of possible options"}; - - private static void validate(String output) throws Exception { - String[] result = JPackageHelper.splitAndFilter(output); - if (result.length != 2) { - System.err.println(output); - throw new AssertionError( - "Invalid number of lines in output: " + result.length); - } - - if (!result[0].trim().equals(RESULT1)) { - System.err.println("Expected: " + RESULT1); - System.err.println("Actual: " + result[0]); - throw new AssertionError("Unexpected line 1"); - } - - for (String expected : EXPECTED) { - if (!result[1].contains(expected)) { - System.err.println("Expected to contain: " + expected); - System.err.println("Actual: " + result[1]); - throw new AssertionError("Unexpected line 2"); - } - } - } - - private static void testNoArg() throws Exception { - String output = JPackageHelper.executeCLI(true, new String[0]); - validate(output); - } - - private static void testNoArgToolProvider() throws Exception { - String output = - JPackageHelper.executeToolProvider(true, new String[0]); - validate(output); - } - - public static void main(String[] args) throws Exception { - testNoArg(); - testNoArgToolProvider(); - } - -} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/NoNameTest.java --- a/test/jdk/tools/jpackage/share/NoNameTest.java Mon Sep 30 15:59:50 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +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 --name - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @modules jdk.jpackage - * @run main/othervm -Xmx512m NoNameTest - */ -public class NoNameTest { - private static final String OUTPUT = "output"; - private static final String app = JPackagePath.getApp("Hello"); - private static final String appOutput = JPackagePath.getAppOutputFile(); - - private static final String[] CMD = { - "--package-type", "app-image", - "--input", "input", - "--dest", OUTPUT, - "--main-jar", "hello.jar", - "--main-class", "Hello", - }; - - 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.createHelloImageJar(); - testMainClassAttribute(); - testMainClassAttributeToolProvider(); - } - -} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/RuntimeBase.java --- a/test/jdk/tools/jpackage/share/RuntimeBase.java Mon Sep 30 15:59:50 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; - - public class RuntimeBase { - private static final String app = JPackagePath.getApp(); - private static final String runtimeJava = JPackagePath.getRuntimeJava(); - private static final String runtimeJavaOutput = "javaOutput.txt"; - private static final String appOutput = JPackagePath.getAppOutputFile(); - - 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 = JPackageHelper.splitAndFilter(output); - validateResult(result); - } - - private static void validateRuntime() throws Exception { - int retVal = JPackageHelper.execute(new File(runtimeJavaOutput), runtimeJava, "--list-modules"); - if (retVal != 0) { - throw new AssertionError("Test application exited with error: " + retVal); - } - - File outfile = new File(runtimeJavaOutput); - if (!outfile.exists()) { - throw new AssertionError(runtimeJavaOutput + " was not created"); - } - - String output = Files.readString(outfile.toPath()); - String[] result = JPackageHelper.splitAndFilter(output); - if (result.length != 1) { - throw new AssertionError("Unexpected number of lines: " + result.length); - } - - if (!result[0].startsWith("java.base")) { - throw new AssertionError("Unexpected result: " + result[0]); - } - } - - public static void testCreateAppImage(String [] cmd) throws Exception { - JPackageHelper.executeCLI(true, cmd); - validate(); - validateRuntime(); - } - - public static void testCreateAppImageToolProvider(String [] cmd) throws Exception { - JPackageHelper.executeToolProvider(true, cmd); - validate(); - validateRuntime(); - } - -} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/RuntimeModuleTest.java --- a/test/jdk/tools/jpackage/share/RuntimeModuleTest.java Mon Sep 30 15:59:50 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +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 runtime test - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @build RuntimeBase - * @modules jdk.jpackage - * @run main/othervm -Xmx512m RuntimeModuleTest - */ -public class RuntimeModuleTest { - private static final String OUTPUT = "output"; - private static final String [] CMD = { - "--package-type", "app-image", - "--runtime-image", "runtime", - "--dest", OUTPUT, - "--name", "test", - "--module", "com.hello/com.hello.Hello", - "--module-path", "input"}; - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloModule(); - JPackageHelper.createRuntime(); - RuntimeBase.testCreateAppImage(CMD); - JPackageHelper.deleteOutputFolder(OUTPUT); - RuntimeBase.testCreateAppImageToolProvider(CMD); - } - -} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/RuntimePackageTest.java --- a/test/jdk/tools/jpackage/share/RuntimePackageTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/share/RuntimePackageTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -23,7 +23,7 @@ import java.nio.file.Path; import java.util.Optional; -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.JPackageCommand; @@ -44,6 +44,7 @@ * @test * @summary jpackage with --runtime-image * @library ../helpers + * @build jdk.jpackage.test.* * @comment Temporary disable for Linux and OSX until functionality implemented * @requires (os.family != "mac") * @modules jdk.jpackage/jdk.jpackage.internal @@ -52,7 +53,7 @@ public class RuntimePackageTest { public static void main(String[] args) { - Test.run(args, () -> { + TKit.run(args, () -> { new PackageTest() .addInitializer(cmd -> { cmd.addArguments("--runtime-image", Optional.ofNullable( @@ -61,7 +62,7 @@ // Remove --input parameter from jpackage command line as we don't // create input directory in the test and jpackage fails // if --input references non existant directory. - cmd.removeArgument("--input"); + cmd.removeArgumentWithValue("--input"); }) .run(); }); diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/RuntimeTest.java --- a/test/jdk/tools/jpackage/share/RuntimeTest.java Mon Sep 30 15:59:50 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +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 runtime test - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @build RuntimeBase - * @modules jdk.jpackage - * @run main/othervm -Xmx512m RuntimeTest - */ -public class RuntimeTest { - private static final String OUTPUT = "output"; - private static final String [] CMD = { - "--package-type", "app-image", - "--runtime-image", "runtime", - "--input", "input", - "--dest", OUTPUT, - "--name", "test", - "--main-jar", "hello.jar", - "--main-class", "Hello", - }; - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloImageJar(); - JPackageHelper.createRuntime(); - RuntimeBase.testCreateAppImage(CMD); - JPackageHelper.deleteOutputFolder(OUTPUT); - RuntimeBase.testCreateAppImageToolProvider(CMD); - } - -} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/SimplePackageTest.java --- a/test/jdk/tools/jpackage/share/SimplePackageTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/share/SimplePackageTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -21,7 +21,7 @@ * questions. */ -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; /** @@ -41,13 +41,14 @@ * @test * @summary Simple jpackage command run * @library ../helpers + * @build jdk.jpackage.test.* * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m SimplePackageTest */ public class SimplePackageTest { public static void main(String[] args) { - Test.run(args, () -> { + TKit.run(args, () -> { new PackageTest() .configureHelloApp() .addBundleDesktopIntegrationVerifier(false) diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/TempRootTest.java --- a/test/jdk/tools/jpackage/share/TempRootTest.java Mon Sep 30 15:59:50 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; - - /* - * @test - * @requires (os.family == "windows") - * @summary jpackage create image to test --temp - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @modules jdk.jpackage - * @run main/othervm -Xmx512m TempRootTest - */ -public class TempRootTest { - private static final String OUTPUT = "output"; - private static String buildRoot = null; - private static final String BUILD_ROOT = "buildRoot"; - private static final String BUILD_ROOT_TB = "buildRootToolProvider"; - - 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_BUILD_ROOT = { - "--package-type", "app-image", - "--input", "input", - "--dest", OUTPUT, - "--name", "test", - "--main-jar", "hello.jar", - "--main-class", "Hello", - "--temp", "TBD"}; - - private static void validate(boolean retain) throws Exception { - File br = new File(buildRoot); - if (retain) { - if (!br.exists()) { - throw new AssertionError(br.getAbsolutePath() + " does not exist"); - } - } else { - if (br.exists()) { - throw new AssertionError(br.getAbsolutePath() + " exist"); - } - } - } - - private static void init(boolean toolProvider) { - if (toolProvider) { - buildRoot = BUILD_ROOT_TB; - } else { - buildRoot = BUILD_ROOT; - } - - CMD_BUILD_ROOT[CMD_BUILD_ROOT.length - 1] = buildRoot; - } - - private static void testTempRoot() throws Exception { - init(false); - JPackageHelper.executeCLI(true, CMD); - validate(false); - JPackageHelper.deleteOutputFolder(OUTPUT); - JPackageHelper.executeCLI(true, CMD_BUILD_ROOT); - validate(true); - } - - private static void testTempRootToolProvider() throws Exception { - init(true); - JPackageHelper.deleteOutputFolder(OUTPUT); - JPackageHelper.executeToolProvider(true, CMD); - validate(false); - JPackageHelper.deleteOutputFolder(OUTPUT); - JPackageHelper.executeToolProvider(true, CMD_BUILD_ROOT); - validate(true); - } - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloImageJar(); - testTempRoot(); - testTempRootToolProvider(); - } - -} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/Test.java --- a/test/jdk/tools/jpackage/share/Test.java Mon Sep 30 15:59:50 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +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 test - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @build Base - * @modules jdk.jpackage - * @run main/othervm -Xmx512m Test - */ - -public class Test { - 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", - }; - - public static void main(String[] args) throws Exception { - JPackageHelper.createHelloImageJar(); - Base.testCreateAppImage(CMD); - JPackageHelper.deleteOutputFolder(OUTPUT); - Base.testCreateAppImageToolProvider(CMD); - } -} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/VersionTest.java --- a/test/jdk/tools/jpackage/share/VersionTest.java Mon Sep 30 15:59:50 2019 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +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 version test - * @library ../helpers - * @build JPackageHelper - * @build JPackagePath - * @modules jdk.jpackage - * @run main/othervm -Xmx512m VersionTest - */ -public class VersionTest { - - private static final String ARG = "--version"; - private static final String RESULT = System.getProperty("java.version"); - - private static void validate(String output) throws Exception { - String[] result = JPackageHelper.splitAndFilter(output); - if (result.length != 1) { - System.err.println(output); - throw new AssertionError("Invalid number of lines in output: " + result.length); - } - - if (!result[0].trim().equals(RESULT)) { - System.err.println("Expected: " + RESULT); - System.err.println("Actual: " + result[0]); - throw new AssertionError("Unexpected line 1"); - } - } - - private static void testVersion() throws Exception { - String output = JPackageHelper.executeCLI(true, ARG); - validate(output); - } - - private static void testVersionToolProvider() throws Exception { - String output = JPackageHelper.executeToolProvider(true, ARG); - validate(output); - } - - public static void main(String[] args) throws Exception { - testVersion(); - testVersionToolProvider(); - } - -} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/share/jdk/jpackage/tests/BasicTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/BasicTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -0,0 +1,254 @@ +/* + * 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.nio.file.Path; +import java.util.List; +import java.util.ArrayList; +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 jdk.jpackage.test.Annotations.*; + +/* + * @test + * @summary jpackage basic testing + * @library ../../../../helpers + * @build jdk.jpackage.test.* + * @modules jdk.jpackage + * @compile BasicTest.java + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=jdk.jpackage.tests.BasicTest + */ + +public class BasicTest { + @Test + public void testNoArgs() { + List output = JPackageCommand.filterOutput( + createVanillaJPackageCommand().executeAndGetOutput()); + TKit.assertStringListEquals(List.of("Usage: jpackage ", + "Use jpackage --help (or -h) for a list of possible options"), + output, "Check jpackage output"); + } + + @Test + public void testVersion() { + List output = JPackageCommand.filterOutput( + createVanillaJPackageCommand() + .addArgument("--version") + .executeAndGetOutput()); + TKit.assertStringListEquals(List.of(System.getProperty("java.version")), + output, "Check jpackage output"); + } + + @Test + public void testNoName() { + final String mainClassName = "Greetings"; + + JPackageCommand cmd = new JPackageCommand() + .helloAppImage(mainClassName) + .removeArgumentWithValue("--name"); + + Path expectedImageDir = cmd.outputDir().resolve(mainClassName); + if (TKit.isOSX()) { + expectedImageDir = expectedImageDir.getParent().resolve( + expectedImageDir.getFileName().toString() + ".app"); + } + + cmd.executeAndAssertHelloAppImageCreated(); + TKit.assertEquals(expectedImageDir.toAbsolutePath().normalize().toString(), + cmd.appImage().toAbsolutePath().normalize().toString(), + String.format( + "Check [%s] directory is filled with application image data", + expectedImageDir)); + } + + @Test + public void testApp() { + new JPackageCommand() + .helloAppImage() + .executeAndAssertHelloAppImageCreated(); + } + + @Test + public void testModularApp() { + new JPackageCommand() + .helloAppImage("com.other/com.other.Hello") + .executeAndAssertHelloAppImageCreated(); + } + + @Test +// @Parameter("ALL-MODULE-PATH") ; This test fails + @Parameter("ALL-DEFAULT") + public void testAddModules(String addModulesArg) { + JPackageCommand cmd = new JPackageCommand() + .helloAppImage("com.other/com.other.Hello"); + if (!addModulesArg.isEmpty()) { + cmd.addArguments("--add-modules", addModulesArg); + } + cmd.executeAndAssertHelloAppImageCreated(); + } + + /** + * Test --temp option. Doesn't make much sense for app image as temporary + * directory is used only on Windows. + * @throws IOException + */ +// @Test + public void testTemp() throws IOException { + JPackageCommand cmd = new JPackageCommand().helloAppImage(); + TKit.withTempDirectory("temp-root", tempDir -> { + cmd.addArguments("--temp", tempDir); + + cmd.executeAndAssertHelloAppImageCreated(); + + // Check jpackage actually used the supplied directory. + TKit.assertNotEquals(0, tempDir.toFile().list().length, + String.format( + "Check jpackage wrote some data in the supplied temporary directory [%s]", + tempDir)); + + // Temporary directory should not be empty, + // jpackage should exit with error. + cmd.execute().assertExitCodeIs(1); + }); + } + + @Test + public void testAtFile() throws IOException { + JPackageCommand cmd = new JPackageCommand().helloAppImage(); + + // Init options file with the list of options configured + // for JPackageCommand instance. + final Path optionsFile = TKit.workDir().resolve("options"); + Files.write(optionsFile, + List.of(String.join(" ", cmd.getAllArguments()))); + + // Build app jar file. + cmd.executePrerequisiteActions(); + + // Make sure output directory is empty. Normally JPackageCommand would + // do this automatically. + TKit.deleteDirectoryContentsRecursive(cmd.outputDir()); + + // Instead of running jpackage command through configured + // JPackageCommand instance, run vanilla jpackage command with @ file. + createVanillaJPackageCommand() + .addArgument(String.format("@%s", optionsFile)) + .execute().assertExitCodeIsZero(); + + // Verify output of jpackage command. + cmd.assertImageCreated(); + HelloApp.executeLauncherAndVerifyOutput(cmd); + } + + @Parameter("Hello") + @Parameter("com.foo/com.foo.main.Aloha") + @Test + public void testJLinkRuntime(String javaAppDesc) { + JPackageCommand cmd = new JPackageCommand().helloAppImage(javaAppDesc); + + // If `--module` parameter was set on jpackage command line, get its + // value and extract module name. + // E.g.: foo.bar2/foo.bar.Buz -> foo.bar2 + // Note: HelloApp class manages `--module` parameter on jpackage command line + final String moduleName = cmd.getArgumentValue("--module", () -> null, + (v) -> v.split("/", 2)[0]); + + if (moduleName != null) { + // Build module jar. + cmd.executePrerequisiteActions(); + } + + TKit.withTempDirectory("runtime", runtimeDir -> { + TKit.deleteDirectoryRecursive(runtimeDir, String.format( + "Delete [%s] output directory for jlink command", runtimeDir)); + Executor jlink = createJavaToolCommand(JavaTool.JLINK) + .saveOutput(false) + .addArguments( + "--add-modules", "java.base", + "--output", runtimeDir.toString(), + "--strip-debug", + "--no-header-files", + "--no-man-pages"); + + if (moduleName != null) { + jlink.addArguments("--add-modules", moduleName, "--module-path", + Path.of(cmd.getArgumentValue("--module-path")).resolve( + "hello.jar").toString()); + } + + jlink.execute().assertExitCodeIsZero(); + + cmd.addArguments("--runtime-image", runtimeDir); + cmd.executeAndAssertHelloAppImageCreated(); + + final Path appImageRuntimePath = cmd.appImage().resolve( + cmd.appRuntimeDirectoryInAppImage()); + + // This is an overkill to list modules in jlink output as we have + // already verified that Java app is functional and thus app's runtime + // is likely to be OK, but let's double check. + List moduleList = new Executor().dumpOutput().setExecutable( + appImageRuntimePath.resolve( + JPackageCommand.relativePathInRuntime(JavaTool.JAVA))).addArguments( + "--list-modules").executeAndGetOutput().stream().sorted().collect( + Collectors.toList()); + + List expectedModules = new ArrayList<>(); + expectedModules.add(String.format("java.base@%s", + System.getProperty("java.version"))); + if (moduleName != null) { + expectedModules.add(moduleName); + } + expectedModules = expectedModules.stream().sorted().collect( + Collectors.toList()); + + TKit.assertStringListEquals(expectedModules, moduleList, + String.format( + "Check modules in application image runtime directory at [%s]", + appImageRuntimePath)); + }); + } + + private static Executor createVanillaJPackageCommand() { + return createJavaToolCommand(JavaTool.JPACKAGE); + } + + private static Executor createJavaToolCommand(JavaTool tool) { + Executor exec = new Executor().dumpOutput().saveOutput(); + if (new JPackageCommand().isWithToolProvider()) { + exec.setToolProvider(tool.asToolProvider()); + } else { + exec.setExecutable(tool); + } + + return exec; + } +} diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/windows/WinConsoleTest.java --- a/test/jdk/tools/jpackage/windows/WinConsoleTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/windows/WinConsoleTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -25,38 +25,40 @@ import java.io.InputStream; import java.io.FileInputStream; import java.io.IOException; - -import jdk.jpackage.internal.IOUtils; -import jdk.jpackage.test.Test; -import jdk.jpackage.test.HelloApp; +import jdk.jpackage.test.TKit; import jdk.jpackage.test.JPackageCommand; +import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.Annotations.Parameter; /* * @test * @summary jpackage with --win-console * @library ../helpers + * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @modules jdk.jpackage/jdk.jpackage.internal - * @run main/othervm/timeout=360 -Xmx512m WinConsoleTest + * @modules jdk.jpackage + * @compile WinConsoleTest.java + * + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-before-run=jdk.jpackage.test.JPackageCommand.useToolProviderByDefault + * --jpt-run=WinConsoleTest + * + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=WinConsoleTest */ public class WinConsoleTest { - public static void main(String[] args) { - Test.run(args, () -> { - JPackageCommand cmd = JPackageCommand.helloAppImage(); - final Path launcherPath = cmd.appImage().resolve( - cmd.launcherPathInAppImage()); - - IOUtils.deleteRecursive(cmd.outputDir().toFile()); - cmd.execute().assertExitCodeIsZero(); - HelloApp.executeLauncherAndVerifyOutput(cmd); - checkSubsystem(launcherPath, false); - - IOUtils.deleteRecursive(cmd.outputDir().toFile()); - cmd.addArgument("--win-console").execute().assertExitCodeIsZero(); - HelloApp.executeLauncherAndVerifyOutput(cmd); - checkSubsystem(launcherPath, true); - }); + @Test + @Parameter("true") + @Parameter("false") + public static void test(boolean withWinConsole) throws IOException { + JPackageCommand cmd = JPackageCommand.helloAppImage(); + if (!withWinConsole) { + cmd.removeArgument("--win-console"); + } + cmd.executeAndAssertHelloAppImageCreated(); + checkSubsystem(cmd.appImage().resolve(cmd.launcherPathInAppImage()), + withWinConsole); } private static void checkSubsystem(Path path, boolean isConsole) throws @@ -69,7 +71,7 @@ try (InputStream inputStream = new FileInputStream(path.toString())) { byte[] bytes = new byte[bufferSize]; - Test.assertEquals(bufferSize, inputStream.read(bytes), + TKit.assertEquals(bufferSize, inputStream.read(bytes), String.format("Check %d bytes were read from %s file", bufferSize, path)); @@ -82,7 +84,7 @@ // Signature, File Header and subsystem offset. i = i + 4 + 20 + 68; byte subsystem = bytes[i]; - Test.assertEquals(expectedSubsystem, subsystem, + TKit.assertEquals(expectedSubsystem, subsystem, String.format("Check subsystem of PE [%s] file", path)); return; @@ -90,7 +92,7 @@ } } - Test.assertUnexpected(String.format( + TKit.assertUnexpected(String.format( "Subsystem not found in PE header of [%s] file", path)); } } diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/windows/WinDirChooserTest.java --- a/test/jdk/tools/jpackage/windows/WinDirChooserTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/windows/WinDirChooserTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -21,7 +21,7 @@ * questions. */ -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; @@ -37,6 +37,7 @@ * @test * @summary jpackage with --win-dir-chooser * @library ../helpers + * @build jdk.jpackage.test.* * @requires (os.family == "windows") * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m WinDirChooserTest @@ -44,7 +45,7 @@ public class WinDirChooserTest { public static void main(String[] args) { - Test.run(args, () -> { + TKit.run(args, () -> { new PackageTest() .forTypes(PackageType.WINDOWS) .configureHelloApp() diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/windows/WinMenuGroupTest.java --- a/test/jdk/tools/jpackage/windows/WinMenuGroupTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/windows/WinMenuGroupTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -21,7 +21,7 @@ * questions. */ -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; @@ -39,6 +39,7 @@ * @test * @summary jpackage with --win-menu and --win-menu-group * @library ../helpers + * @build jdk.jpackage.test.* * @requires (os.family == "windows") * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m WinMenuGroupTest @@ -46,7 +47,7 @@ public class WinMenuGroupTest { public static void main(String[] args) { - Test.run(args, () -> { + TKit.run(args, () -> { new PackageTest() .forTypes(PackageType.WINDOWS) .configureHelloApp() diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/windows/WinMenuTest.java --- a/test/jdk/tools/jpackage/windows/WinMenuTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/windows/WinMenuTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -21,7 +21,7 @@ * questions. */ -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; @@ -36,6 +36,7 @@ * @test * @summary jpackage with --win-menu * @library ../helpers + * @build jdk.jpackage.test.* * @requires (os.family == "windows") * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m WinMenuTest @@ -43,7 +44,7 @@ public class WinMenuTest { public static void main(String[] args) { - Test.run(args, () -> { + TKit.run(args, () -> { new PackageTest() .forTypes(PackageType.WINDOWS) .configureHelloApp() diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/windows/WinPerUserInstallTest.java --- a/test/jdk/tools/jpackage/windows/WinPerUserInstallTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/windows/WinPerUserInstallTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -21,7 +21,7 @@ * questions. */ -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; @@ -38,6 +38,7 @@ * @test * @summary jpackage with --win-per-user-install, --win-menu, --win-menu-group * @library ../helpers + * @build jdk.jpackage.test.* * @requires (os.family == "windows") * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m WinPerUserInstallTest @@ -45,7 +46,7 @@ public class WinPerUserInstallTest { public static void main(String[] args) { - Test.run(args, () -> { + TKit.run(args, () -> { new PackageTest() .forTypes(PackageType.WINDOWS) .configureHelloApp() diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/windows/WinShortcutTest.java --- a/test/jdk/tools/jpackage/windows/WinShortcutTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/windows/WinShortcutTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -21,7 +21,7 @@ * questions. */ -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; @@ -37,6 +37,7 @@ * @test * @summary jpackage with --win-shortcut * @library ../helpers + * @build jdk.jpackage.test.* * @requires (os.family == "windows") * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m WinShortcutTest @@ -44,7 +45,7 @@ public class WinShortcutTest { public static void main(String[] args) { - Test.run(args, () -> { + TKit.run(args, () -> { new PackageTest() .forTypes(PackageType.WINDOWS) .configureHelloApp() diff -r 73f8e557549a -r f09bf58c1f17 test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java --- a/test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java Mon Sep 30 15:59:50 2019 -0400 +++ b/test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java Mon Sep 30 19:11:19 2019 -0400 @@ -21,7 +21,7 @@ * questions. */ -import jdk.jpackage.test.Test; +import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; @@ -40,6 +40,7 @@ * @test * @summary jpackage with --win-upgrade-uuid and --app-version * @library ../helpers + * @build jdk.jpackage.test.* * @requires (os.family == "windows") * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m WinUpgradeUUIDTest @@ -47,7 +48,7 @@ public class WinUpgradeUUIDTest { public static void main(String[] args) { - Test.run(args, () -> { + TKit.run(args, () -> { PackageTest test = init(); if (test.getAction() != PackageTest.Action.VERIFY_INSTALL) { test.run();