8370120: Make jpackage tests output more stable

Reviewed-by: almatvee
This commit is contained in:
Alexey Semenyuk 2025-10-18 01:14:42 +00:00
parent b0af41d667
commit eff6439e75
12 changed files with 98 additions and 49 deletions

View File

@ -215,7 +215,7 @@ final class JLinkRuntimeBuilder implements RuntimeBuilder {
}
private static String getStringList(Set<String> strings) {
return strings.stream().collect(Collectors.joining(","));
return strings.stream().sorted().collect(Collectors.joining(","));
}
private final List<String> jlinkCmdLine;

View File

@ -24,15 +24,16 @@
*/
package jdk.jpackage.internal;
import static java.util.stream.Collectors.toMap;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Path;
import java.util.EnumSet;
import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import jdk.jpackage.internal.resources.ResourceLocator;
/**
@ -46,11 +47,11 @@ final class PackageScripts<T extends Enum<T> & Supplier<OverridableResource>> {
}
PackageScripts(Class<T> scriptIdsType) {
scripts = EnumSet.allOf(scriptIdsType).stream().collect(
Collectors.toMap(UnaryOperator.identity(), scriptId -> {
return new ShellScriptResource(scriptId.name()).setResource(
scriptId.get());
}));
scripts = EnumSet.allOf(scriptIdsType).stream().collect(toMap(x -> x, scriptId -> {
return new ShellScriptResource(scriptId.name()).setResource(scriptId.get());
}, (a, b) -> {
throw new UnsupportedOperationException();
}, TreeMap::new));
}
PackageScripts<T> setSubstitutionData(T id, Map<String, String> data) {

View File

@ -38,6 +38,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import javax.xml.XMLConstants;
@ -193,7 +194,7 @@ final class WixSourceConverter {
}
}
private final Map<Path, OverridableResource> resources = new HashMap<>();
private final Map<Path, OverridableResource> resources = new TreeMap<>();
private final WixToolsetType wixToolsetType;
}

View File

@ -69,6 +69,7 @@ public class PrintEnv {
lines.add(ModuleFinder.ofSystem().findAll().stream()
.map(ModuleReference::descriptor)
.map(ModuleDescriptor::name)
.sorted()
.collect(Collectors.joining(",")));
} else if (arg.equals(PRINT_WORK_DIR)) {
lines.add("$CD=" + Path.of("").toAbsolutePath());

View File

@ -120,8 +120,7 @@ macDmgFilterScpt() {
# - Trim random absolute temp path
# - Replace "/dmg-workdir/" (new) with "/images/" (old)
find "$stash_dir" -name '*.scpt' -type f | xargs -I {} sed $sed_inplace_option \
-e 's|"/.*/jdk.jpackage[0-9]\{1,\}/|"/jdk.jpackage/|' \
-e 's|"file:///.*/jdk.jpackage[0-9]\{1,\}/|"file:///jdk.jpackage/|' \
-e 's|/jdk.jpackage[0-9]\{1,\}/|/jdk.jpackage/|' \
-e 's|/dmg-workdir/|/images/|' \
'{}'
}

View File

@ -56,6 +56,9 @@ filterFile () {
# Strip variable part of temporary directory name `jdk.jpackage5060841750457404688`
-e 's|\([\/]\)jdk\.jpackage[0-9]\{1,\}\b|\1jdk.jpackage|g'
# Strip variable part of temporary directory name `jdk.jpackage.test217379316521032539`
-e 's|\([\/]\)jdk\.jpackage\.test[0-9]\{1,\}\b|\1jdk.jpackage.test|g'
# Convert PID value `[PID: 131561]`
-e 's/\[PID: [0-9]\{1,\}\]/[PID: <pid>]/'
@ -76,6 +79,41 @@ filterFile () {
# Convert variable part of stack trace entry `at jdk.jpackage.test.JPackageCommand.execute(JPackageCommand.java:863)`
-e 's/^\(.*\b\.java:\)[0-9]\{1,\}\()\r\{0,1\}\)$/\1N\2/'
# Whipe out entire output of /usr/bin/hdiutil command.
# It is of little to no interest and contains too many variable parts to deal with individually.
-e '/^Running \/usr\/bin\/hdiutil/,/^Returned:/{
//,/^Output:/!d
}'
# Zip stack traces.
-e $'/^\tat /{
:a
g
N
s/.*\\n//
/^\tat /ba
s/\\(^\t... \\)[0-9]\\{1,\\}\\( more\\)/\\1N\\2/
s/\(.*\)/\tat <stacktrace>\\n\\1/
P
D
}'
# Convert PID value in `taskkill /F /PID 5640`
-e 's|taskkill /F /PID [0-9]\{1,\}|taskkill /F /PID <pid>|'
# Convert PID value in `The process with PID 5640 has been terminated`
-e 's|\(The process with PID \)[0-9]\{1,\}\( has been terminated\)|\1<pid>\2|'
# Convert timeout value in `Check timeout value 57182ms is positive`
-e 's|\(Check timeout value \)[0-9]\{1,\}\(ms is positive\)|\1<timeout>\2|'
# Convert variable part of /usr/bin/osascript output `jdk.jpackage/config/SigningRuntimeImagePackageTest-dmg-setup.scpt:455:497: execution error: Finder got an error: Cant set 1 to icon view. (-10006)`
-e 's|\(-dmg-setup.scpt:\)[0-9]\{1,\}:[0-9]\{1,\}\(: execution error: \)|\1<N:M>\2|'
# Use the same name for all exceptions.
-e 's|[^ ]\{1,\}\.[^ ]\{1,\}\Exception:|<Exception>:|g'
-e 's|[^ ]\{1,\}\.[^ ]\{1,\}\ExceptionBox:|<Exception>:|g'
)
sed $sed_inplace_option "$1" "${expressions[@]}"

View File

@ -27,12 +27,11 @@ import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;
import java.util.TreeMap;
import jdk.jpackage.internal.util.PathUtils;
@ -44,7 +43,7 @@ public final class FileAssociations {
}
private void createFile() {
Map<String, String> entries = new HashMap<>(Map.of(
Map<String, String> entries = new TreeMap<>(Map.of(
"extension", suffixName,
"mime-type", getMime()
));

View File

@ -22,6 +22,8 @@
*/
package jdk.jpackage.test;
import static java.util.Collections.unmodifiableSortedSet;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.reflect.InvocationTargetException;
@ -32,12 +34,13 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Matcher;
@ -389,8 +392,7 @@ public final class LinuxHelper {
Map<Scriptlet, List<String>> scriptlets = getScriptlets(cmd);
if (integrated) {
Set<Scriptlet> requiredScriptlets = Stream.of(Scriptlet.values()).sorted().collect(
Collectors.toSet());
var requiredScriptlets = Stream.of(Scriptlet.values()).sorted().toList();
TKit.assertTrue(scriptlets.keySet().containsAll(
requiredScriptlets), String.format(
"Check all required scriptlets %s found in the package. Package scriptlets: %s",
@ -488,13 +490,13 @@ public final class LinuxHelper {
var data = new DesktopFile(desktopFile, true);
final Set<String> mandatoryKeys = new HashSet<>(Set.of("Name", "Comment",
final Set<String> mandatoryKeys = new TreeSet<>(Set.of("Name", "Comment",
"Exec", "Icon", "Terminal", "Type", "Categories"));
mandatoryKeys.removeAll(data.keySet());
TKit.assertTrue(mandatoryKeys.isEmpty(), String.format(
"Check for missing %s keys in the file", mandatoryKeys));
for (var e : Map.of("Type", "Application", "Terminal", "false").entrySet()) {
for (var e : List.of(Map.entry("Type", "Application"), Map.entry("Terminal", "false"))) {
String key = e.getKey();
TKit.assertEquals(e.getValue(), data.find(key).orElseThrow(), String.format(
"Check value of [%s] key", key));
@ -710,7 +712,7 @@ public final class LinuxHelper {
private static Map<Scriptlet, List<String>> getDebScriptlets(
JPackageCommand cmd, Set<Scriptlet> scriptlets) {
Map<Scriptlet, List<String>> result = new HashMap<>();
Map<Scriptlet, List<String>> result = new TreeMap<>();
TKit.withTempDirectory("dpkg-control-files", tempDir -> {
// Extract control Debian package files into temporary directory
Executor.of("dpkg", "-e")
@ -732,7 +734,7 @@ public final class LinuxHelper {
List<String> output = Executor.of("rpm", "-qp", "--scripts",
cmd.outputBundle().toString()).executeAndGetOutput();
Map<Scriptlet, List<String>> result = new HashMap<>();
Map<Scriptlet, List<String>> result = new TreeMap<>();
List<String> curScriptletBody = null;
for (String str : output) {
Matcher m = Scriptlet.RPM_HEADER_PATTERN.matcher(str);
@ -887,7 +889,8 @@ public final class LinuxHelper {
private static final Pattern XDG_CMD_ICON_SIZE_PATTERN = Pattern.compile("\\s--size\\s+(\\d+)\\b");
// Values grabbed from https://linux.die.net/man/1/xdg-icon-resource
private static final Set<Integer> XDG_CMD_VALID_ICON_SIZES = Set.of(16, 22, 32, 48, 64, 128);
private static final Set<Integer> XDG_CMD_VALID_ICON_SIZES = unmodifiableSortedSet(
new TreeSet<>(List.of(16, 22, 32, 48, 64, 128)));
private static final Method getServiceUnitFileName = initGetServiceUnitFileName();
}

View File

@ -21,6 +21,7 @@
* questions.
*/
import static java.util.Collections.unmodifiableSortedSet;
import static java.util.Map.entry;
import static jdk.jpackage.internal.util.PListWriter.writeDict;
import static jdk.jpackage.internal.util.PListWriter.writePList;
@ -40,6 +41,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -142,12 +144,12 @@ public class CustomInfoPListTest {
if (customPLists.isEmpty()) {
throw new IllegalArgumentException();
}
customPLists = unmodifiableSortedSet(new TreeSet<>(customPLists));
}
@Override
public String toString() {
return customPLists.stream()
.sorted(Comparator.comparing(CustomPListType::role))
.map(CustomPListType::toString)
.collect(Collectors.joining("+"));
}
@ -155,12 +157,12 @@ public class CustomInfoPListTest {
JPackageCommand init(JPackageCommand cmd) throws IOException {
if (customPLists.contains(CustomPListType.APP_WITH_FA)) {
final Path propFile = TKit.createTempFile("fa.properties");
var map = Map.ofEntries(
final var props = List.of(
entry("mime-type", "application/x-jpackage-foo"),
entry("extension", "foo"),
entry("description", "bar")
);
TKit.createPropertiesFile(propFile, map);
TKit.createPropertiesFile(propFile, props);
cmd.setArgumentValue("--file-associations", propFile);
}

View File

@ -32,6 +32,7 @@ import static jdk.jpackage.test.MacHelper.writeFaPListFragment;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Stream;
@ -61,7 +62,7 @@ public class MacFileAssociationsTest {
@Test
public static void test() throws Exception {
final Path propFile = TKit.createTempFile("fa.properties");
Map<String, String> map = Map.ofEntries(
final var props = List.of(
entry("mime-type", "application/x-jpackage-foo"),
entry("extension", "foo"),
entry("description", "bar"),
@ -73,7 +74,7 @@ public class MacFileAssociationsTest {
entry("mac.UISupportsDocumentBrowser", "false"),
entry("mac.NSExportableTypes", "public.png, public.jpg"),
entry("mac.UTTypeConformsTo", "public.image, public.data"));
TKit.createPropertiesFile(propFile, map);
TKit.createPropertiesFile(propFile, props);
final var cmd = JPackageCommand.helloAppImage().setFakeRuntime();
cmd.addArguments("--file-associations", propFile);

View File

@ -21,10 +21,13 @@
* questions.
*/
import static java.util.Map.entry;
import static jdk.jpackage.test.JPackageStringBundle.MAIN;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import jdk.jpackage.test.Annotations.Parameter;
import jdk.jpackage.test.Annotations.Test;
import jdk.jpackage.test.FileAssociations;
@ -114,9 +117,9 @@ public class FileAssociationsTest {
final Path propFile = TKit.workDir().resolve("fa.properties");
initPackageTest().addRunOnceInitializer(() -> {
TKit.createPropertiesFile(propFile, Map.of(
"extension", "foo",
"description", "bar"
TKit.createPropertiesFile(propFile, List.of(
entry("extension", "foo"),
entry("description", "bar")
));
}).addInitializer(cmd -> {
cmd.addArguments("--file-associations", propFile);
@ -131,10 +134,10 @@ public class FileAssociationsTest {
final Path propFile = TKit.workDir().resolve("fa.properties");
initPackageTest().addRunOnceInitializer(() -> {
TKit.createPropertiesFile(propFile, Map.of(
"mime-type", "application/x-jpackage-foo, application/x-jpackage-bar",
"extension", "foo",
"description", "bar"
TKit.createPropertiesFile(propFile, List.of(
entry("mime-type", "application/x-jpackage-foo, application/x-jpackage-bar"),
entry("extension", "foo"),
entry("description", "bar")
));
}).addInitializer(cmd -> {
cmd.addArguments("--file-associations", propFile);

View File

@ -22,9 +22,6 @@
*/
import java.io.IOException;
import java.util.stream.Stream;
import java.util.stream.Collectors;
import java.util.function.Consumer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
@ -34,17 +31,21 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import jdk.jpackage.test.TKit;
import jdk.jpackage.test.JPackageCommand;
import jdk.jpackage.test.LauncherIconVerifier;
import jdk.jpackage.test.PackageTest;
import jdk.jpackage.test.Executor;
import jdk.jpackage.test.LinuxHelper;
import jdk.jpackage.test.AdditionalLauncher;
import jdk.jpackage.internal.util.function.ThrowingConsumer;
import java.util.TreeMap;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.jpackage.internal.util.function.ThrowingBiConsumer;
import jdk.jpackage.internal.util.function.ThrowingConsumer;
import jdk.jpackage.test.AdditionalLauncher;
import jdk.jpackage.test.Annotations.Parameters;
import jdk.jpackage.test.Annotations.Test;
import jdk.jpackage.test.Executor;
import jdk.jpackage.test.JPackageCommand;
import jdk.jpackage.test.LauncherIconVerifier;
import jdk.jpackage.test.LinuxHelper;
import jdk.jpackage.test.PackageTest;
import jdk.jpackage.test.TKit;
/*
* @test
@ -92,18 +93,18 @@ public class IconTest {
IconType additionalLauncherIconType, String[] extraJPackageArgs) {
this.appImage = (bundleType == BundleType.AppImage);
this.extraJPackageArgs = extraJPackageArgs;
config = Map.of(
config = new TreeMap<>(Map.of(
Launcher.Main, mainLauncherIconType,
Launcher.Additional, additionalLauncherIconType);
Launcher.Additional, additionalLauncherIconType));
}
public IconTest(BundleType bundleType, IconType mainLauncherIconType,
IconType additionalLauncherIconType) {
this.appImage = (bundleType == BundleType.AppImage);
this.extraJPackageArgs = new String[0];
config = Map.of(
config = new TreeMap<>(Map.of(
Launcher.Main, mainLauncherIconType,
Launcher.Additional, additionalLauncherIconType);
Launcher.Additional, additionalLauncherIconType));
}
public IconTest(BundleType bundleType, IconType mainLauncherIconType) {