8282007: Assorted enhancements to jpackage testing framework

Reviewed-by: almatvee
This commit is contained in:
Alexey Semenyuk 2022-02-17 05:27:41 +00:00
parent b6e48e6782
commit cd234f5dbe
17 changed files with 562 additions and 326 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -37,6 +37,7 @@ import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.stream.Stream; import java.util.stream.Stream;
import java.util.Collections; import java.util.Collections;
import java.util.Optional;
public class Hello implements OpenFilesHandler { public class Hello implements OpenFilesHandler {
@ -60,6 +61,15 @@ public class Hello implements OpenFilesHandler {
var outputFile = getOutputFile(args); var outputFile = getOutputFile(args);
trace(String.format("Output file: [%s]", outputFile)); trace(String.format("Output file: [%s]", outputFile));
Files.write(outputFile, lines); Files.write(outputFile, lines);
if (Optional.ofNullable(System.getProperty("jpackage.test.noexit")).map(
Boolean::parseBoolean).orElse(false)) {
trace("noexit");
var lock = new Object();
synchronized (lock) {
lock.wait();
}
}
} }
private static List<String> printArgs(String[] args) { private static List<String> printArgs(String[] args) {
@ -87,7 +97,8 @@ public class Hello implements OpenFilesHandler {
} }
private static Path getOutputFile(String[] args) { private static Path getOutputFile(String[] args) {
Path outputFilePath = Path.of("appOutput.txt"); Path outputFilePath = Path.of(Optional.ofNullable(System.getProperty(
"jpackage.test.appOutput")).orElse("appOutput.txt"));
// If first arg is a file (most likely from fa), then put output in the same folder as // If first arg is a file (most likely from fa), then put output in the same folder as
// the file from fa. // the file from fa.
@ -101,7 +112,7 @@ public class Hello implements OpenFilesHandler {
try { try {
// Try writing in the default output file. // Try writing in the default output file.
Files.write(outputFilePath, Collections.emptyList()); Files.write(outputFilePath, Collections.emptyList());
return outputFilePath; return outputFilePath.toAbsolutePath();
} catch (IOException ex) { } catch (IOException ex) {
// Log reason of a failure. // Log reason of a failure.
StringWriter errors = new StringWriter(); StringWriter errors = new StringWriter();
@ -109,7 +120,7 @@ public class Hello implements OpenFilesHandler {
Stream.of(errors.toString().split("\\R")).forEachOrdered(Hello::trace); Stream.of(errors.toString().split("\\R")).forEachOrdered(Hello::trace);
} }
return Path.of(System.getProperty("user.home")).resolve(outputFilePath); return Path.of(System.getProperty("user.home")).resolve(outputFilePath).toAbsolutePath();
} }
@Override @Override

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,13 +29,17 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import jdk.jpackage.internal.ApplicationLayout;
import jdk.jpackage.test.Functional.ThrowingBiConsumer; import jdk.jpackage.test.Functional.ThrowingBiConsumer;
import static jdk.jpackage.test.Functional.ThrowingFunction.toFunction;
public final class AdditionalLauncher { public class AdditionalLauncher {
public AdditionalLauncher(String name) { public AdditionalLauncher(String name) {
this.name = name; this.name = name;
@ -43,12 +47,12 @@ public final class AdditionalLauncher {
setPersistenceHandler(null); setPersistenceHandler(null);
} }
public AdditionalLauncher setDefaultArguments(String... v) { final public AdditionalLauncher setDefaultArguments(String... v) {
defaultArguments = new ArrayList<>(List.of(v)); defaultArguments = new ArrayList<>(List.of(v));
return this; return this;
} }
public AdditionalLauncher addDefaultArguments(String... v) { final public AdditionalLauncher addDefaultArguments(String... v) {
if (defaultArguments == null) { if (defaultArguments == null) {
return setDefaultArguments(v); return setDefaultArguments(v);
} }
@ -57,12 +61,12 @@ public final class AdditionalLauncher {
return this; return this;
} }
public AdditionalLauncher setJavaOptions(String... v) { final public AdditionalLauncher setJavaOptions(String... v) {
javaOptions = new ArrayList<>(List.of(v)); javaOptions = new ArrayList<>(List.of(v));
return this; return this;
} }
public AdditionalLauncher addJavaOptions(String... v) { final public AdditionalLauncher addJavaOptions(String... v) {
if (javaOptions == null) { if (javaOptions == null) {
return setJavaOptions(v); return setJavaOptions(v);
} }
@ -71,23 +75,24 @@ public final class AdditionalLauncher {
return this; return this;
} }
public AdditionalLauncher addRawProperties(Map.Entry<String, String>... v) { final public AdditionalLauncher addRawProperties(
Map.Entry<String, String>... v) {
return addRawProperties(List.of(v)); return addRawProperties(List.of(v));
} }
public AdditionalLauncher addRawProperties( final public AdditionalLauncher addRawProperties(
Collection<Map.Entry<String, String>> v) { Collection<Map.Entry<String, String>> v) {
rawProperties.addAll(v); rawProperties.addAll(v);
return this; return this;
} }
public AdditionalLauncher setShortcuts(boolean menu, boolean shortcut) { final public AdditionalLauncher setShortcuts(boolean menu, boolean shortcut) {
withMenuShortcut = menu; withMenuShortcut = menu;
withShortcut = shortcut; withShortcut = shortcut;
return this; return this;
} }
public AdditionalLauncher setIcon(Path iconPath) { final public AdditionalLauncher setIcon(Path iconPath) {
if (iconPath == NO_ICON) { if (iconPath == NO_ICON) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
@ -96,12 +101,12 @@ public final class AdditionalLauncher {
return this; return this;
} }
public AdditionalLauncher setNoIcon() { final public AdditionalLauncher setNoIcon() {
icon = NO_ICON; icon = NO_ICON;
return this; return this;
} }
public AdditionalLauncher setPersistenceHandler( final public AdditionalLauncher setPersistenceHandler(
ThrowingBiConsumer<Path, List<Map.Entry<String, String>>> handler) { ThrowingBiConsumer<Path, List<Map.Entry<String, String>>> handler) {
if (handler != null) { if (handler != null) {
createFileHandler = ThrowingBiConsumer.toBiConsumer(handler); createFileHandler = ThrowingBiConsumer.toBiConsumer(handler);
@ -111,19 +116,53 @@ public final class AdditionalLauncher {
return this; return this;
} }
public void applyTo(JPackageCommand cmd) { final public void applyTo(JPackageCommand cmd) {
cmd.addPrerequisiteAction(this::initialize); cmd.addPrerequisiteAction(this::initialize);
cmd.addVerifyAction(this::verify); cmd.addVerifyAction(this::verify);
} }
public void applyTo(PackageTest test) { final public void applyTo(PackageTest test) {
test.addLauncherName(name);
test.addInitializer(this::initialize); test.addInitializer(this::initialize);
test.addInstallVerifier(this::verify); test.addInstallVerifier(this::verify);
} }
static void forEachAdditionalLauncher(JPackageCommand cmd,
BiConsumer<String, Path> consumer) {
var argIt = cmd.getAllArguments().iterator();
while (argIt.hasNext()) {
if ("--add-launcher".equals(argIt.next())) {
// <launcherName>=<propFile>
var arg = argIt.next();
var items = arg.split("=", 2);
consumer.accept(items[0], Path.of(items[1]));
}
}
}
static PropertyFile getAdditionalLauncherProperties(
JPackageCommand cmd, String launcherName) {
PropertyFile shell[] = new PropertyFile[1];
forEachAdditionalLauncher(cmd, (name, propertiesFilePath) -> {
if (name.equals(launcherName)) {
shell[0] = toFunction(PropertyFile::new).apply(
propertiesFilePath);
}
});
return Optional.of(shell[0]).get();
}
private void initialize(JPackageCommand cmd) { private void initialize(JPackageCommand cmd) {
final Path propsFile = TKit.workDir().resolve(name + ".properties"); Path propsFile = TKit.workDir().resolve(name + ".properties");
if (Files.exists(propsFile)) {
// File with the given name exists, pick another name that
// will not reference existing file.
try {
propsFile = TKit.createTempFile(propsFile);
TKit.deleteIfExists(propsFile);
} catch (IOException ex) {
Functional.rethrowUnchecked(ex);
}
}
cmd.addArguments("--add-launcher", String.format("%s=%s", name, cmd.addArguments("--add-launcher", String.format("%s=%s", name,
propsFile)); propsFile));
@ -242,7 +281,7 @@ public final class AdditionalLauncher {
} }
} }
private void verify(JPackageCommand cmd) throws IOException { protected void verify(JPackageCommand cmd) throws IOException {
verifyIcon(cmd); verifyIcon(cmd);
verifyShortcuts(cmd); verifyShortcuts(cmd);
@ -255,14 +294,60 @@ public final class AdditionalLauncher {
return; return;
} }
HelloApp.assertApp(launcherPath) var appVerifier = HelloApp.assertApp(launcherPath)
.addDefaultArguments(Optional .addDefaultArguments(Optional
.ofNullable(defaultArguments) .ofNullable(defaultArguments)
.orElseGet(() -> List.of(cmd.getAllArgumentValues("--arguments")))) .orElseGet(() -> List.of(cmd.getAllArgumentValues("--arguments"))))
.addJavaOptions(Optional .addJavaOptions(Optional
.ofNullable(javaOptions) .ofNullable(javaOptions)
.orElseGet(() -> List.of(cmd.getAllArgumentValues("--java-options")))) .orElseGet(() -> List.of(cmd.getAllArgumentValues(
.executeAndVerifyOutput(); "--java-options"))).stream().map(
str -> resolveVariables(cmd, str)).toList());
appVerifier.executeAndVerifyOutput();
}
public static final class PropertyFile {
PropertyFile(Path path) throws IOException {
data = Files.readAllLines(path).stream().map(str -> {
return str.split("=", 2);
}).collect(
Collectors.toMap(tokens -> tokens[0], tokens -> tokens[1],
(oldValue, newValue) -> {
return newValue;
}));
}
public boolean isPropertySet(String name) {
Objects.requireNonNull(name);
return data.containsKey(name);
}
public Optional<String> getPropertyValue(String name) {
Objects.requireNonNull(name);
return Optional.of(data.get(name));
}
public Optional<Boolean> getPropertyBooleanValue(String name) {
Objects.requireNonNull(name);
return Optional.ofNullable(data.get(name)).map(Boolean::parseBoolean);
}
private final Map<String, String> data;
}
private static String resolveVariables(JPackageCommand cmd, String str) {
var map = Map.of(
"$APPDIR", cmd.appLayout().appDirectory(),
"$ROOTDIR",
cmd.isImagePackageType() ? cmd.outputBundle() : cmd.appInstallationDirectory(),
"$BINDIR", cmd.appLayout().launchersDirectory());
for (var e : map.entrySet()) {
str = str.replaceAll(Pattern.quote(e.getKey()),
Matcher.quoteReplacement(e.getValue().toString()));
}
return str;
} }
private List<String> javaOptions; private List<String> javaOptions;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,6 +29,7 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -85,7 +86,8 @@ public final class CfgFile {
} }
if (!currentSection.isEmpty()) { if (!currentSection.isEmpty()) {
result.put("", Collections.unmodifiableMap(currentSection)); result.put(Optional.ofNullable(currentSectionName).orElse(""),
Collections.unmodifiableMap(currentSection));
} }
return new CfgFile(Collections.unmodifiableMap(result), path.toString()); return new CfgFile(Collections.unmodifiableMap(result), path.toString());

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -90,8 +90,10 @@ public final class Executor extends CommandArguments<Executor> {
} }
public Executor setWindowsTmpDir(String tmp) { public Executor setWindowsTmpDir(String tmp) {
TKit.assertTrue(TKit.isWindows(), if (!TKit.isWindows()) {
"setWindowsTmpDir is only valid on Windows platform"); throw new UnsupportedOperationException(
"setWindowsTmpDir is only valid on Windows platform");
}
winTmpDir = tmp; winTmpDir = tmp;
return this; return this;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -351,6 +351,7 @@ public final class HelloApp {
public final static class AppOutputVerifier { public final static class AppOutputVerifier {
AppOutputVerifier(Path helloAppLauncher) { AppOutputVerifier(Path helloAppLauncher) {
this.launcherPath = helloAppLauncher; this.launcherPath = helloAppLauncher;
this.outputFilePath = TKit.workDir().resolve(OUTPUT_FILENAME);
this.params = new HashMap<>(); this.params = new HashMap<>();
this.defaultLauncherArgs = new ArrayList<>(); this.defaultLauncherArgs = new ArrayList<>();
} }
@ -367,6 +368,8 @@ public final class HelloApp {
public AppOutputVerifier addParam(String name, String value) { public AppOutputVerifier addParam(String name, String value) {
if (name.startsWith("param")) { if (name.startsWith("param")) {
params.put(name, value); params.put(name, value);
} else if ("jpackage.test.appOutput".equals(name)) {
outputFilePath = Path.of(value);
} }
return this; return this;
} }
@ -397,6 +400,18 @@ public final class HelloApp {
.collect(Collectors.toList())); .collect(Collectors.toList()));
} }
public void verifyOutput(String... args) {
final List<String> launcherArgs = List.of(args);
final List<String> appArgs;
if (launcherArgs.isEmpty()) {
appArgs = defaultLauncherArgs;
} else {
appArgs = launcherArgs;
}
verifyOutputFile(outputFilePath, appArgs, params);
}
public void executeAndVerifyOutput(String... args) { public void executeAndVerifyOutput(String... args) {
executeAndVerifyOutput(false, args); executeAndVerifyOutput(false, args);
} }
@ -408,8 +423,7 @@ public final class HelloApp {
getExecutor(launcherArgs.toArray(new String[0])).dumpOutput().setRemovePath( getExecutor(launcherArgs.toArray(new String[0])).dumpOutput().setRemovePath(
removePath).executeAndRepeatUntilExitCode(0, attempts, removePath).executeAndRepeatUntilExitCode(0, attempts,
waitBetweenAttemptsSeconds); waitBetweenAttemptsSeconds);
Path outputFile = TKit.workDir().resolve(OUTPUT_FILENAME); verifyOutputFile(outputFilePath, appArgs, params);
verifyOutputFile(outputFile, appArgs, params);
} }
public void executeAndVerifyOutput(boolean removePath, String... args) { public void executeAndVerifyOutput(boolean removePath, String... args) {
@ -453,6 +467,7 @@ public final class HelloApp {
} }
private final Path launcherPath; private final Path launcherPath;
private Path outputFilePath;
private final List<String> defaultLauncherArgs; private final List<String> defaultLauncherArgs;
private final Map<String, String> params; private final Map<String, String> params;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -47,6 +47,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import jdk.jpackage.internal.AppImageFile; import jdk.jpackage.internal.AppImageFile;
import jdk.jpackage.internal.ApplicationLayout; import jdk.jpackage.internal.ApplicationLayout;
import static jdk.jpackage.test.AdditionalLauncher.forEachAdditionalLauncher;
import jdk.jpackage.test.Functional.ThrowingConsumer; import jdk.jpackage.test.Functional.ThrowingConsumer;
import jdk.jpackage.test.Functional.ThrowingFunction; import jdk.jpackage.test.Functional.ThrowingFunction;
import jdk.jpackage.test.Functional.ThrowingSupplier; import jdk.jpackage.test.Functional.ThrowingSupplier;
@ -242,6 +243,17 @@ public final class JPackageCommand extends CommandArguments<JPackageCommand> {
return this; return this;
} }
public JPackageCommand setInputToEmptyDirectory() {
if (Files.exists(inputDir())) {
try {
setArgumentValue("--input", TKit.createTempDirectory("input"));
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
return this;
}
public JPackageCommand setFakeRuntime() { public JPackageCommand setFakeRuntime() {
verifyMutable(); verifyMutable();
@ -414,6 +426,28 @@ public final class JPackageCommand extends CommandArguments<JPackageCommand> {
return unpackDir.resolve(TKit.removeRootFromAbsolutePath(path)); return unpackDir.resolve(TKit.removeRootFromAbsolutePath(path));
} }
/**
* Returns path to package file from the path in unpacked package directory
* or the given path if the package is not unpacked.
*/
public Path pathToPackageFile(Path path) {
Path unpackDir = unpackedPackageDirectory();
if (unpackDir == null) {
if (!path.isAbsolute()) {
throw new IllegalArgumentException(String.format(
"Path [%s] is not absolute", path));
}
return path;
}
if (!path.startsWith(unpackDir)) {
throw new IllegalArgumentException(String.format(
"Path [%s] doesn't start with [%s] path", path, unpackDir));
}
return Path.of("/").resolve(unpackDir.relativize(path));
}
Path unpackedPackageDirectory() { Path unpackedPackageDirectory() {
verifyIsOfType(PackageType.NATIVE); verifyIsOfType(PackageType.NATIVE);
return getArgumentValue(UNPACKED_PATH_ARGNAME, () -> null, Path::of); return getArgumentValue(UNPACKED_PATH_ARGNAME, () -> null, Path::of);
@ -497,6 +531,18 @@ public final class JPackageCommand extends CommandArguments<JPackageCommand> {
return appLauncherPath(null); return appLauncherPath(null);
} }
/**
* Returns names of all additional launchers or empty list if none
* configured.
*/
public List<String> addLauncherNames() {
List<String> names = new ArrayList<>();
forEachAdditionalLauncher(this, (launcherName, propFile) -> {
names.add(launcherName);
});
return names;
}
private void verifyNotRuntime() { private void verifyNotRuntime() {
if (isRuntime()) { if (isRuntime()) {
throw new IllegalArgumentException("Java runtime packaging"); throw new IllegalArgumentException("Java runtime packaging");
@ -537,9 +583,9 @@ public final class JPackageCommand extends CommandArguments<JPackageCommand> {
throw TKit.throwUnknownPlatformError(); throw TKit.throwUnknownPlatformError();
} }
if (criticalRuntimeFiles.stream().filter( if (!criticalRuntimeFiles.stream().anyMatch(v -> {
v -> runtimeDir.resolve(v).toFile().exists()).findFirst().orElse( return runtimeDir.resolve(v).toFile().exists();
null) == null) { })) {
// Fake runtime // Fake runtime
TKit.trace(String.format( TKit.trace(String.format(
"%s because application runtime directory [%s] is incomplete", "%s because application runtime directory [%s] is incomplete",
@ -738,7 +784,7 @@ public final class JPackageCommand extends CommandArguments<JPackageCommand> {
appImageFileName)); appImageFileName));
} }
} }
} else if (TKit.isOSX()) { } else if (TKit.isOSX() && !isRuntime()) {
TKit.assertFileExists(AppImageFile.getPathInAppImage( TKit.assertFileExists(AppImageFile.getPathInAppImage(
appInstallationDirectory())); appInstallationDirectory()));
} else { } else {
@ -763,7 +809,11 @@ public final class JPackageCommand extends CommandArguments<JPackageCommand> {
JPackageCommand setUnpackedPackageLocation(Path path) { JPackageCommand setUnpackedPackageLocation(Path path) {
verifyIsOfType(PackageType.NATIVE); verifyIsOfType(PackageType.NATIVE);
setArgumentValue(UNPACKED_PATH_ARGNAME, path); if (path != null) {
setArgumentValue(UNPACKED_PATH_ARGNAME, path);
} else {
removeArgumentWithValue(UNPACKED_PATH_ARGNAME);
}
return this; return this;
} }
@ -788,6 +838,11 @@ public final class JPackageCommand extends CommandArguments<JPackageCommand> {
return createExecutor().getPrintableCommandLine(); return createExecutor().getPrintableCommandLine();
} }
@Override
public String toString() {
return getPrintableCommandLine();
}
public void verifyIsOfType(Collection<PackageType> types) { public void verifyIsOfType(Collection<PackageType> types) {
verifyIsOfType(types.toArray(PackageType[]::new)); verifyIsOfType(types.toArray(PackageType[]::new));
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -40,7 +40,7 @@ public enum JavaTool {
} }
} }
Path getPath() { public Path getPath() {
return path; return path;
} }
@ -48,7 +48,7 @@ public enum JavaTool {
return ToolProvider.findFirst(toolName()).orElse(null); return ToolProvider.findFirst(toolName()).orElse(null);
} }
Path relativePathInJavaHome() { private Path relativePathInJavaHome() {
Path path = Path.of("bin", toolName()); Path path = Path.of("bin", toolName());
if (TKit.isWindows()) { if (TKit.isWindows()) {
path = path.getParent().resolve(path.getFileName().toString() + ".exe"); path = path.getParent().resolve(path.getFileName().toString() + ".exe");

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -42,8 +42,7 @@ import jdk.jpackage.internal.IOUtils;
import jdk.jpackage.test.PackageTest.PackageHandlers; import jdk.jpackage.test.PackageTest.PackageHandlers;
public final class LinuxHelper {
public class LinuxHelper {
private static String getReleaseSuffix(JPackageCommand cmd) { private static String getReleaseSuffix(JPackageCommand cmd) {
String value = null; String value = null;
final PackageType packageType = cmd.packageType(); final PackageType packageType = cmd.packageType();
@ -183,7 +182,10 @@ public class LinuxHelper {
}; };
deb.uninstallHandler = cmd -> { deb.uninstallHandler = cmd -> {
cmd.verifyIsOfType(PackageType.LINUX_DEB); cmd.verifyIsOfType(PackageType.LINUX_DEB);
Executor.of("sudo", "dpkg", "-r", getPackageName(cmd)).execute(); var packageName = getPackageName(cmd);
String script = String.format("! dpkg -s %s || sudo dpkg -r %s",
packageName, packageName);
Executor.of("sh", "-c", script).execute();
}; };
deb.unpackHandler = (cmd, destinationDir) -> { deb.unpackHandler = (cmd, destinationDir) -> {
cmd.verifyIsOfType(PackageType.LINUX_DEB); cmd.verifyIsOfType(PackageType.LINUX_DEB);
@ -200,13 +202,16 @@ public class LinuxHelper {
PackageHandlers rpm = new PackageHandlers(); PackageHandlers rpm = new PackageHandlers();
rpm.installHandler = cmd -> { rpm.installHandler = cmd -> {
cmd.verifyIsOfType(PackageType.LINUX_RPM); cmd.verifyIsOfType(PackageType.LINUX_RPM);
Executor.of("sudo", "rpm", "-i") Executor.of("sudo", "rpm", "-U")
.addArgument(cmd.outputBundle()) .addArgument(cmd.outputBundle())
.execute(); .execute();
}; };
rpm.uninstallHandler = cmd -> { rpm.uninstallHandler = cmd -> {
cmd.verifyIsOfType(PackageType.LINUX_RPM); cmd.verifyIsOfType(PackageType.LINUX_RPM);
Executor.of("sudo", "rpm", "-e", getPackageName(cmd)).execute(); var packageName = getPackageName(cmd);
String script = String.format("! rpm -q %s || sudo rpm -e %s",
packageName, packageName);
Executor.of("sh", "-c", script).execute();
}; };
rpm.unpackHandler = (cmd, destinationDir) -> { rpm.unpackHandler = (cmd, destinationDir) -> {
cmd.verifyIsOfType(PackageType.LINUX_RPM); cmd.verifyIsOfType(PackageType.LINUX_RPM);
@ -363,10 +368,10 @@ public class LinuxHelper {
test.addInstallVerifier(cmd -> { test.addInstallVerifier(cmd -> {
// Verify .desktop files. // Verify .desktop files.
try (var files = Files.walk(cmd.appLayout().destktopIntegrationDirectory(), 1)) { try (var files = Files.list(cmd.appLayout().destktopIntegrationDirectory())) {
List<Path> desktopFiles = files List<Path> desktopFiles = files
.filter(path -> path.getFileName().toString().endsWith(".desktop")) .filter(path -> path.getFileName().toString().endsWith(".desktop"))
.collect(Collectors.toList()); .toList();
if (!integrated) { if (!integrated) {
TKit.assertStringListEquals(List.of(), TKit.assertStringListEquals(List.of(),
desktopFiles.stream().map(Path::toString).collect( desktopFiles.stream().map(Path::toString).collect(
@ -470,23 +475,18 @@ public class LinuxHelper {
String desktopFileName = queryMimeTypeDefaultHandler(mimeType); String desktopFileName = queryMimeTypeDefaultHandler(mimeType);
Path desktopFile = getSystemDesktopFilesFolder().resolve( Path systemDesktopFile = getSystemDesktopFilesFolder().resolve(
desktopFileName);
Path appDesktopFile = cmd.appLayout().destktopIntegrationDirectory().resolve(
desktopFileName); desktopFileName);
TKit.assertFileExists(desktopFile); TKit.assertFileExists(systemDesktopFile);
TKit.assertFileExists(appDesktopFile);
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();
TKit.trace(String.format("Done"));
TKit.assertEquals(cmd.appLauncherPath().toString(),
mimeHandler, String.format(
"Check mime type handler is the main application launcher"));
TKit.assertStringListEquals(Files.readAllLines(appDesktopFile),
Files.readAllLines(systemDesktopFile), String.format(
"Check [%s] file is a copy of [%s] file",
systemDesktopFile, appDesktopFile));
}); });
}); });

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -39,6 +39,7 @@ import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath; import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathFactory;
import jdk.jpackage.internal.IOUtils;
import jdk.jpackage.test.Functional.ThrowingConsumer; import jdk.jpackage.test.Functional.ThrowingConsumer;
import jdk.jpackage.test.Functional.ThrowingSupplier; import jdk.jpackage.test.Functional.ThrowingSupplier;
import jdk.jpackage.test.PackageTest.PackageHandlers; import jdk.jpackage.test.PackageTest.PackageHandlers;
@ -46,7 +47,7 @@ import jdk.jpackage.internal.RetryExecutor;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
public class MacHelper { public final class MacHelper {
public static void withExplodedDmg(JPackageCommand cmd, public static void withExplodedDmg(JPackageCommand cmd,
ThrowingConsumer<Path> consumer) { ThrowingConsumer<Path> consumer) {
@ -172,41 +173,62 @@ public class MacHelper {
pkg.installHandler = cmd -> { pkg.installHandler = cmd -> {
cmd.verifyIsOfType(PackageType.MAC_PKG); cmd.verifyIsOfType(PackageType.MAC_PKG);
Executor.of("sudo", "/usr/sbin/installer", "-allowUntrusted", "-pkg") Executor.of("sudo", "/usr/sbin/installer", "-allowUntrusted", "-pkg")
.addArgument(cmd.outputBundle()) .addArgument(cmd.outputBundle())
.addArguments("-target", "/") .addArguments("-target", "/")
.execute(); .execute();
}; };
pkg.unpackHandler = (cmd, destinationDir) -> { pkg.unpackHandler = (cmd, destinationDir) -> {
cmd.verifyIsOfType(PackageType.MAC_PKG); cmd.verifyIsOfType(PackageType.MAC_PKG);
var dataDir = destinationDir.resolve("data");
Executor.of("pkgutil", "--expand") Executor.of("pkgutil", "--expand")
.addArgument(cmd.outputBundle()) .addArgument(cmd.outputBundle())
.addArgument(destinationDir.resolve("data")) // We need non-existing folder .addArgument(dataDir) // We need non-existing folder
.execute(); .execute();
final Path unpackRoot = destinationDir.resolve("unpacked"); final Path unpackRoot = destinationDir.resolve("unpacked");
Path installDir = TKit.removeRootFromAbsolutePath( // Unpack all ".pkg" files from $dataDir folder in $unpackDir folder
getInstallationDirectory(cmd)).getParent(); try (var dataListing = Files.list(dataDir)) {
final Path unpackDir = unpackRoot.resolve(installDir); dataListing.filter(file -> {
try { return ".pkg".equals(IOUtils.getSuffix(file.getFileName()));
Files.createDirectories(unpackDir); }).forEach(ThrowingConsumer.toConsumer(pkgDir -> {
// Installation root of the package is stored in
// /pkg-info@install-location attribute in $pkgDir/PackageInfo xml file
var doc = createDocumentBuilder().parse(
new ByteArrayInputStream(Files.readAllBytes(
pkgDir.resolve("PackageInfo"))));
var xPath = XPathFactory.newInstance().newXPath();
final String installRoot = (String) xPath.evaluate(
"/pkg-info/@install-location", doc,
XPathConstants.STRING);
final Path unpackDir = unpackRoot.resolve(
TKit.removeRootFromAbsolutePath(Path.of(installRoot)));
Files.createDirectories(unpackDir);
Executor.of("tar", "-C")
.addArgument(unpackDir)
.addArgument("-xvf")
.addArgument(pkgDir.resolve("Payload"))
.execute();
}));
} catch (IOException ex) { } catch (IOException ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
Executor.of("tar", "-C")
.addArgument(unpackDir)
.addArgument("-xvf")
.addArgument(Path.of(destinationDir.toString(), "data",
cmd.name() + "-app.pkg", "Payload"))
.execute();
return unpackRoot; return unpackRoot;
}; };
pkg.uninstallHandler = cmd -> { pkg.uninstallHandler = cmd -> {
cmd.verifyIsOfType(PackageType.MAC_PKG); cmd.verifyIsOfType(PackageType.MAC_PKG);
Executor.of("sudo", "rm", "-rf") Executor.of("sudo", "rm", "-rf")
.addArgument(cmd.appInstallationDirectory()) .addArgument(cmd.appInstallationDirectory())
.execute(); .execute();
}; };
return pkg; return pkg;
@ -220,13 +242,13 @@ public class MacHelper {
static Path getInstallationDirectory(JPackageCommand cmd) { static Path getInstallationDirectory(JPackageCommand cmd) {
cmd.verifyIsOfType(PackageType.MAC); cmd.verifyIsOfType(PackageType.MAC);
return Path.of(cmd.getArgumentValue("--install-dir", () -> "/Applications")) return Path.of(cmd.getArgumentValue("--install-dir",
.resolve(cmd.name() + (cmd.isRuntime() ? "" : ".app")); () -> cmd.isRuntime() ? "/Library/Java/JavaVirtualMachines" : "/Applications")).resolve(
cmd.name() + (cmd.isRuntime() ? "" : ".app"));
} }
private static String getPackageName(JPackageCommand cmd) { private static String getPackageName(JPackageCommand cmd) {
return cmd.getArgumentValue("--mac-package-name", return cmd.getArgumentValue("--mac-package-name", cmd::installerName);
() -> cmd.installerName());
} }
public static final class PListWrapper { public static final class PListWrapper {
@ -274,25 +296,24 @@ public class MacHelper {
return values; return values;
} }
PListWrapper(String xml) throws ParserConfigurationException, private PListWrapper(String xml) throws ParserConfigurationException,
SAXException, IOException { SAXException, IOException {
doc = createDocumentBuilder().parse(new ByteArrayInputStream( doc = createDocumentBuilder().parse(new ByteArrayInputStream(
xml.getBytes(StandardCharsets.UTF_8))); xml.getBytes(StandardCharsets.UTF_8)));
} }
private static DocumentBuilder createDocumentBuilder() throws
ParserConfigurationException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultInstance();
dbf.setFeature(
"http://apache.org/xml/features/nonvalidating/load-external-dtd",
false);
return dbf.newDocumentBuilder();
}
private final org.w3c.dom.Document doc; private final org.w3c.dom.Document doc;
} }
private static DocumentBuilder createDocumentBuilder() throws
ParserConfigurationException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultInstance();
dbf.setFeature(
"http://apache.org/xml/features/nonvalidating/load-external-dtd",
false);
return dbf.newDocumentBuilder();
}
static final Set<Path> CRITICAL_RUNTIME_FILES = Set.of(Path.of( static final Set<Path> CRITICAL_RUNTIME_FILES = Set.of(Path.of(
"Contents/Home/lib/server/libjvm.dylib")); "Contents/Home/lib/server/libjvm.dylib"));
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,7 @@ package jdk.jpackage.test;
import java.awt.Desktop; import java.awt.Desktop;
import java.awt.GraphicsEnvironment; import java.awt.GraphicsEnvironment;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
@ -36,19 +37,32 @@ import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import jdk.jpackage.internal.AppImageFile;
import jdk.jpackage.internal.ApplicationLayout; import jdk.jpackage.internal.ApplicationLayout;
import jdk.jpackage.test.Functional.ThrowingBiConsumer; import jdk.jpackage.test.Functional.ThrowingBiConsumer;
import static jdk.jpackage.test.Functional.ThrowingBiConsumer.toBiConsumer;
import jdk.jpackage.test.Functional.ThrowingConsumer; import jdk.jpackage.test.Functional.ThrowingConsumer;
import static jdk.jpackage.test.Functional.ThrowingConsumer.toConsumer;
import jdk.jpackage.test.Functional.ThrowingRunnable; import jdk.jpackage.test.Functional.ThrowingRunnable;
import static jdk.jpackage.test.Functional.ThrowingSupplier.toSupplier;
import static jdk.jpackage.test.Functional.rethrowUnchecked;
import static jdk.jpackage.test.PackageType.LINUX;
import static jdk.jpackage.test.PackageType.LINUX_DEB;
import static jdk.jpackage.test.PackageType.LINUX_RPM;
import static jdk.jpackage.test.PackageType.MAC_DMG;
import static jdk.jpackage.test.PackageType.MAC_PKG;
import static jdk.jpackage.test.PackageType.NATIVE;
import static jdk.jpackage.test.PackageType.WINDOWS;
import static jdk.jpackage.test.PackageType.WIN_EXE;
import static jdk.jpackage.test.PackageType.WIN_MSI;
/** /**
@ -82,7 +96,7 @@ public final class PackageTest extends RunnablePackageTest {
public PackageTest forTypes(PackageType... types) { public PackageTest forTypes(PackageType... types) {
Collection<PackageType> newTypes; Collection<PackageType> newTypes;
if (types == null || types.length == 0) { if (types == null || types.length == 0) {
newTypes = PackageType.NATIVE; newTypes = NATIVE;
} else { } else {
newTypes = Stream.of(types).collect(Collectors.toSet()); newTypes = Stream.of(types).collect(Collectors.toSet());
} }
@ -122,7 +136,7 @@ public final class PackageTest extends RunnablePackageTest {
namedInitializers.add(id); namedInitializers.add(id);
} }
currentTypes.forEach(type -> handlers.get(type).addInitializer( currentTypes.forEach(type -> handlers.get(type).addInitializer(
ThrowingConsumer.toConsumer(v))); toConsumer(v)));
return this; return this;
} }
@ -151,13 +165,12 @@ public final class PackageTest extends RunnablePackageTest {
public PackageTest addBundleVerifier( public PackageTest addBundleVerifier(
ThrowingBiConsumer<JPackageCommand, Executor.Result> v) { ThrowingBiConsumer<JPackageCommand, Executor.Result> v) {
currentTypes.forEach(type -> handlers.get(type).addBundleVerifier( currentTypes.forEach(type -> handlers.get(type).addBundleVerifier(
ThrowingBiConsumer.toBiConsumer(v))); toBiConsumer(v)));
return this; return this;
} }
public PackageTest addBundleVerifier(ThrowingConsumer<JPackageCommand> v) { public PackageTest addBundleVerifier(ThrowingConsumer<JPackageCommand> v) {
return addBundleVerifier( return addBundleVerifier((cmd, unused) -> toConsumer(v).accept(cmd));
(cmd, unused) -> ThrowingConsumer.toConsumer(v).accept(cmd));
} }
public PackageTest addBundlePropertyVerifier(String propertyName, public PackageTest addBundlePropertyVerifier(String propertyName,
@ -184,7 +197,7 @@ public final class PackageTest extends RunnablePackageTest {
} }
public PackageTest addBundleDesktopIntegrationVerifier(boolean integrated) { public PackageTest addBundleDesktopIntegrationVerifier(boolean integrated) {
forTypes(PackageType.LINUX, () -> { forTypes(LINUX, () -> {
LinuxHelper.addBundleDesktopIntegrationVerifier(this, integrated); LinuxHelper.addBundleDesktopIntegrationVerifier(this, integrated);
}); });
return this; return this;
@ -192,31 +205,25 @@ public final class PackageTest extends RunnablePackageTest {
public PackageTest addInstallVerifier(ThrowingConsumer<JPackageCommand> v) { public PackageTest addInstallVerifier(ThrowingConsumer<JPackageCommand> v) {
currentTypes.forEach(type -> handlers.get(type).addInstallVerifier( currentTypes.forEach(type -> handlers.get(type).addInstallVerifier(
ThrowingConsumer.toConsumer(v))); toConsumer(v)));
return this; return this;
} }
public PackageTest addUninstallVerifier(ThrowingConsumer<JPackageCommand> v) { public PackageTest addUninstallVerifier(ThrowingConsumer<JPackageCommand> v) {
currentTypes.forEach(type -> handlers.get(type).addUninstallVerifier( currentTypes.forEach(type -> handlers.get(type).addUninstallVerifier(
ThrowingConsumer.toConsumer(v))); toConsumer(v)));
return this; return this;
} }
public PackageTest setPackageInstaller(Consumer<JPackageCommand> v) { public PackageTest disablePackageInstaller() {
currentTypes.forEach( currentTypes.forEach(
type -> packageHandlers.get(type).installHandler = v); type -> packageHandlers.get(type).installHandler = cmd -> {});
return this; return this;
} }
public PackageTest setPackageUnpacker( public PackageTest disablePackageUninstaller() {
BiFunction<JPackageCommand, Path, Path> v) {
currentTypes.forEach(type -> packageHandlers.get(type).unpackHandler = v);
return this;
}
public PackageTest setPackageUninstaller(Consumer<JPackageCommand> v) {
currentTypes.forEach( currentTypes.forEach(
type -> packageHandlers.get(type).uninstallHandler = v); type -> packageHandlers.get(type).uninstallHandler = cmd -> {});
return this; return this;
} }
@ -238,7 +245,7 @@ public final class PackageTest extends RunnablePackageTest {
// running check of type of environment. // running check of type of environment.
addHelloAppInitializer(null); addHelloAppInitializer(null);
forTypes(PackageType.LINUX, () -> { forTypes(LINUX, () -> {
LinuxHelper.addFileAssociationsVerifier(this, fa); LinuxHelper.addFileAssociationsVerifier(this, fa);
}); });
@ -317,11 +324,6 @@ public final class PackageTest extends RunnablePackageTest {
return this; return this;
} }
public PackageTest addLauncherName(String name) {
launcherNames.add(name);
return this;
}
public final static class Group extends RunnablePackageTest { public final static class Group extends RunnablePackageTest {
public Group(PackageTest... tests) { public Group(PackageTest... tests) {
handlers = Stream.of(tests) handlers = Stream.of(tests)
@ -372,7 +374,7 @@ public final class PackageTest extends RunnablePackageTest {
} }
private List<Consumer<Action>> createPackageTypeHandlers() { private List<Consumer<Action>> createPackageTypeHandlers() {
return PackageType.NATIVE.stream() return NATIVE.stream()
.map(type -> { .map(type -> {
Handler handler = handlers.entrySet().stream() Handler handler = handlers.entrySet().stream()
.filter(entry -> !entry.getValue().isVoid()) .filter(entry -> !entry.getValue().isVoid())
@ -393,29 +395,39 @@ public final class PackageTest extends RunnablePackageTest {
private Consumer<Action> createPackageTypeHandler( private Consumer<Action> createPackageTypeHandler(
PackageType type, Handler handler) { PackageType type, Handler handler) {
return ThrowingConsumer.toConsumer(new ThrowingConsumer<Action>() { return toConsumer(new ThrowingConsumer<Action>() {
@Override @Override
public void accept(Action action) throws Throwable { public void accept(Action action) throws Throwable {
if (terminated) {
throw new IllegalStateException();
}
if (action == Action.FINALIZE) { if (action == Action.FINALIZE) {
if (unpackDir != null && Files.isDirectory(unpackDir) if (unpackDir != null) {
&& !unpackDir.startsWith(TKit.workDir())) { if (Files.isDirectory(unpackDir)
TKit.deleteDirectoryRecursive(unpackDir); && !unpackDir.startsWith(TKit.workDir())) {
TKit.deleteDirectoryRecursive(unpackDir);
}
unpackDir = null;
} }
terminated = true;
} }
if (aborted) { if (aborted) {
return; return;
} }
final JPackageCommand curCmd; final Supplier<JPackageCommand> curCmd = () -> {
if (Set.of(Action.INITIALIZE, Action.CREATE).contains(action)) { if (Set.of(Action.INITIALIZE, Action.CREATE).contains(action)) {
curCmd = cmd; return cmd;
} else { } else {
curCmd = cmd.createImmutableCopy(); return cmd.createImmutableCopy();
} }
};
switch (action) { switch (action) {
case UNPACK: { case UNPACK: {
cmd.setUnpackedPackageLocation(null);
var handler = packageHandlers.get(type).unpackHandler; var handler = packageHandlers.get(type).unpackHandler;
if (!(aborted = (handler == null))) { if (!(aborted = (handler == null))) {
unpackDir = TKit.createTempDirectory( unpackDir = TKit.createTempDirectory(
@ -428,9 +440,10 @@ public final class PackageTest extends RunnablePackageTest {
} }
case INSTALL: { case INSTALL: {
cmd.setUnpackedPackageLocation(null);
var handler = packageHandlers.get(type).installHandler; var handler = packageHandlers.get(type).installHandler;
if (!(aborted = (handler == null))) { if (!(aborted = (handler == null))) {
handler.accept(curCmd); handler.accept(curCmd.get());
} }
break; break;
} }
@ -438,18 +451,19 @@ public final class PackageTest extends RunnablePackageTest {
case UNINSTALL: { case UNINSTALL: {
var handler = packageHandlers.get(type).uninstallHandler; var handler = packageHandlers.get(type).uninstallHandler;
if (!(aborted = (handler == null))) { if (!(aborted = (handler == null))) {
handler.accept(curCmd); handler.accept(curCmd.get());
} }
break; break;
} }
case CREATE: case CREATE:
handler.accept(action, curCmd); cmd.setUnpackedPackageLocation(null);
handler.accept(action, curCmd.get());
aborted = (expectedJPackageExitCode != 0); aborted = (expectedJPackageExitCode != 0);
return; return;
default: default:
handler.accept(action, curCmd); handler.accept(action, curCmd.get());
break; break;
} }
@ -462,6 +476,7 @@ public final class PackageTest extends RunnablePackageTest {
private Path unpackDir; private Path unpackDir;
private boolean aborted; private boolean aborted;
private boolean terminated;
private final JPackageCommand cmd = Functional.identity(() -> { private final JPackageCommand cmd = Functional.identity(() -> {
JPackageCommand result = new JPackageCommand(); JPackageCommand result = new JPackageCommand();
result.setDefaultInputOutput().setDefaultAppName(); result.setDefaultInputOutput().setDefaultAppName();
@ -535,13 +550,23 @@ public final class PackageTest extends RunnablePackageTest {
verifyPackageUninstalled(cmd); verifyPackageUninstalled(cmd);
} }
break; break;
case PURGE:
if (expectedJPackageExitCode == 0) {
var bundle = cmd.outputBundle();
if (toSupplier(() -> TKit.deleteIfExists(bundle)).get()) {
TKit.trace(String.format("Deleted [%s] package",
bundle));
}
}
break;
} }
} }
private void verifyPackageBundle(JPackageCommand cmd, private void verifyPackageBundle(JPackageCommand cmd,
Executor.Result result) { Executor.Result result) {
if (expectedJPackageExitCode == 0) { if (expectedJPackageExitCode == 0) {
if (PackageType.LINUX.contains(cmd.packageType())) { if (LINUX.contains(cmd.packageType())) {
LinuxHelper.verifyPackageBundleEssential(cmd); LinuxHelper.verifyPackageBundleEssential(cmd);
} }
} }
@ -557,35 +582,85 @@ public final class PackageTest extends RunnablePackageTest {
} }
TKit.trace(String.format(formatString, cmd.getPrintableCommandLine())); TKit.trace(String.format(formatString, cmd.getPrintableCommandLine()));
Optional.ofNullable(cmd.unpackedPackageDirectory()).ifPresent(
unpackedDir -> {
verifyRootCountInUnpackedPackage(cmd, unpackedDir);
});
if (!cmd.isRuntime()) { if (!cmd.isRuntime()) {
if (PackageType.WINDOWS.contains(cmd.packageType()) if (WINDOWS.contains(cmd.packageType())
&& !cmd.isPackageUnpacked( && !cmd.isPackageUnpacked(
"Not verifying desktop integration")) { "Not verifying desktop integration")) {
// Check main launcher // Check main launcher
new WindowsHelper.DesktopIntegrationVerifier(cmd, null); WindowsHelper.verifyDesktopIntegration(cmd, null);
// Check additional launchers // Check additional launchers
launcherNames.forEach(name -> { cmd.addLauncherNames().forEach(name -> {
new WindowsHelper.DesktopIntegrationVerifier(cmd, name); WindowsHelper.verifyDesktopIntegration(cmd, name);
}); });
} }
} }
cmd.assertAppLayout(); cmd.assertAppLayout();
installVerifiers.forEach(v -> v.accept(cmd)); installVerifiers.forEach(v -> v.accept(cmd));
} }
private void verifyRootCountInUnpackedPackage(JPackageCommand cmd,
Path unpackedDir) {
final long expectedRootCount;
if (WINDOWS.contains(cmd.packageType())) {
// On Windows it is always two entries:
// installation home directory and MSI file
expectedRootCount = 2;
} else if (LINUX.contains(cmd.packageType())) {
Set<Path> roots = new HashSet<>();
roots.add(Path.of("/").resolve(Path.of(cmd.getArgumentValue(
"--install-dir", () -> "/opt")).getName(0)));
if (cmd.hasArgument("--license-file")) {
switch (cmd.packageType()) {
case LINUX_RPM -> {
// License file is in /usr/share/licenses subtree
roots.add(Path.of("/usr"));
}
case LINUX_DEB -> {
Path installDir = cmd.appInstallationDirectory();
if (installDir.equals(Path.of("/"))
|| installDir.startsWith("/usr")) {
// License file is in /usr/share/doc subtree
roots.add(Path.of("/usr"));
}
}
}
}
expectedRootCount = roots.size();
} else {
expectedRootCount = 1;
}
try ( var files = Files.list(unpackedDir)) {
TKit.assertEquals(expectedRootCount, files.count(),
String.format(
"Check the package has %d top installation directories",
expectedRootCount));
} catch (IOException ex) {
rethrowUnchecked(ex);
}
}
private void verifyPackageUninstalled(JPackageCommand cmd) { private void verifyPackageUninstalled(JPackageCommand cmd) {
TKit.trace(String.format("Verify uninstalled: %s", TKit.trace(String.format("Verify uninstalled: %s",
cmd.getPrintableCommandLine())); cmd.getPrintableCommandLine()));
if (!cmd.isRuntime()) { if (!cmd.isRuntime()) {
TKit.assertPathExists(cmd.appLauncherPath(), false); TKit.assertPathExists(cmd.appLauncherPath(), false);
if (PackageType.WINDOWS.contains(cmd.packageType())) { if (WINDOWS.contains(cmd.packageType())) {
// Check main launcher // Check main launcher
new WindowsHelper.DesktopIntegrationVerifier(cmd, null); WindowsHelper.verifyDesktopIntegration(cmd, null);
// Check additional launchers // Check additional launchers
launcherNames.forEach(name -> { cmd.addLauncherNames().forEach(name -> {
new WindowsHelper.DesktopIntegrationVerifier(cmd, name); WindowsHelper.verifyDesktopIntegration(cmd, name);
}); });
} }
} }
@ -610,18 +685,18 @@ public final class PackageTest extends RunnablePackageTest {
private static Map<PackageType, PackageHandlers> createDefaultPackageHandlers() { private static Map<PackageType, PackageHandlers> createDefaultPackageHandlers() {
HashMap<PackageType, PackageHandlers> handlers = new HashMap<>(); HashMap<PackageType, PackageHandlers> handlers = new HashMap<>();
if (TKit.isLinux()) { if (TKit.isLinux()) {
handlers.put(PackageType.LINUX_DEB, LinuxHelper.createDebPackageHandlers()); handlers.put(LINUX_DEB, LinuxHelper.createDebPackageHandlers());
handlers.put(PackageType.LINUX_RPM, LinuxHelper.createRpmPackageHandlers()); handlers.put(LINUX_RPM, LinuxHelper.createRpmPackageHandlers());
} }
if (TKit.isWindows()) { if (TKit.isWindows()) {
handlers.put(PackageType.WIN_MSI, WindowsHelper.createMsiPackageHandlers()); handlers.put(WIN_MSI, WindowsHelper.createMsiPackageHandlers());
handlers.put(PackageType.WIN_EXE, WindowsHelper.createExePackageHandlers()); handlers.put(WIN_EXE, WindowsHelper.createExePackageHandlers());
} }
if (TKit.isOSX()) { if (TKit.isOSX()) {
handlers.put(PackageType.MAC_DMG, MacHelper.createDmgPackageHandlers()); handlers.put(MAC_DMG, MacHelper.createDmgPackageHandlers());
handlers.put(PackageType.MAC_PKG, MacHelper.createPkgPackageHandlers()); handlers.put(MAC_PKG, MacHelper.createPkgPackageHandlers());
} }
return handlers; return handlers;
@ -633,7 +708,6 @@ public final class PackageTest extends RunnablePackageTest {
private Map<PackageType, Handler> handlers; private Map<PackageType, Handler> handlers;
private Set<String> namedInitializers; private Set<String> namedInitializers;
private Map<PackageType, PackageHandlers> packageHandlers; private Map<PackageType, PackageHandlers> packageHandlers;
private final List<String> launcherNames = new ArrayList();
private final static File BUNDLE_OUTPUT_DIR; private final static File BUNDLE_OUTPUT_DIR;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -41,6 +41,12 @@ public abstract class RunnablePackageTest {
.filter(Predicate.not(Action.INITIALIZE::equals)) .filter(Predicate.not(Action.INITIALIZE::equals))
.filter(Predicate.not(Action.FINALIZE::equals)) .filter(Predicate.not(Action.FINALIZE::equals))
.collect(Collectors.toList())); .collect(Collectors.toList()));
if (hasAction(Action.PURGE) && !actionList.contains(Action.PURGE)) {
// Default action list contains "purge" action meaning
// packages are not needed for further processing.
// Copy this behavior in custom action list.
actionList.add(Action.PURGE);
}
} }
actionList.add(Action.FINALIZE); actionList.add(Action.FINALIZE);
@ -51,6 +57,10 @@ public abstract class RunnablePackageTest {
runActions(actionGroups); runActions(actionGroups);
} }
public static boolean hasAction(Action a) {
return DEFAULT_ACTIONS.contains(a);
}
protected void runActions(List<Action[]> actions) { protected void runActions(List<Action[]> actions) {
actions.forEach(this::runAction); actions.forEach(this::runAction);
} }
@ -89,6 +99,10 @@ public abstract class RunnablePackageTest {
* Uninstall package. * Uninstall package.
*/ */
UNINSTALL, UNINSTALL,
/**
* Purge package.
*/
PURGE,
/** /**
* Finalize test. * Finalize test.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -58,7 +58,7 @@ public class WindowsHelper {
private static Path getInstallationSubDirectory(JPackageCommand cmd) { private static Path getInstallationSubDirectory(JPackageCommand cmd) {
cmd.verifyIsOfType(PackageType.WINDOWS); cmd.verifyIsOfType(PackageType.WINDOWS);
return Path.of(cmd.getArgumentValue("--install-dir", () -> cmd.name())); return Path.of(cmd.getArgumentValue("--install-dir", cmd::name));
} }
private static void runMsiexecWithRetries(Executor misexec) { private static void runMsiexecWithRetries(Executor misexec) {
@ -66,7 +66,13 @@ public class WindowsHelper {
for (int attempt = 0; attempt < 8; ++attempt) { for (int attempt = 0; attempt < 8; ++attempt) {
result = misexec.executeWithoutExitCodeCheck(); result = misexec.executeWithoutExitCodeCheck();
// The given Executor may either be of an msiexe command or an if (result.exitCode == 1605) {
// ERROR_UNKNOWN_PRODUCT, attempt to uninstall not installed
// package
return;
}
// The given Executor may either be of an msiexec command or an
// unpack.bat script containing the msiexec command. In the later // unpack.bat script containing the msiexec command. In the later
// case, when misexec returns 1618, the unpack.bat may return 1603 // case, when misexec returns 1618, the unpack.bat may return 1603
if ((result.exitCode == 1618) || (result.exitCode == 1603)) { if ((result.exitCode == 1618) || (result.exitCode == 1603)) {
@ -91,16 +97,25 @@ public class WindowsHelper {
PackageHandlers msi = new PackageHandlers(); PackageHandlers msi = new PackageHandlers();
msi.installHandler = cmd -> installMsi.accept(cmd, true); msi.installHandler = cmd -> installMsi.accept(cmd, true);
msi.uninstallHandler = cmd -> installMsi.accept(cmd, false); msi.uninstallHandler = cmd -> {
if (Files.exists(cmd.outputBundle())) {
installMsi.accept(cmd, false);
}
};
msi.unpackHandler = (cmd, destinationDir) -> { msi.unpackHandler = (cmd, destinationDir) -> {
cmd.verifyIsOfType(PackageType.WIN_MSI); cmd.verifyIsOfType(PackageType.WIN_MSI);
final Path unpackBat = destinationDir.resolve("unpack.bat"); final Path unpackBat = destinationDir.resolve("unpack.bat");
final Path unpackDir = destinationDir.resolve( final Path unpackDir = destinationDir.resolve(
TKit.removeRootFromAbsolutePath( TKit.removeRootFromAbsolutePath(
getInstallationRootDirectory(cmd))); getInstallationRootDirectory(cmd)));
// Put msiexec in .bat file because can't pass value of TARGETDIR // Put msiexec in .bat file because can't pass value of TARGETDIR
// property containing spaces through ProcessBuilder properly. // property containing spaces through ProcessBuilder properly.
TKit.createTextFile(unpackBat, List.of(String.join(" ", List.of( // Set folder permissions to allow msiexec unpack msi bundle.
TKit.createTextFile(unpackBat, List.of(
String.format("icacls \"%s\" /inheritance:e /grant Users:M",
destinationDir),
String.join(" ", List.of(
"msiexec", "msiexec",
"/a", "/a",
String.format("\"%s\"", cmd.outputBundle().normalize()), String.format("\"%s\"", cmd.outputBundle().normalize()),
@ -125,10 +140,19 @@ public class WindowsHelper {
PackageHandlers exe = new PackageHandlers(); PackageHandlers exe = new PackageHandlers();
exe.installHandler = cmd -> installExe.accept(cmd, true); exe.installHandler = cmd -> installExe.accept(cmd, true);
exe.uninstallHandler = cmd -> installExe.accept(cmd, false); exe.uninstallHandler = cmd -> {
if (Files.exists(cmd.outputBundle())) {
installExe.accept(cmd, false);
}
};
return exe; return exe;
} }
static void verifyDesktopIntegration(JPackageCommand cmd,
String launcherName) {
new DesktopIntegrationVerifier(cmd, launcherName);
}
public static String getMsiProperty(JPackageCommand cmd, String propertyName) { public static String getMsiProperty(JPackageCommand cmd, String propertyName) {
cmd.verifyIsOfType(PackageType.WIN_MSI); cmd.verifyIsOfType(PackageType.WIN_MSI);
return Executor.of("cscript.exe", "//Nologo") return Executor.of("cscript.exe", "//Nologo")
@ -143,21 +167,45 @@ public class WindowsHelper {
return cmd.hasArgument("--win-per-user-install"); return cmd.hasArgument("--win-per-user-install");
} }
static class DesktopIntegrationVerifier { private static class DesktopIntegrationVerifier {
DesktopIntegrationVerifier(JPackageCommand cmd, String name) { DesktopIntegrationVerifier(JPackageCommand cmd, String launcherName) {
cmd.verifyIsOfType(PackageType.WINDOWS); cmd.verifyIsOfType(PackageType.WINDOWS);
this.cmd = cmd;
this.name = (name == null ? cmd.name() : name); name = Optional.ofNullable(launcherName).orElseGet(cmd::name);
isUserLocalInstall = isUserLocalInstall(cmd);
appInstalled = cmd.appLauncherPath(launcherName).toFile().exists();
desktopShortcutPath = Path.of(name + ".lnk");
startMenuShortcutPath = Path.of(cmd.getArgumentValue(
"--win-menu-group", () -> "Unknown"), name + ".lnk");
if (name.equals(cmd.name())) {
isWinMenu = cmd.hasArgument("--win-menu");
isDesktop = cmd.hasArgument("--win-shortcut");
} else {
var props = AdditionalLauncher.getAdditionalLauncherProperties(cmd,
launcherName);
isWinMenu = props.getPropertyBooleanValue("win-menu").orElseGet(
() -> cmd.hasArgument("--win-menu"));
isDesktop = props.getPropertyBooleanValue("win-shortcut").orElseGet(
() -> cmd.hasArgument("--win-shortcut"));
}
verifyStartMenuShortcut(); verifyStartMenuShortcut();
verifyDesktopShortcut(); verifyDesktopShortcut();
verifyFileAssociationsRegistry();
Stream.of(cmd.getAllArgumentValues("--file-associations")).map(
Path::of).forEach(this::verifyFileAssociationsRegistry);
} }
private void verifyDesktopShortcut() { private void verifyDesktopShortcut() {
boolean appInstalled = cmd.appLauncherPath(name).toFile().exists(); if (isDesktop) {
if (cmd.hasArgument("--win-shortcut")) { if (isUserLocalInstall) {
if (isUserLocalInstall(cmd)) {
verifyUserLocalDesktopShortcut(appInstalled); verifyUserLocalDesktopShortcut(appInstalled);
verifySystemDesktopShortcut(false); verifySystemDesktopShortcut(false);
} else { } else {
@ -170,10 +218,6 @@ public class WindowsHelper {
} }
} }
private Path desktopShortcutPath() {
return Path.of(name + ".lnk");
}
private void verifyShortcut(Path path, boolean exists) { private void verifyShortcut(Path path, boolean exists) {
if (exists) { if (exists) {
TKit.assertFileExists(path); TKit.assertFileExists(path);
@ -185,19 +229,18 @@ public class WindowsHelper {
private void verifySystemDesktopShortcut(boolean exists) { private void verifySystemDesktopShortcut(boolean exists) {
Path dir = Path.of(queryRegistryValueCache( Path dir = Path.of(queryRegistryValueCache(
SYSTEM_SHELL_FOLDERS_REGKEY, "Common Desktop")); SYSTEM_SHELL_FOLDERS_REGKEY, "Common Desktop"));
verifyShortcut(dir.resolve(desktopShortcutPath()), exists); verifyShortcut(dir.resolve(desktopShortcutPath), exists);
} }
private void verifyUserLocalDesktopShortcut(boolean exists) { private void verifyUserLocalDesktopShortcut(boolean exists) {
Path dir = Path.of( Path dir = Path.of(
queryRegistryValueCache(USER_SHELL_FOLDERS_REGKEY, "Desktop")); queryRegistryValueCache(USER_SHELL_FOLDERS_REGKEY, "Desktop"));
verifyShortcut(dir.resolve(desktopShortcutPath()), exists); verifyShortcut(dir.resolve(desktopShortcutPath), exists);
} }
private void verifyStartMenuShortcut() { private void verifyStartMenuShortcut() {
boolean appInstalled = cmd.appLauncherPath(name).toFile().exists(); if (isWinMenu) {
if (cmd.hasArgument("--win-menu")) { if (isUserLocalInstall) {
if (isUserLocalInstall(cmd)) {
verifyUserLocalStartMenuShortcut(appInstalled); verifyUserLocalStartMenuShortcut(appInstalled);
verifySystemStartMenuShortcut(false); verifySystemStartMenuShortcut(false);
} else { } else {
@ -210,13 +253,8 @@ public class WindowsHelper {
} }
} }
private Path startMenuShortcutPath() {
return Path.of(cmd.getArgumentValue("--win-menu-group",
() -> "Unknown"), name + ".lnk");
}
private void verifyStartMenuShortcut(Path shortcutsRoot, boolean exists) { private void verifyStartMenuShortcut(Path shortcutsRoot, boolean exists) {
Path shortcutPath = shortcutsRoot.resolve(startMenuShortcutPath()); Path shortcutPath = shortcutsRoot.resolve(startMenuShortcutPath);
verifyShortcut(shortcutPath, exists); verifyShortcut(shortcutPath, exists);
if (!exists) { if (!exists) {
TKit.assertPathNotEmptyDirectory(shortcutPath.getParent()); TKit.assertPathNotEmptyDirectory(shortcutPath.getParent());
@ -234,13 +272,7 @@ public class WindowsHelper {
USER_SHELL_FOLDERS_REGKEY, "Programs")), exists); USER_SHELL_FOLDERS_REGKEY, "Programs")), exists);
} }
private void verifyFileAssociationsRegistry() {
Stream.of(cmd.getAllArgumentValues("--file-associations")).map(
Path::of).forEach(this::verifyFileAssociationsRegistry);
}
private void verifyFileAssociationsRegistry(Path faFile) { private void verifyFileAssociationsRegistry(Path faFile) {
boolean appInstalled = cmd.appLauncherPath(name).toFile().exists();
try { try {
TKit.trace(String.format( TKit.trace(String.format(
"Get file association properties from [%s] file", "Get file association properties from [%s] file",
@ -290,7 +322,12 @@ public class WindowsHelper {
} }
} }
private final JPackageCommand cmd; private final Path desktopShortcutPath;
private final Path startMenuShortcutPath;
private final boolean isUserLocalInstall;
private final boolean appInstalled;
private final boolean isWinMenu;
private final boolean isDesktop;
private final String name; private final String name;
} }

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -78,15 +78,25 @@ help_usage ()
echo " Optional, for jtreg tests debug purposes only." echo " Optional, for jtreg tests debug purposes only."
echo ' -l <logfile> - value for `jpackage.test.logfile` property.' echo ' -l <logfile> - value for `jpackage.test.logfile` property.'
echo " Optional, for jtreg tests debug purposes only." echo " Optional, for jtreg tests debug purposes only."
echo " -m <mode> - mode to run jtreg tests." echo " -m <mode> - mode to run jtreg tests. Supported values:"
echo ' Should be one of `create`, `update` or `print-default-tests`.'
echo ' Optional, default mode is `update`.'
echo ' - `create`' echo ' - `create`'
echo ' Remove all package bundles from the output directory before running jtreg tests.' echo ' Remove all package bundles from the output directory before running jtreg tests.'
echo ' - `update`' echo ' - `update`'
echo ' Run jtreg tests and overrite existing package bundles in the output directory.' echo ' Run jtreg tests and overrite existing package bundles in the output directory.'
echo ' - `print-default-tests`' echo ' - `print-default-tests`'
echo ' Print default list of packaging tests and exit.' echo ' Print default list of packaging tests and exit.'
echo ' - `create-small-runtime`'
echo ' Create small Java runtime using <jdk>/bin/jlink command in the output directory.'
echo ' - `create-packages`'
echo ' Create packages.'
echo ' The script will set `jpackage.test.action` property.'
echo ' - `test-packages`'
echo ' Create and fully test packages. Will create, unpack, install, and uninstall packages.'
echo ' The script will set `jpackage.test.action` property.'
echo ' - `do-packages`'
echo " Create, unpack and verify packages."
echo ' The script will not set `jpackage.test.action` property.'
echo ' Optional, defaults are `update` and `create-packages`.'
} }
error () error ()
@ -133,8 +143,6 @@ exec_command ()
test_jdk= test_jdk=
# Path to local copy of open jdk repo with jpackage jtreg tests # Path to local copy of open jdk repo with jpackage jtreg tests
# hg clone http://hg.openjdk.java.net/jdk/sandbox
# cd sandbox; hg update -r JDK-8200758-branch
open_jdk_with_jpackage_jtreg_tests=$(dirname $0)/../../../../ open_jdk_with_jpackage_jtreg_tests=$(dirname $0)/../../../../
# Directory where to save artifacts for testing. # Directory where to save artifacts for testing.
@ -152,12 +160,27 @@ mode=update
# jtreg extra arguments # jtreg extra arguments
declare -a jtreg_args declare -a jtreg_args
# Create packages only
jtreg_args+=("-Djpackage.test.action=create")
# run all tests # run all tests
run_all_tests= run_all_tests=
test_actions=
set_mode ()
{
case "$1" in
create-packages) test_actions='-Djpackage.test.action=create';;
test-packages) test_actions='-Djpackage.test.action=uninstall,create,unpack,verify-install,install,verify-install,uninstall,verify-uninstall,purge';;
do-packages) test_actions=;;
create-small-runtime) mode=$1;;
print-default-tests) mode=$1;;
create) mode=$1;;
update) mode=$1;;
*) fatal_with_help_usage 'Invalid value of -m option:' [$1];;
esac
}
set_mode 'create-packages'
mapfile -t tests < <(find_all_packaging_tests) mapfile -t tests < <(find_all_packaging_tests)
while getopts "vahdct:j:o:r:m:l:" argname; do while getopts "vahdct:j:o:r:m:l:" argname; do
@ -171,7 +194,7 @@ while getopts "vahdct:j:o:r:m:l:" argname; do
o) output_dir="$OPTARG";; o) output_dir="$OPTARG";;
r) runtime_dir="$OPTARG";; r) runtime_dir="$OPTARG";;
l) logfile="$OPTARG";; l) logfile="$OPTARG";;
m) mode="$OPTARG";; m) set_mode "$OPTARG";;
h) help_usage; exit 0;; h) help_usage; exit 0;;
?) help_usage; exit 1;; ?) help_usage; exit 1;;
esac esac
@ -201,6 +224,11 @@ if [ ! -e "$JAVA_HOME/bin/java" ]; then
fatal JAVA_HOME variable is set to [$JAVA_HOME] value, but $JAVA_HOME/bin/java not found. fatal JAVA_HOME variable is set to [$JAVA_HOME] value, but $JAVA_HOME/bin/java not found.
fi fi
if [ "$mode" = "create-small-runtime" ]; then
exec_command "$test_jdk/bin/jlink" --add-modules java.base,java.datatransfer,java.xml,java.prefs,java.desktop --compress=2 --no-header-files --no-man-pages --strip-debug --output "$output_dir"
exit
fi
if [ -z "$JT_HOME" ]; then if [ -z "$JT_HOME" ]; then
if [ -z "$JT_BUNDLE_URL" ]; then if [ -z "$JT_BUNDLE_URL" ]; then
fatal 'JT_HOME or JT_BUNDLE_URL environment variable is not set. Link to JTREG bundle can be found at https://openjdk.java.net/jtreg/'. fatal 'JT_HOME or JT_BUNDLE_URL environment variable is not set. Link to JTREG bundle can be found at https://openjdk.java.net/jtreg/'.
@ -222,18 +250,12 @@ if [ -n "$logfile" ]; then
jtreg_args+=("-Djpackage.test.logfile=$(to_native_path "$logfile")") jtreg_args+=("-Djpackage.test.logfile=$(to_native_path "$logfile")")
fi fi
if [ "$mode" = create ]; then
true
elif [ "$mode" = update ]; then
true
else
fatal_with_help_usage 'Invalid value of -m option:' [$mode]
fi
if [ -z "$run_all_tests" ]; then if [ -z "$run_all_tests" ]; then
jtreg_args+=(-Djpackage.test.SQETest=yes) jtreg_args+=(-Djpackage.test.SQETest=yes)
fi fi
jtreg_args+=("$test_actions")
# Drop arguments separator # Drop arguments separator
[ "$1" != "--" ] || shift [ "$1" != "--" ] || shift
@ -249,10 +271,10 @@ installJtreg ()
if [ ! -f "$jtreg_jar" ]; then if [ ! -f "$jtreg_jar" ]; then
exec_command mkdir -p "$workdir" exec_command mkdir -p "$workdir"
if [[ ${jtreg_bundle: -7} == ".tar.gz" ]]; then if [[ ${jtreg_bundle: -7} == ".tar.gz" ]]; then
exec_command "(" cd "$workdir" "&&" wget "$jtreg_bundle" "&&" tar -xzf "$(basename $jtreg_bundle)" ";" rm -f "$(basename $jtreg_bundle)" ")" exec_command "(" cd "$workdir" "&&" wget --no-check-certificate "$jtreg_bundle" "&&" tar -xzf "$(basename $jtreg_bundle)" ";" rm -f "$(basename $jtreg_bundle)" ")"
else else
if [[ ${jtreg_bundle: -4} == ".zip" ]]; then if [[ ${jtreg_bundle: -4} == ".zip" ]]; then
exec_command "(" cd "$workdir" "&&" wget "$jtreg_bundle" "&&" unzip "$(basename $jtreg_bundle)" ";" rm -f "$(basename $jtreg_bundle)" ")" exec_command "(" cd "$workdir" "&&" wget --no-check-certificate "$jtreg_bundle" "&&" unzip "$(basename $jtreg_bundle)" ";" rm -f "$(basename $jtreg_bundle)" ")"
else else
fatal 'Unsupported extension of JREG bundle ['$JT_BUNDLE_URL']. Only *.zip or *.tar.gz is supported.' fatal 'Unsupported extension of JREG bundle ['$JT_BUNDLE_URL']. Only *.zip or *.tar.gz is supported.'
fi fi

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -69,8 +69,6 @@ public class MultiLauncherTwoPhaseTest {
launcher2.applyTo(appImageCmd); launcher2.applyTo(appImageCmd);
PackageTest packageTest = new PackageTest() PackageTest packageTest = new PackageTest()
.addLauncherName("bar") // Add launchers name for verification
.addLauncherName("foo")
.addRunOnceInitializer(() -> appImageCmd.execute()) .addRunOnceInitializer(() -> appImageCmd.execute())
.addBundleDesktopIntegrationVerifier(true) .addBundleDesktopIntegrationVerifier(true)
.addInitializer(cmd -> { .addInitializer(cmd -> {

View File

@ -1,100 +0,0 @@
#!/bin/bash
# Copyright (c) 2020, 2021, 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.
#
# Complete testing of jpackage platform-specific packaging.
#
# The script does the following:
# 1. Create packages.
# 2. Install created packages.
# 3. Verifies packages are installed.
# 4. Uninstall created packages.
# 5. Verifies packages are uninstalled.
#
# For the list of accepted command line arguments see `run_tests.sh` script.
#
# Fail fast
set -e; set -o pipefail;
# Script debug
dry_run=${JPACKAGE_TEST_DRY_RUN}
# Default directory where jpackage should write bundle files
output_dir=~/jpackage_bundles
set_args ()
{
args=()
local arg_is_output_dir=
local arg_is_mode=
local output_dir_set=
local with_append_actions=yes
for arg in "$@"; do
if [ "$arg" == "-o" ]; then
arg_is_output_dir=yes
output_dir_set=yes
elif [ "$arg" == "-m" ]; then
arg_is_mode=yes
continue
elif [ "$arg" == '--' ]; then
append_actions
with_append_actions=
continue
elif ! case "$arg" in -Djpackage.test.action=*) false;; esac; then
continue
elif [ -n "$arg_is_output_dir" ]; then
arg_is_output_dir=
output_dir="$arg"
elif [ -n "$arg_is_mode" ]; then
arg_is_mode=
continue
fi
args+=( "$arg" )
done
[ -n "$output_dir_set" ] || args=( -o "$output_dir" "${args[@]}" )
[ -z "$with_append_actions" ] || append_actions
}
append_actions ()
{
args+=( '--' '-Djpackage.test.action=create,install,verify-install,uninstall,verify-uninstall' )
}
exec_command ()
{
if [ -n "$dry_run" ]; then
echo "$@"
else
eval "$@"
fi
}
set_args "$@"
basedir="$(dirname $0)"
exec_command ${SHELL} "$basedir/run_tests.sh" -m create "${args[@]}"

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -100,7 +100,7 @@ public class WinUpgradeUUIDTest {
// It will be uninstalled automatically when the second // It will be uninstalled automatically when the second
// package will be installed. // package will be installed.
// However uninstall verification for the first package will be executed. // However uninstall verification for the first package will be executed.
PackageTest test1 = init.get().setPackageUninstaller(cmd -> {}); PackageTest test1 = init.get().disablePackageUninstaller();
PackageTest test2 = init.get().addInitializer(cmd -> { PackageTest test2 = init.get().addInitializer(cmd -> {
cmd.setArgumentValue("--app-version", "2.0"); cmd.setArgumentValue("--app-version", "2.0");