Skip to content

Commit

Permalink
Merge pull request Karm#88 from Karm/jdk-min-max-version-annotation
Browse files Browse the repository at this point in the history
Adds minJDK and maxJDK to IfMandrelVersion annotation
  • Loading branch information
Karm authored Apr 4, 2022
2 parents 8f68c24 + dcaadea commit 98791f5
Show file tree
Hide file tree
Showing 10 changed files with 364 additions and 21 deletions.
1 change: 1 addition & 0 deletions .github/workflows/builder_image_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ jobs:
sudo apt-get update -y
sudo apt-get install -y gdb
pushd ts
mkdir -p ~/.m2/
cp .github/mvn-settings.xml ~/.m2/settings.xml
mvn clean verify -Ptestsuite-builder-image -Dquarkus.version=${{ matrix.quarkus-version }} -Dquarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel:${{ matrix.mandrel-builder-image }}
shell: bash
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/local_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ jobs:
cmd /C native-image --version
)
pushd ts
mkdir ~/.m2
copy .github/mvn-settings.xml ~/.m2/settings.xml
mvn clean verify -Ptestsuite -Dquarkus.version=${{ matrix.quarkus-version }}
shell: cmd
Expand All @@ -158,6 +159,7 @@ jobs:
fi
native-image --version
pushd ts
mkdir -p ~/.m2/
cp .github/mvn-settings.xml ~/.m2/settings.xml
mvn clean verify -Ptestsuite -Dquarkus.version=${{ matrix.quarkus-version }}
shell: bash
Expand Down
120 changes: 120 additions & 0 deletions .github/workflows/testing_testsuite.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
name: Testing testsuite

on:
workflow_dispatch:
push:
paths-ignore:
- 'LICENSE'
- '**.md'
pull_request:
types: [ opened, synchronize, reopened, ready_for_review ]
paths-ignore:
- 'LICENSE'
- '**.md'

env:
LANG: en_US.UTF-8

jobs:
local-run:
name: ${{ matrix.os }} - ${{ matrix.java-version }} - ${{ matrix.mandrel-version }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
mandrel-version: [ '21.3.1.1-Final', '22.0.0.2-Final' ]
java-version: [ '11', '17' ]
os: [ ubuntu-20.04, windows-2019 ]
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 1
path: ts
- name: Cache local Maven repository
uses: actions/cache@v2
with:
path: ~/.m2/repository
key: ${{ matrix.os }}-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ matrix.os }}-
- uses: actions/cache@v2
name: Mandrel installation cached
id: cache_mandrel
with:
path: |
${{ github.workspace }}/${{ matrix.java-version }}-${{ matrix.mandrel-version }}
key: ${{ matrix.os }}-${{ matrix.java-version }}-${{ matrix.mandrel-version }}
- name: Install Mandrel Windows
if: startsWith(matrix.os, 'windows') && steps.cache_mandrel.outputs.cache-hit != 'true'
run: |
$url= "https://github.com/graalvm/mandrel/releases/download/mandrel-${{ matrix.mandrel-version }}/mandrel-java${{ matrix.java-version }}-windows-amd64-${{ matrix.mandrel-version }}.zip"
$wc = New-Object System.Net.WebClient
$file = $(Split-Path -Path $url -Leaf)
Write-Host "Downloading $url to $Env:temp\$file"
$wc.DownloadFile($url, "$Env:temp\$file")
Expand-Archive "$Env:temp\$file" -DestinationPath "${{ github.workspace }}"
$path=(Get-ChildItem mandrel-*).name
move $path ${{ github.workspace }}/${{ matrix.java-version }}-${{ matrix.mandrel-version }}
shell: powershell
- name: Install Mandrel Linux
if: startsWith(matrix.os, 'ubuntu') && steps.cache_mandrel.outputs.cache-hit != 'true'
run: |
wget "https://github.com/graalvm/mandrel/releases/download/mandrel-${{ matrix.mandrel-version }}/mandrel-java${{ matrix.java-version }}-linux-amd64-${{ matrix.mandrel-version }}.tar.gz"
tar -xf mandrel-java${{ matrix.java-version }}-linux-amd64-${{ matrix.mandrel-version }}.tar.gz
rm *.tar.gz
mv $( echo mandrel-java${{ matrix.java-version }}*-*/ ) ${{ github.workspace }}/${{ matrix.java-version }}-${{ matrix.mandrel-version }}
shell: bash
- name: Windows test
if: startsWith(matrix.os, 'windows')
timeout-minutes: 55
env:
MAVEN_OPTS: -Xmx1g
run: |
set PATH=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\;%PATH%
call vcvars64
IF NOT %ERRORLEVEL% == 0 ( exit 1 )
set "GRAALVM_HOME=${{ github.workspace }}\${{ matrix.java-version }}-${{ matrix.mandrel-version }}"
set "JAVA_HOME=%GRAALVM_HOME%"
set "PATH=%JAVA_HOME%\bin;%PATH%"
if not exist "%GRAALVM_HOME%\bin\native-image.cmd" (
echo "Cannot find native-image tool. Quitting..."
exit 1
) else (
echo "native-image.cmd is present, good."
cmd /C native-image --version
)
pushd ts
mkdir ~/.m2/
copy .github/mvn-settings.xml ~/.m2/settings.xml
mvn clean verify -Ptestsuite -DexcludeTags=all -DincludeTags=testing-testsuite
shell: cmd
- name: Linux test
if: startsWith(matrix.os, 'ubuntu')
timeout-minutes: 55
env:
MAVEN_OPTS: -Xmx1g
run: |
sudo apt-get update -y
sudo apt-get install -y gdb
export JAVA_HOME=${{ github.workspace }}/${{ matrix.java-version }}-${{ matrix.mandrel-version }}
export GRAALVM_HOME="${JAVA_HOME}"
export PATH="${JAVA_HOME}/bin:$PATH"
if [[ ! -e "${JAVA_HOME}/bin/native-image" ]]; then
echo "Cannot find native-image tool. Quitting..."
exit 1
fi
native-image --version
pushd ts
mkdir -p ~/.m2/
cp .github/mvn-settings.xml ~/.m2/settings.xml
mvn clean verify -Ptestsuite -DexcludeTags=all -DincludeTags=testing-testsuite
shell: bash
- name: Prepare failure archive (if maven failed)
if: failure()
run: tar czvf test-reports-mandrel-it.tgz ${{ github.workspace }}/ts/testsuite/target/archived-logs
- name: Upload failure Archive (if maven failed)
uses: actions/upload-artifact@v2
if: failure()
with:
name: reports-${{ matrix.mandrel-version }}-${{ matrix.java-version }}-${{ matrix.os }}
path: 'test-reports-mandrel-it.tgz'
2 changes: 1 addition & 1 deletion testsuite/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
<dependency>
<groupId>org.graalvm.sdk</groupId>
<artifactId>graal-sdk</artifactId>
<version>21.2.0</version>
<version>21.3.1</version>
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.condition.DisabledOnJre;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.JRE;
import org.junit.jupiter.api.condition.OS;

import java.io.File;
Expand Down Expand Up @@ -572,8 +570,7 @@ public void timezonesBakedIn(TestInfo testInfo) throws IOException, InterruptedE
@Test
@Tag("jdk-17")
@Tag("recordannotations")
@DisabledOnJre(JRE.JAVA_11)
@IfMandrelVersion(min = "21.3.1.1")
@IfMandrelVersion(min = "21.3.1.1", minJDK = "17")
public void recordAnnotationsWork(TestInfo testInfo) throws IOException, InterruptedException {
final Apps app = Apps.RECORDANNOTATIONS;
LOGGER.info("Testing app: " + app);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,25 @@
*
* IfMandrelVersion(min = "21.1", inContainer = true)
* i.e. [21.1, +∞)
*
* IfMandrelVersion(min = "21.3.1", minJDK = "17")
* i.e. [21.3.1, +∞) and [17, +∞)
*
* IfMandrelVersion(min = "22", minJDK = "17", maxJDK = "17.0.2")
* i.e. [22, +∞) and [17, 17.0.2]
*
* //@formatter:on
* Note that versions 21.1.0.0-final and 21.1.0.0-snapshot and 21.1.0.0 are all considered equal.
*
* The actual comparator comes from Graal's own org.graalvm.home.Version.
*
* inContainer: Whether the version should be pulled from a builder image container.
*
* JDK versions comparator uses feature.interim.update, the fourth, patch number or
* any other qualifiers following that are not used, i.e.
* 17.0.3-beta+5-202203292328 and 17.0.3-beta+6 are the same and
* 11.0.14.1+1-LTS and 11.0.14 are the same.
*
* @author Michal Karm Babacek <karm@redhat.com>
*/
@Target(ElementType.METHOD)
Expand All @@ -58,5 +70,9 @@

String max() default "";

String minJDK() default "";

String maxJDK() default "";

boolean inContainer() default false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@
import org.junit.jupiter.api.extension.ExtensionContext;

import java.lang.reflect.AnnotatedElement;
import java.util.regex.Pattern;

import static java.lang.String.format;
import static org.graalvm.tests.integration.utils.versions.UsedVersion.compareJDKVersion;
import static org.graalvm.tests.integration.utils.versions.UsedVersion.featureInterimUpdate;
import static org.junit.jupiter.api.extension.ConditionEvaluationResult.disabled;
import static org.junit.jupiter.api.extension.ConditionEvaluationResult.enabled;
import static org.junit.platform.commons.support.AnnotationSupport.findAnnotation;
Expand All @@ -52,15 +55,28 @@ public ConditionEvaluationResult evaluateExecutionCondition(

private ConditionEvaluationResult disableIfVersionMismatch(IfMandrelVersion annotation, AnnotatedElement element) {
final Version usedVersion = UsedVersion.getVersion(annotation.inContainer());
if (annotation.min().isBlank() || usedVersion.compareTo(Version.parse(annotation.min())) >= 0) {
if (annotation.max().isBlank() || usedVersion.compareTo(Version.parse(annotation.max())) <= 0) {
return enabled(format(
"%s is enabled as Mandrel version %s does satisfy constraints: minVersion: %s, maxVersion: %s",
element, usedVersion.toString(), annotation.min(), annotation.max()));
}
boolean jdkConstraintSatisfied = true;
if (!annotation.minJDK().isBlank() || !annotation.maxJDK().isBlank()) {
final int[] jdkVersion = new int[]{
UsedVersion.jdkFeature(annotation.inContainer()),
UsedVersion.jdkInterim(annotation.inContainer()),
UsedVersion.jdkUpdate(annotation.inContainer())
};
final Pattern p = Pattern.compile("(?<jfeature>[0-9]+)(\\.(?<jinterim>[0-9]*)\\.(?<jupdate>[0-9]*))?");
final int[] min = featureInterimUpdate(p, annotation.minJDK(), Integer.MIN_VALUE);
final int[] max = featureInterimUpdate(p, annotation.maxJDK(), Integer.MAX_VALUE);
jdkConstraintSatisfied = compareJDKVersion(jdkVersion, min) >= 0 && compareJDKVersion(jdkVersion, max) <= 0;
}
final boolean mandrelConstraintSatisfied =
(annotation.min().isBlank() || usedVersion.compareTo(Version.parse(annotation.min())) >= 0) &&
(annotation.max().isBlank() || usedVersion.compareTo(Version.parse(annotation.max())) <= 0);
if (mandrelConstraintSatisfied && jdkConstraintSatisfied) {
return enabled(format(
"%s is enabled as Mandrel version %s does satisfy constraints: min: %s, max: %s, minJDK: %s, maxJDK: %s",
element, usedVersion.toString(), annotation.min(), annotation.max(), annotation.minJDK(), annotation.maxJDK()));
}
return disabled(format(
"%s is disabled as Mandrel version %s does not satisfy constraints: minVersion: %s, maxVersion: %s",
element, usedVersion, annotation.min(), annotation.max()));
"%s is disabled as Mandrel version %s does not satisfy constraints: min: %s, max: %s, minJDK: %s, maxJDK: %s",
element, usedVersion, annotation.min(), annotation.max(), annotation.minJDK(), annotation.maxJDK()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class QuarkusVersion implements Comparable<QuarkusVersion> {
private final int major;
private final int minor;
private final int patch;
private boolean snapshot;
private final boolean snapshot;

public QuarkusVersion(String version) {
this.version = version;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
* @author Michal Karm Babacek <karm@redhat.com>
*/
public class UsedVersion {
private static final int UNDEFINED = -1;

public static Version getVersion(boolean inContainer) {
return inContainer ? InContainer.mVersion.version : Locally.mVersion.version;
Expand All @@ -75,8 +76,8 @@ public static int jdkUpdate(boolean inContainer) {
*/
private static final class MVersion {
private static final Logger LOGGER = Logger.getLogger(MVersion.class.getName());
private static final Pattern VERSION_PATTERN =
Pattern.compile("(?:GraalVM|native-image)(?: Version)? ([^ ]*).*Java Version ([\\d]+)\\.([\\d]+)\\.([\\d]+).*");
private static final Pattern VERSION_PATTERN = Pattern.compile(
"(?:GraalVM|native-image)(?: Version)? (?<version>[^ ]*).*Java Version (?<jfeature>[\\d]+)\\.(?<jinterim>[\\d]+)\\.(?<jupdate>[\\d]+).*");

private final Version version;
private final boolean jdkUsesSysLibs;
Expand All @@ -98,7 +99,8 @@ public MVersion(boolean inContainer) {
final String[] lines = out.split(System.lineSeparator());
lastLine = lines[lines.length - 1].trim();
} else {
final List<String> cmd = getRunCommand("native-image", "--version");
final String TEST_TESTSUITE_ABSOLUTE_PATH = System.getProperty("FAKE_NATIVE_IMAGE_DIR", "");
final List<String> cmd = getRunCommand(TEST_TESTSUITE_ABSOLUTE_PATH + "native-image", "--version");
LOGGER.info("Running command " + cmd + " to determine Mandrel version used.");
try {
lastLine = Commands.runCommand(cmd).trim();
Expand All @@ -124,10 +126,17 @@ public MVersion(boolean inContainer) {
"Output: '" + lastLine + "'");
}
}
version = versionParse(m.group(1));
jdkFeature = Integer.parseInt(m.group(2));
jdkInterim = Integer.parseInt(m.group(3));
jdkUpdate = Integer.parseInt(m.group(4));
version = versionParse(m.group("version"));
final String jFeature = m.group("jfeature");
final String jInterim = m.group("jinterim");
final String jUpdate = m.group("jupdate");
jdkFeature = jFeature == null ? UNDEFINED : Integer.parseInt(jFeature);
jdkInterim = jInterim == null ? UNDEFINED : Integer.parseInt(jInterim);
jdkUpdate = jUpdate == null ? UNDEFINED : Integer.parseInt(jUpdate);
if (jdkFeature == UNDEFINED) {
LOGGER.warn("Failed to correctly parse Java feature (major) version from native-image version command output. " +
"JDK version constraints in tests won't work reliably.");
}
LOGGER.infof("The test suite runs with Mandrel version %s %s, JDK %d.%d.%d.",
version.toString(), inContainer ? "in container" : " installed locally on PATH", jdkFeature, jdkInterim, jdkUpdate);
}
Expand All @@ -149,4 +158,31 @@ private static class Locally {
private static final MVersion mVersion = new MVersion(false);
}

public static int[] featureInterimUpdate(Pattern pattern, String version, int defaultValue) {
final Matcher m = pattern.matcher(version);
if (!m.matches()) {
return new int[]{defaultValue, defaultValue, defaultValue};
}
final String jFeature = m.group("jfeature");
final String jInterim = m.group("jinterim");
final String jUpdate = m.group("jupdate");
return new int[]{
jFeature == null ? defaultValue : Integer.parseInt(jFeature),
jInterim == null ? defaultValue : Integer.parseInt(jInterim),
jUpdate == null ? defaultValue : Integer.parseInt(jUpdate)
};
}

public static int compareJDKVersion(int[] a, int[] b) {
if (a.length != 3 || b.length != 3) {
throw new IllegalArgumentException("3 version elements expected: feature, interim, update");
}
for (int i = 0; i < 3; i++) {
int compare = Integer.compare(a[i], b[i]);
if (compare != 0) {
return compare;
}
}
return 0;
}
}
Loading

0 comments on commit 98791f5

Please sign in to comment.