diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java index c1739b9095a..61e4ccdb4a2 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java @@ -53,6 +53,7 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Collectors; +import java.util.stream.IntStream; import java.util.stream.Stream; import java.util.stream.StreamSupport; import jdk.jpackage.internal.util.function.ThrowingBiConsumer; @@ -126,8 +127,8 @@ public final class PackageTest extends RunnablePackageTest { return this; } - public PackageTest setExpectedInstallExitCode(int v) { - expectedInstallExitCode = v; + public PackageTest setExpectedInstallExitCode(int... v) { + expectedInstallExitCodes = IntStream.of(v).mapToObj(Integer::valueOf).collect(Collectors.toSet()); return this; } @@ -483,11 +484,15 @@ public final class PackageTest extends RunnablePackageTest { } private record PackageTypePipeline(PackageType type, int expectedJPackageExitCode, - int expectedInstallExitCode, PackageHandlers packageHandlers, Handler handler, + Set expectedInstallExitCodes, PackageHandlers packageHandlers, Handler handler, JPackageCommand cmd, State state) implements Consumer { PackageTypePipeline { Objects.requireNonNull(type); + Objects.requireNonNull(expectedInstallExitCodes); + if (expectedInstallExitCodes.isEmpty()) { + throw new IllegalArgumentException(); + } Objects.requireNonNull(packageHandlers); Objects.requireNonNull(handler); Objects.requireNonNull(cmd); @@ -495,9 +500,9 @@ public final class PackageTest extends RunnablePackageTest { } PackageTypePipeline(PackageType type, int expectedJPackageExitCode, - int expectedInstallExitCode, PackageHandlers packageHandlers, + Set expectedInstallExitCodes, PackageHandlers packageHandlers, Handler handler, JPackageCommand cmd) { - this(type, expectedJPackageExitCode, expectedInstallExitCode, + this(type, expectedJPackageExitCode, expectedInstallExitCodes, packageHandlers, handler, cmd, new State()); } @@ -532,9 +537,10 @@ public final class PackageTest extends RunnablePackageTest { case INSTALL -> { cmd.setUnpackedPackageLocation(null); - final int installExitCode = packageHandlers.install(cmd); - TKit.assertEquals(expectedInstallExitCode, installExitCode, - String.format("Check installer exited with %d code", expectedInstallExitCode)); + final int actualInstallExitCode = packageHandlers.install(cmd); + state.actualInstallExitCode = Optional.of(actualInstallExitCode); + TKit.assertTrue(expectedInstallExitCodes.contains(actualInstallExitCode), + String.format("Check installer exit code %d is one of %s", actualInstallExitCode, expectedInstallExitCodes)); } case UNINSTALL -> { @@ -624,7 +630,7 @@ public final class PackageTest extends RunnablePackageTest { } private boolean installFailed() { - return processed(Action.INSTALL) && expectedInstallExitCode != 0; + return processed(Action.INSTALL) && state.actualInstallExitCode.orElseThrow() != 0; } private boolean jpackageFailed() { @@ -636,6 +642,7 @@ public final class PackageTest extends RunnablePackageTest { } private static final class State { + private Optional actualInstallExitCode = Optional.empty(); private final Set packageActions = new HashSet<>(); private final List deleteUnpackDirs = new ArrayList<>(); } @@ -649,7 +656,7 @@ public final class PackageTest extends RunnablePackageTest { } type.applyTo(cmd); return new PackageTypePipeline(type, expectedJPackageExitCode, - expectedInstallExitCode, getPackageHandlers(type), handler.copy(), cmd); + expectedInstallExitCodes, getPackageHandlers(type), handler.copy(), cmd); } private record Handler(List> initializers, @@ -929,7 +936,7 @@ public final class PackageTest extends RunnablePackageTest { private Collection currentTypes; private Set excludeTypes; private int expectedJPackageExitCode; - private int expectedInstallExitCode; + private Set expectedInstallExitCodes; private final Map handlers; private final Set namedInitializers; private final Map packageHandlers; diff --git a/test/jdk/tools/jpackage/windows/WinOSConditionTest.java b/test/jdk/tools/jpackage/windows/WinOSConditionTest.java index c92ad7701b5..aea7e9e99b2 100644 --- a/test/jdk/tools/jpackage/windows/WinOSConditionTest.java +++ b/test/jdk/tools/jpackage/windows/WinOSConditionTest.java @@ -62,6 +62,17 @@ public class WinOSConditionTest { "--resource-dir", resourceDir.toString()).setFakeRuntime(); }) .addUninstallVerifier(cmd -> { + // Installation could have ended up with 1603 or 1625 error codes. + // MSI error code 1625 indicates the test is being executed in an environment + // that doesn't allow per-user installations. This means the test should be skipped. + try (final var lines = cmd.winMsiLogFileContents().orElseThrow()) { + if (lines.anyMatch(line -> { + return line.endsWith("Installation success or error status: 1625."); + })) { + TKit.throwSkippedException("Installation of per-user packages by the current user is forbidden by system policy"); + } + } + // MSI error code 1603 is generic. // Dig into the last msi log file for log messages specific to failed condition. try (final var lines = cmd.winMsiLogFileContents().orElseThrow()) { @@ -72,7 +83,7 @@ public class WinOSConditionTest { } }) .createMsiLog(true) - .setExpectedInstallExitCode(1603) + .setExpectedInstallExitCode(1603, 1625) // Create, try install the package (installation should fail) and verify it is not installed. .run(Action.CREATE, Action.INSTALL, Action.VERIFY_UNINSTALL); }