Skip to content

Commit

Permalink
Stop relying on org.graalvm.home.Version
Browse files Browse the repository at this point in the history
  • Loading branch information
zakkak committed Sep 20, 2023
1 parent 87117ac commit 247001f
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 52 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.quarkus.deployment.pkg.steps;

import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -138,23 +139,33 @@ public static final class Version implements Comparable<Version> {
public static final int UNDEFINED = -1;

final String fullVersion;
final org.graalvm.home.Version version;
public final int javaFeatureVersion;
public final int javaUpdateVersion;
final Distribution distribution;
private int[] versions;
private String suffix;

Version(String fullVersion, String version, Distribution distro) {
this(fullVersion, version, 11, UNDEFINED, distro);
}

Version(String fullVersion, String version, int javaFeatureVersion, int javaUpdateVersion, Distribution distro) {
this.fullVersion = fullVersion;
this.version = org.graalvm.home.Version.parse(version);
breakdownVersion(version);
this.javaFeatureVersion = javaFeatureVersion;
this.javaUpdateVersion = javaUpdateVersion;
this.distribution = distro;
}

private void breakdownVersion(String version) {
int dash = version.indexOf('-');
if (dash != -1) {
this.suffix = version.substring(dash + 1);
version = version.substring(0, dash);
}
this.versions = Arrays.stream(version.split("\\.")).mapToInt(Integer::parseInt).toArray();
}

String getFullVersion() {
return fullVersion;
}
Expand Down Expand Up @@ -189,11 +200,27 @@ boolean is(Version version) {

@Override
public int compareTo(Version o) {
return this.version.compareTo(o.version);
int i = 0;
for (; i < this.versions.length; i++) {
if (i >= o.versions.length) {
if (this.versions[i] != 0) {
return 1;
}
} else if (this.versions[i] != o.versions[i]) {
return this.versions[i] - o.versions[i];
}
}
for (; i < o.versions.length; i++) {
if (o.versions[i] != 0) {
return -1;
}
}
return 0;
}

static Version of(Stream<String> output) {
List<String> lines = output
public static Version of(Stream<String> output) {
String stringOutput = output.collect(Collectors.joining("\n"));
List<String> lines = stringOutput.lines()
.dropWhile(l -> !l.startsWith("GraalVM") && !l.startsWith("native-image"))
.collect(Collectors.toUnmodifiableList());

Expand Down Expand Up @@ -227,17 +254,26 @@ static Version of(Stream<String> output) {
}

throw new IllegalArgumentException(
"Cannot parse version from output: " + output.collect(Collectors.joining("\n")));
"Cannot parse version from output: \n" + stringOutput);
}

private static boolean isMandrel(String s) {
return s != null && s.contains("Mandrel Distribution");
}

/**
* Returns the Mandrel/GraalVM version as a string. e.g. 21.3.0-rc1
*/
public String getVersionAsString() {
return String.join(Arrays.stream(versions).mapToObj(Integer::toString).collect(Collectors.joining()), ".") + "-"
+ suffix;
}

@Override
public String toString() {
return "Version{" +
"version=" + version +
"version="
+ getVersionAsString() +
", fullVersion=" + fullVersion +
", distribution=" + distribution +
", javaFeatureVersion=" + javaFeatureVersion +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ ArtifactResultBuildItem nativeSourcesResult(NativeConfig nativeConfig,

try {
Files.writeString(outputDir.resolve("native-image.args"), String.join(" ", command));
Files.writeString(outputDir.resolve("graalvm.version"), GraalVM.Version.CURRENT.version.toString());
Files.writeString(outputDir.resolve("graalvm.version"), GraalVM.Version.CURRENT.getVersionAsString());
if (nativeImageRunner.isContainerBuild()) {
Files.writeString(outputDir.resolve("native-builder.image"), nativeConfig.builderImage().getEffectiveImage());
}
Expand Down Expand Up @@ -297,7 +297,7 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, LocalesBuildTimeCon

return new NativeImageBuildItem(finalExecutablePath,
new NativeImageBuildItem.GraalVMVersion(graalVMVersion.fullVersion,
graalVMVersion.version.toString(),
graalVMVersion.getVersionAsString(),
graalVMVersion.javaFeatureVersion,
graalVMVersion.distribution.name()));
} catch (ImageGenerationFailureException e) {
Expand Down Expand Up @@ -462,7 +462,7 @@ private void checkGraalVMVersion(GraalVM.Version version) {
log.info("Running Quarkus native-image plugin on " + version.getFullVersion());
if (version.isObsolete()) {
throw new IllegalStateException("Out of date version of GraalVM detected: " + version.getFullVersion() + "."
+ " Quarkus currently supports " + GraalVM.Version.CURRENT.version
+ " Quarkus currently supports " + GraalVM.Version.CURRENT.getVersionAsString()
+ ". Please upgrade GraalVM to this version.");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@ public class GraalVMTest {
@Test
public void testGraalVMVersionDetected() {
// Version detection after: https://github.com/oracle/graal/pull/6302 (3 lines of version output)
assertVersion(org.graalvm.home.Version.create(23, 0, 0), MANDREL,
assertVersion(new Version("GraalVM 23.0.0", "23.0.0", ORACLE), MANDREL,
Version.of(Stream.of(("native-image 17.0.6 2023-01-17\n"
+ "OpenJDK Runtime Environment Mandrel-23.0.0-dev (build 17.0.6+10)\n"
+ "OpenJDK 64-Bit Server VM Mandrel-23.0.0-dev (build 17.0.6+10, mixed mode)").split("\\n"))));
assertVersion(org.graalvm.home.Version.create(23, 0, 0), MANDREL,
assertVersion(new Version("GraalVM 23.0.0", "23.0.0", ORACLE), MANDREL,
Version.of(Stream.of(("native-image 17.0.6 2023-01-17\n"
+ "GraalVM Runtime Environment Mandrel-23.0.0-dev (build 17.0.6+10)\n"
+ "Substrate VM Mandrel-23.0.0-dev (build 17.0.6+10, serial gc)").split("\\n"))));
assertVersion(org.graalvm.home.Version.create(23, 0, 0), MANDREL,
assertVersion(new Version("GraalVM 23.0.0", "23.0.0", ORACLE), MANDREL,
Version.of(Stream.of(("native-image 17.0.7 2023-04-18\n"
+ "OpenJDK Runtime Environment Mandrel-23.0.0.0-Final (build 17.0.7+7)\n"
+ "OpenJDK 64-Bit Server VM Mandrel-23.0.0.0-Final (build 17.0.7+7, mixed mode)").split("\\n"))));
// should also work when the image is not around and we have to download it
assertVersion(org.graalvm.home.Version.create(23, 0, 0), MANDREL,
assertVersion(new Version("GraalVM 23.0.0", "23.0.0", ORACLE), MANDREL,
Version.of(
Stream.of(("Unable to find image 'quay.io/quarkus/ubi-quarkus-mandrel-builder-image:jdk-17' locally\n"
+ "jdk-17: Pulling from quarkus/ubi-quarkus-mandrel-builder-image\n"
Expand All @@ -57,36 +57,36 @@ public void testGraalVMVersionDetected() {
+ "OpenJDK Runtime Environment Mandrel-23.0.0.0-Final (build 17.0.7+7)\n"
+ "OpenJDK 64-Bit Server VM Mandrel-23.0.0.0-Final (build 17.0.7+7, mixed mode)")
.split("\\n"))));
assertVersion(org.graalvm.home.Version.create(23, 0), ORACLE,
assertVersion(new Version("GraalVM 23.0", "23.0", ORACLE), ORACLE,
Version.of(Stream.of(("native-image 20 2023-03-21\n"
+ "GraalVM Runtime Environment GraalVM CE (build 20+34-jvmci-23.0-b10)\n"
+ "Substrate VM GraalVM CE (build 20+34, serial gc)").split("\\n"))));

// Older version parsing
assertVersion(org.graalvm.home.Version.create(20, 1), ORACLE,
assertVersion(new Version("GraalVM 20.1", "20.1", ORACLE), ORACLE,
Version.of(Stream.of("GraalVM Version 20.1.0 (Java Version 11.0.7)")));
assertVersion(org.graalvm.home.Version.create(20, 1, 0, 1), MANDREL, Version
assertVersion(new Version("GraalVM 20.1.0.1", "20.1.0.1", ORACLE), MANDREL, Version
.of(Stream.of("GraalVM Version 20.1.0.1.Alpha2 56d4ee1b28 (Mandrel Distribution) (Java Version 11.0.8)")));
assertVersion(org.graalvm.home.Version.create(20, 1, 0, 1), MANDREL, Version
assertVersion(new Version("GraalVM 20.1.0.1", "20.1.0.1", ORACLE), MANDREL, Version
.of(Stream.of("GraalVM Version 20.1.0.1-Final 56d4ee1b28 (Mandrel Distribution) (Java Version 11.0.8)")));
assertVersion(org.graalvm.home.Version.create(21, 0), MANDREL, Version
assertVersion(new Version("GraalVM 21.0", "21.0", ORACLE), MANDREL, Version
.of(Stream.of("GraalVM Version 21.0.0.0-0b3 (Mandrel Distribution) (Java Version 11.0.8)")));
assertVersion(org.graalvm.home.Version.create(20, 3, 1, 2), MANDREL, Version
assertVersion(new Version("GraalVM 20.3.1.2", "20.3.1.2", ORACLE), MANDREL, Version
.of(Stream.of("GraalVM Version 20.3.1.2-dev (Mandrel Distribution) (Java Version 11.0.8)")));
assertVersion(org.graalvm.home.Version.create(21, 1), MANDREL, Version
assertVersion(new Version("GraalVM 21.1", "21.1", ORACLE), MANDREL, Version
.of(Stream.of("native-image 21.1.0.0-Final (Mandrel Distribution) (Java Version 11.0.11+9)")));
assertVersion(org.graalvm.home.Version.create(21, 1), MANDREL, Version
assertVersion(new Version("GraalVM 21.1", "21.1", ORACLE), MANDREL, Version
.of(Stream.of("GraalVM 21.1.0.0-Final (Mandrel Distribution) (Java Version 11.0.11+9)")));
assertVersion(org.graalvm.home.Version.create(21, 1), ORACLE, Version
assertVersion(new Version("GraalVM 21.1", "21.1", ORACLE), ORACLE, Version
.of(Stream.of("GraalVM 21.1.0 Java 11 CE (Java Version 11.0.11+5-jvmci-21.1-b02)")));
assertVersion(org.graalvm.home.Version.create(21, 1), ORACLE, Version
assertVersion(new Version("GraalVM 21.1", "21.1", ORACLE), ORACLE, Version
.of(Stream.of("native-image 21.1.0.0 Java 11 CE (Java Version 11.0.11+5-jvmci-21.1-b02)")));
assertVersion(org.graalvm.home.Version.create(21, 2), MANDREL, Version
assertVersion(new Version("GraalVM 21.2", "21.2", ORACLE), MANDREL, Version
.of(Stream.of("native-image 21.2.0.0-Final Mandrel Distribution (Java Version 11.0.12+7)")));
}

static void assertVersion(org.graalvm.home.Version graalVmVersion, Distribution distro, Version version) {
assertThat(graalVmVersion.compareTo(version.version)).isEqualTo(0);
static void assertVersion(Version graalVmVersion, Distribution distro, Version version) {
assertThat(graalVmVersion.compareTo(version)).isEqualTo(0);
assertThat(version.distribution).isEqualTo(distro);
if (distro == MANDREL) {
assertThat(version.isMandrel()).isTrue();
Expand All @@ -99,6 +99,18 @@ public void testGraalVMVersionsOlderThan() {
assertOlderThan("GraalVM Version 20.0.0 (Java Version 11.0.7)", "GraalVM Version 20.1.0 (Java Version 11.0.8)");
assertOlderThan("GraalVM Version 21.2.0 (Java Version 11.0.12)", Version.VERSION_21_3);
assertOlderThan("GraalVM Version 21.2.0 (Java Version 11.0.12)", Version.VERSION_21_3_0);
assertOlderThan("native-image 21 2023-09-19\n" +
"GraalVM Runtime Environment GraalVM CE 21+35.1 (build 21+35-jvmci-23.1-b15)\n" +
"Substrate VM GraalVM CE 21+35.1 (build 21+35, serial gc)\n",
"native-image 21-beta 2023-09-19\n" +
"OpenJDK Runtime Environment Mandrel-23.1.0.1-devde078ae3bea (build 21-beta+35-ea)\n" +
"OpenJDK 64-Bit Server VM Mandrel-23.1.0.1-devde078ae3bea (build 21-beta+35-ea, mixed mode)");
assertOlderThan("native-image 21-beta 2023-09-19\n" +
"OpenJDK Runtime Environment Mandrel-23.0.0.1-devde078ae3bea (build 21-beta+35-ea)\n" +
"OpenJDK 64-Bit Server VM Mandrel-23.0.0.1-devde078ae3bea (build 21-beta+35-ea, mixed mode)",
"native-image 21 2023-09-19\n" +
"GraalVM Runtime Environment GraalVM CE 21+35.1 (build 21+35-jvmci-23.1-b15)\n" +
"Substrate VM GraalVM CE 21+35.1 (build 21+35, serial gc)\n");
}

/**
Expand Down Expand Up @@ -126,17 +138,24 @@ public void testGraalVMVersionsCompareEqualTo() {
assertCompareEqualTo("GraalVM 21.3.0 Java 11 CE (Java Version 11.0.13+7-jvmci-21.3-b05)",
"GraalVM 21.3.0.0.0.0 Java 11 CE (Java Version 11.0.13+7-jvmci-21.3-b05)");
assertThat(Version.VERSION_21_3.compareTo(Version.VERSION_21_3_0)).isEqualTo(0);
assertCompareEqualTo("native-image 21-beta 2023-09-19\n" +
"OpenJDK Runtime Environment Mandrel-23.1.0.0-devde078ae3bea (build 21-beta+35-ea)\n" +
"OpenJDK 64-Bit Server VM Mandrel-23.1.0.0-devde078ae3bea (build 21-beta+35-ea, mixed mode)",
"native-image 21 2023-09-19\n" +
"GraalVM Runtime Environment GraalVM CE 21+35.1 (build 21+35-jvmci-23.1-b15)\n" +
"Substrate VM GraalVM CE 21+35.1 (build 21+35, serial gc)\n");
}

/**
* Asserts that version is equals to other when compared.
*/
static void assertCompareEqualTo(String version, String other) {
assertThat(Version.of(Stream.of(version)).compareTo(Version.of(Stream.of(other)))).isEqualTo(0);
assertThat(Version.of(Stream.of(version.split("\\n"))).compareTo(Version.of(Stream.of(other.split("\\n")))))
.isEqualTo(0);
}

static void assertCompareNotEqualTo(String version, String other) {
assertThat(Version.of(Stream.of(version)).compareTo(Version.of(Stream.of(other)))).isNotEqualTo(0);
assertThat(Version.of(Stream.of(version)).compareTo(Version.of(Stream.of(other.split("\\n"))))).isNotEqualTo(0);
}

@Test
Expand All @@ -150,6 +169,18 @@ public void testGraalVMVersionsNewerThan() {
"GraalVM 21.3 Java 11 CE (Java Version 11.0.13+7-jvmci-21.3-b05)");
assertNewerThan("native-image 22.3.0-dev6d51160e2f3 Mandrel Distribution (Java Version 17.0.4-beta+7-202206162318)",
"native-image 22.2.0-dev6d51160e2f3 Mandrel Distribution (Java Version 17.0.4-beta+7-202206162318)");
assertNewerThan("native-image 21-beta 2023-09-19\n" +
"OpenJDK Runtime Environment Mandrel-23.1.0.1-devde078ae3bea (build 21-beta+35-ea)\n" +
"OpenJDK 64-Bit Server VM Mandrel-23.1.0.1-devde078ae3bea (build 21-beta+35-ea, mixed mode)",
"native-image 21 2023-09-19\n" +
"GraalVM Runtime Environment GraalVM CE 21+35.1 (build 21+35-jvmci-23.1-b15)\n" +
"Substrate VM GraalVM CE 21+35.1 (build 21+35, serial gc)\n");
assertNewerThan("native-image 21 2023-09-19\n" +
"GraalVM Runtime Environment GraalVM CE 21+35.1 (build 21+35-jvmci-23.1-b15)\n" +
"Substrate VM GraalVM CE 21+35.1 (build 21+35, serial gc)\n",
"native-image 21-beta 2023-09-19\n" +
"OpenJDK Runtime Environment Mandrel-23.0.0.1-devde078ae3bea (build 21-beta+35-ea)\n" +
"OpenJDK 64-Bit Server VM Mandrel-23.0.0.1-devde078ae3bea (build 21-beta+35-ea, mixed mode)");
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import org.junit.jupiter.api.extension.ExecutionCondition;
import org.junit.jupiter.api.extension.ExtensionContext;

import io.quarkus.deployment.pkg.steps.GraalVM;

public class DisableIfBuiltWithGraalVMNewerThanCondition implements ExecutionCondition {

private static final String QUARKUS_INTEGRATION_TEST_NAME = QuarkusIntegrationTest.class.getName();
Expand All @@ -33,9 +35,9 @@ public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext con
GraalVMVersion annotationValue = optional.get().value();
Properties quarkusArtifactProperties = readQuarkusArtifactProperties(context);
try {
org.graalvm.home.Version version = org.graalvm.home.Version
.parse(quarkusArtifactProperties.getProperty("metadata.graalvm.version.version"));
int comparison = annotationValue.compareTo(version);
GraalVM.Version version = GraalVM.Version
.of(quarkusArtifactProperties.getProperty("metadata.graalvm.version.version").lines());
int comparison = annotationValue.getVersion().compareTo(version);
if (comparison < 0) {
return ConditionEvaluationResult.disabled("Native binary was built with GraalVM{version=" + version.toString()
+ "} but the test is disabled for GraalVM versions newer than " + annotationValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import org.junit.jupiter.api.extension.ExecutionCondition;
import org.junit.jupiter.api.extension.ExtensionContext;

import io.quarkus.deployment.pkg.steps.GraalVM;

public class DisableIfBuiltWithGraalVMOlderThanCondition implements ExecutionCondition {

private static final String QUARKUS_INTEGRATION_TEST_NAME = QuarkusIntegrationTest.class.getName();
Expand All @@ -33,9 +35,9 @@ public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext con
GraalVMVersion annotationValue = optional.get().value();
Properties quarkusArtifactProperties = readQuarkusArtifactProperties(context);
try {
org.graalvm.home.Version version = org.graalvm.home.Version
.parse(quarkusArtifactProperties.getProperty("metadata.graalvm.version.version"));
int comparison = annotationValue.compareTo(version);
GraalVM.Version version = GraalVM.Version
.of(quarkusArtifactProperties.getProperty("metadata.graalvm.version.version").lines());
int comparison = annotationValue.getVersion().compareTo(version);
if (comparison > 0) {
return ConditionEvaluationResult.disabled("Native binary was built with GraalVM{version=" + version.toString()
+ "} but the test is disabled for GraalVM versions older than " + annotationValue);
Expand Down
Loading

0 comments on commit 247001f

Please sign in to comment.