Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,11 @@ public PackageTest() {
disabledInstallers = new HashSet<>();
disabledUninstallers = new HashSet<>();
excludeTypes = new HashSet<>();
handlers = NATIVE.stream().collect(Collectors.toMap(v -> v, v -> new Handler()));
forTypes();
setExpectedExitCode(0);
setExpectedInstallExitCode(0);
namedInitializers = new HashSet<>();
handlers = NATIVE.stream()
.collect(Collectors.toMap(v -> v, v -> new Handler()));
}

public PackageTest excludeTypes(PackageType... types) {
Expand All @@ -102,6 +101,7 @@ public PackageTest forTypes(PackageType... types) {
newTypes = Stream.of(types).collect(Collectors.toSet());
}
currentTypes = newTypes.stream()
.filter(handlers.keySet()::contains)
.filter(isPackageTypeEnabled)
.filter(Predicate.not(excludeTypes::contains))
.collect(Collectors.toUnmodifiableSet());
Expand Down Expand Up @@ -456,9 +456,11 @@ protected void runAction(Action... action) {
}

private List<Consumer<Action>> createPackageTypeHandlers() {
if (handlers.keySet().stream().noneMatch(isPackageTypeEnabled)) {
PackageType.throwSkippedExceptionIfNativePackagingUnavailable();
}
return handlers.entrySet().stream()
.filter(entry -> !entry.getValue().isVoid())
.filter(entry -> NATIVE.contains(entry.getKey()))
.sorted(Comparator.comparing(Map.Entry::getKey))
.map(entry -> {
return createPackageTypeHandler(entry.getKey(), entry.getValue());
Expand Down
24 changes: 20 additions & 4 deletions test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,21 @@
*/
package jdk.jpackage.test;

import static jdk.jpackage.internal.util.function.ExceptionBox.rethrowUnchecked;

import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.jpackage.internal.Log;
import static jdk.jpackage.internal.util.function.ExceptionBox.rethrowUnchecked;

/**
* jpackage type traits.
Expand Down Expand Up @@ -93,6 +96,15 @@ public String getType() {
return type;
}

public static RuntimeException throwSkippedExceptionIfNativePackagingUnavailable() {
if (NATIVE.stream().noneMatch(PackageType::isSupported)) {
TKit.throwSkippedException("None of the native packagers supported in this environment");
} else if (NATIVE.stream().noneMatch(PackageType::isEnabled)) {
TKit.throwSkippedException("All native packagers supported in this environment are disabled");
}
return null;
}

private static boolean isBundlerSupportedImpl(String bundlerClass) {
try {
Class<?> clazz = Class.forName(bundlerClass);
Expand Down Expand Up @@ -131,14 +143,18 @@ private static boolean isBundlerSupported(String bundlerClass) {
return reply.get();
}

private static Set<PackageType> orderedSet(PackageType... types) {
return new LinkedHashSet<>(List.of(types));
}

private final String type;
private final String suffix;
private final boolean enabled;
private final boolean supported;

public static final Set<PackageType> LINUX = Set.of(LINUX_DEB, LINUX_RPM);
public static final Set<PackageType> WINDOWS = Set.of(WIN_EXE, WIN_MSI);
public static final Set<PackageType> MAC = Set.of(MAC_PKG, MAC_DMG);
public static final Set<PackageType> LINUX = orderedSet(LINUX_DEB, LINUX_RPM);
public static final Set<PackageType> WINDOWS = orderedSet(WIN_MSI, WIN_EXE);
public static final Set<PackageType> MAC = orderedSet(MAC_DMG, MAC_PKG);
public static final Set<PackageType> NATIVE = Stream.concat(
Stream.concat(LINUX.stream(), WINDOWS.stream()),
MAC.stream()).collect(Collectors.toUnmodifiableSet());
Expand Down
33 changes: 30 additions & 3 deletions test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
Expand Down Expand Up @@ -518,9 +519,9 @@ public static RuntimeException throwUnknownPlatformError() {
}

public static RuntimeException throwSkippedException(String reason) {
RuntimeException ex = ThrowingSupplier.toSupplier(
() -> (RuntimeException) Class.forName("jtreg.SkippedException").getConstructor(
String.class).newInstance(reason)).get();
RuntimeException ex = ThrowingSupplier.toSupplier(() -> {
return JtregSkippedExceptionClass.INSTANCE.getConstructor(String.class).newInstance(reason);
}).get();
return throwSkippedException(ex);
}

Expand Down Expand Up @@ -1140,4 +1141,30 @@ static Set<String> tokenizeConfigProperty(String propertyName) {
VERBOSE_TEST_SETUP = isNonOf.test(Set.of("init", "i"));
}
}

private static final class JtregSkippedExceptionClass extends ClassLoader {
@SuppressWarnings("unchecked")
JtregSkippedExceptionClass() {
super(TKit.class.getClassLoader());

final byte[] bytes = Base64.getDecoder().decode(
// Base64-encoded "jtreg/SkippedException.class" file
// emitted by jdk8's javac from "$OPEN_JDK/test/lib/jtreg/SkippedException.java"
"yv66vgAAADQAFQoABAARCgAEABIHABMHABQBABBzZXJpYWxWZXJzaW9uVUlEAQABSgEADUNvbnN0"
+ "YW50VmFsdWUFErH6BHk+kr0BAAY8aW5pdD4BACooTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFu"
+ "Zy9UaHJvd2FibGU7KVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQAVKExqYXZhL2xhbmcvU3Ry"
+ "aW5nOylWAQAKU291cmNlRmlsZQEAFVNraXBwZWRFeGNlcHRpb24uamF2YQwACgALDAAKAA4BABZq"
+ "dHJlZy9Ta2lwcGVkRXhjZXB0aW9uAQAaamF2YS9sYW5nL1J1bnRpbWVFeGNlcHRpb24AMQADAAQA"
+ "AAABABoABQAGAAEABwAAAAIACAACAAEACgALAAEADAAAACMAAwADAAAAByorLLcAAbEAAAABAA0A"
+ "AAAKAAIAAAAiAAYAIwABAAoADgABAAwAAAAiAAIAAgAAAAYqK7cAArEAAAABAA0AAAAKAAIAAAAm"
+ "AAUAJwABAA8AAAACABA");

clazz = (Class<RuntimeException>)defineClass("jtreg.SkippedException", bytes, 0, bytes.length);
}

private final Class<RuntimeException> clazz;

static final Class<RuntimeException> INSTANCE = new JtregSkippedExceptionClass().clazz;

}
}
138 changes: 100 additions & 38 deletions test/jdk/tools/jpackage/share/ErrorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
import java.util.regex.Pattern;
import java.util.stream.Stream;
import jdk.jpackage.internal.util.TokenReplace;
import jdk.jpackage.test.Annotations.Parameter;
import jdk.jpackage.test.Annotations.ParameterSupplier;
import jdk.jpackage.test.Annotations.Test;
import jdk.jpackage.test.CannedFormattedString;
Expand Down Expand Up @@ -119,13 +118,71 @@ private static String makeToken(String v) {
private final TokenReplace tokenReplace = new TokenReplace(token());
}

public record TestSpec(Optional<PackageType> type, Optional<String> appDesc, List<String> addArgs,
record PackageTypeSpec(Optional<PackageType> type, boolean anyNativeType) implements CannedFormattedString.CannedArgument {
PackageTypeSpec {
Objects.requireNonNull(type);
if (type.isPresent() && anyNativeType) {
throw new IllegalArgumentException();
}
}

PackageTypeSpec(PackageType type) {
this(Optional.of(type), false);
}

boolean isSupported() {
if (anyNativeType) {
return NATIVE_TYPE.isPresent();
} else {
return type.orElseThrow().isSupported();
}
}

PackageType resolvedType() {
return type.or(() -> NATIVE_TYPE).orElseThrow(PackageType::throwSkippedExceptionIfNativePackagingUnavailable);
}

@Override
public String value() {
return resolvedType().getType();
}

@Override
public final String toString() {
if (anyNativeType) {
return "NATIVE";
} else {
return type.orElseThrow().toString();
}
}

private static Optional<PackageType> defaultNativeType() {
final Collection<PackageType> nativeTypes;
if (TKit.isLinux()) {
nativeTypes = PackageType.LINUX;
} else if (TKit.isOSX()) {
nativeTypes = PackageType.MAC;
} else if (TKit.isWindows()) {
nativeTypes = List.of(PackageType.WIN_MSI);
} else {
throw TKit.throwUnknownPlatformError();
}

return nativeTypes.stream().filter(PackageType::isSupported).findFirst();
}

static final PackageTypeSpec NATIVE = new PackageTypeSpec(Optional.empty(), true);

private static final Optional<PackageType> NATIVE_TYPE = defaultNativeType();
}

public record TestSpec(Optional<PackageTypeSpec> type, Optional<String> appDesc, List<String> addArgs,
List<String> removeArgs, List<CannedFormattedString> expectedErrors) {

static final class Builder {

Builder type(PackageType v) {
type = v;
type = Optional.ofNullable(v).map(PackageTypeSpec::new).orElse(null);
return this;
}

Expand All @@ -134,7 +191,8 @@ Builder notype() {
}

Builder nativeType() {
return type(NATIVE_TYPE);
type = PackageTypeSpec.NATIVE;
return this;
}

Builder appDesc(String v) {
Expand Down Expand Up @@ -207,7 +265,8 @@ Builder error(String key, Object ... args) {
}

Builder invalidTypeArg(String arg, String... otherArgs) {
return addArgs(arg).addArgs(otherArgs).error("ERR_InvalidTypeOption", arg, type.getType());
Objects.requireNonNull(type);
return addArgs(arg).addArgs(otherArgs).error("ERR_InvalidTypeOption", arg, type);
}

Builder unsupportedPlatformOption(String arg, String ... otherArgs) {
Expand All @@ -219,7 +278,7 @@ TestSpec create() {
List.copyOf(addArgs), List.copyOf(removeArgs), List.copyOf(expectedErrors));
}

private PackageType type = PackageType.IMAGE;
private PackageTypeSpec type = new PackageTypeSpec(PackageType.IMAGE);
private String appDesc = DEFAULT_APP_DESC;
private List<String> addArgs = new ArrayList<>();
private List<String> removeArgs = new ArrayList<>();
Expand All @@ -242,9 +301,13 @@ void test() {
test(Map.of());
}

boolean isSupported() {
return type.map(PackageTypeSpec::isSupported).orElse(true);
}

void test(Map<Token, Function<JPackageCommand, Object>> tokenValueSuppliers) {
final var cmd = appDesc.map(JPackageCommand::helloAppImage).orElseGet(JPackageCommand::new);
type.ifPresent(cmd::setPackageType);
type.map(PackageTypeSpec::resolvedType).ifPresent(cmd::setPackageType);

removeArgs.forEach(cmd::removeArgumentWithValue);
cmd.addArguments(addArgs);
Expand Down Expand Up @@ -407,6 +470,7 @@ public static Collection<Object[]> invalidAppVersion() {

@Test
@ParameterSupplier("basic")
@ParameterSupplier("testRuntimeInstallerInvalidOptions")
@ParameterSupplier(value="testWindows", ifOS = WINDOWS)
@ParameterSupplier(value="testMac", ifOS = MACOS)
@ParameterSupplier(value="testLinux", ifOS = LINUX)
Expand All @@ -418,19 +482,27 @@ public static void test(TestSpec spec) {
spec.test();
}

@Test
@Parameter({"--input", "foo"})
@Parameter({"--module-path", "dir"})
@Parameter({"--add-modules", "java.base"})
@Parameter({"--main-class", "Hello"})
@Parameter({"--arguments", "foo"})
@Parameter({"--java-options", "-Dfoo.bar=10"})
@Parameter({"--add-launcher", "foo=foo.properties"})
@Parameter({"--app-content", "dir"})
@Parameter(value="--win-console", ifOS = WINDOWS)
public static void testRuntimeInstallerInvalidOptions(String... args) {
testSpec().noAppDesc().nativeType().addArgs("--runtime-image", Token.JAVA_HOME.token()).addArgs(args)
.error("ERR_NoInstallerEntryPoint", args[0]).create().test();
public static Collection<Object[]> testRuntimeInstallerInvalidOptions() {
Stream<List<String>> argsStream = Stream.of(
List.of("--input", "foo"),
List.of("--module-path", "dir"),
List.of("--add-modules", "java.base"),
List.of("--main-class", "Hello"),
List.of("--arguments", "foo"),
List.of("--java-options", "-Dfoo.bar=10"),
List.of("--add-launcher", "foo=foo.properties"),
List.of("--app-content", "dir"));

if (TKit.isWindows()) {
argsStream = Stream.concat(argsStream, Stream.of(List.of("--win-console")));
}

return fromTestSpecBuilders(argsStream.map(args -> {
return testSpec().noAppDesc().nativeType()
.addArgs("--runtime-image", Token.JAVA_HOME.token())
.addArgs(args)
.error("ERR_NoInstallerEntryPoint", args.getFirst());
}));
}

@Test
Expand Down Expand Up @@ -567,9 +639,7 @@ public static Collection<Object[]> testLinux() {
testSpec().type(PackageType.LINUX_RPM).addArgs("--linux-package-name", "#")
.error("error.rpm-invalid-value-for-package-name", "#")
.error("error.rpm-invalid-value-for-package-name.advice")
).map(TestSpec.Builder::create).filter(spec -> {
return spec.type().orElseThrow().isSupported();
}).toList());
).map(TestSpec.Builder::create).toList());

return toTestArgs(testCases.stream());
}
Expand Down Expand Up @@ -669,20 +739,14 @@ private static void defaultInit(JPackageCommand cmd, List<CannedFormattedString>
cmd.validateOutput(expectedErrors.toArray(CannedFormattedString[]::new));
}

private static PackageType defaultNativeType() {
if (TKit.isLinux()) {
return PackageType.LINUX.stream().filter(PackageType::isSupported).findFirst().orElseThrow();
} else if (TKit.isOSX()) {
return PackageType.MAC_DMG;
} else if (TKit.isWindows()) {
return PackageType.WIN_MSI;
} else {
throw new UnsupportedOperationException();
}
}

private static <T> Collection<Object[]> toTestArgs(Stream<T> stream) {
return stream.map(v -> {
return stream.filter(v -> {
if (v instanceof TestSpec ts) {
return ts.isSupported();
} else {
return true;
}
}).map(v -> {
return new Object[] {v};
}).toList();
}
Expand All @@ -696,6 +760,4 @@ private static String adjustTextStreamVerifierArg(String str) {
}

private static final Pattern LINE_SEP_REGEXP = Pattern.compile("\\R");

private static final PackageType NATIVE_TYPE = defaultNativeType();
}
2 changes: 0 additions & 2 deletions test/jdk/tools/jpackage/share/ServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@
* @test
* @summary Launcher as service packaging test
* @library /test/jdk/tools/jpackage/helpers
* @library /test/lib
* @build jdk.jpackage.test.*
* @build jtreg.SkippedException
* @key jpackagePlatformPackage
* @compile -Xlint:all -Werror ServiceTest.java
* @run main/othervm/timeout=360 -Xmx512m
Expand Down
2 changes: 0 additions & 2 deletions test/jdk/tools/jpackage/windows/WinLongPathTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,8 @@
* @bug 8289771
* @summary jpackage with long paths on windows
* @library /test/jdk/tools/jpackage/helpers
* @library /test/lib
* @key jpackagePlatformPackage
* @build jdk.jpackage.test.*
* @build jtreg.SkippedException
* @requires (os.family == "windows")
* @compile -Xlint:all -Werror WinLongPathTest.java
* @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main
Expand Down