From 940b83c2b93e1c72bfe1f363040df9824b0e482e Mon Sep 17 00:00:00 2001 From: Vladimir Sitnikov Date: Tue, 2 May 2023 12:35:17 +0300 Subject: [PATCH 1/2] test: add IBM Semeru Java distribution to test matrix Semeru uses Open9J JIT, so it might behave differently from the other OpenJDK distributions, so it is assigned a greater weight in the test matrix. The option for testing with "same hashcode" -XX:hashCode=2 is moved to Test task execution only since javac, and kotlinc do not behave well with "same hashcode". --- .github/workflows/gradle.yml | 6 ++- .github/workflows/matrix.js | 42 +++++++++++-------- .github/workflows/matrix_builder.js | 8 +++- build.gradle | 25 ----------- .../groovy/jqwik.common-configuration.gradle | 28 +++++++++++++ 5 files changed, 64 insertions(+), 45 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index bc5b07a66..d6d4cd0d2 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -54,17 +54,19 @@ jobs: with: script: | console.log('The following command might help reproducing CI results, use Java ${{ matrix.java_version }}') - console.log('TZ="${{ matrix.tz }}" _JAVA_OPTIONS="${{ matrix.testExtraJvmArgs }}" ./gradlew check ${{ matrix.extraGradleArgs }}') + console.log('TZ="${{ matrix.tz }}" _JAVA_OPTIONS="${{ matrix.extraJvmArgs }}" ./gradlew check ${{ matrix.extraGradleArgs }} -PtestExtraJvmArgs="${{ matrix.testExtraJvmArgs }}"') - uses: burrunan/gradle-cache-action@v1 # See https://github.com/burrunan/gradle-cache-action name: Build and Test env: - _JAVA_OPTIONS: ${{ matrix.testExtraJvmArgs }} + _JAVA_OPTIONS: ${{ matrix.extraJvmArgs }} with: # It allows different cache contents for different JDKs job-id: java${{ matrix.java_version }} arguments: check -DshowStandardStreams=true ${{ matrix.extraGradleArgs }} + properties: | + testExtraJvmArgs=${{ matrix.testExtraJvmArgs }} # - name: Publish Test Report # uses: scacap/action-surefire-report@v1 diff --git a/.github/workflows/matrix.js b/.github/workflows/matrix.js index 548bab6bd..d5248b506 100644 --- a/.github/workflows/matrix.js +++ b/.github/workflows/matrix.js @@ -20,18 +20,16 @@ const matrix = new MatrixBuilder(); matrix.addAxis({ name: 'java_distribution', values: [ - 'corretto', - 'liberica', - 'microsoft', - 'oracle', - 'temurin', - 'zulu', + {value: 'corretto', weight: 1}, + {value: 'liberica', weight: 1}, + {value: 'microsoft', weight: 1}, + {value: 'oracle', weight: 1}, + {value: 'semeru', weight: 4}, + {value: 'temurin', weight: 1}, + {value: 'zulu', weight: 1}, ] }); -// TODO: support different JITs (see https://github.com/actions/setup-java/issues/279) -matrix.addAxis({name: 'jit', title: '', values: ['hotspot']}); - // See the supported versions at https://foojay.io/almanac/java-17/ matrix.addAxis({ name: 'java_version', @@ -92,12 +90,16 @@ matrix.setNamePattern([ 'tz', 'locale', ]); +// Semeru uses OpenJ9 jit which has no option for making hash codes the same +// See https://github.com/eclipse-openj9/openj9/issues/17309 +matrix.exclude({java_distribution: {value: 'semeru'}, hash: {value: 'same'}}); +matrix.exclude({java_distribution: {value: 'semeru'}, java_version: '19'}); // Microsoft Java has no distribution for 8, 18, 19 -matrix.exclude({java_distribution: 'microsoft', java_version: '8'}); -matrix.exclude({java_distribution: 'microsoft', java_version: '18'}); -matrix.exclude({java_distribution: 'microsoft', java_version: '19'}); +matrix.exclude({java_distribution: {value: 'microsoft'}, java_version: '8'}); +matrix.exclude({java_distribution: {value: 'microsoft'}, java_version: '18'}); +matrix.exclude({java_distribution: {value: 'microsoft'}, java_version: '19'}); // Oracle supports 17+ only -matrix.exclude({java_distribution: 'oracle', java_version: ['8', '11', '19']}); +matrix.exclude({java_distribution: {value: 'oracle'}, java_version: ['8', '11', '19']}); // TODO: remove when compileJava with "same hashcode" issues are resolved // See https://bugs.openjdk.org/browse/JDK-8288590 is resolved // See https://github.com/jqwik-team/jqwik/pull/460#issuecomment-1428261036 @@ -133,14 +135,19 @@ include.forEach(v => { }); include.forEach(v => { let jvmArgs = []; - + // Extra JVM arguments passed to test execution + let testJvmArgs = []; if (v.hash.value === 'same') { - jvmArgs.push('-XX:+UnlockExperimentalVMOptions', '-XX:hashCode=2'); + // javac has issues with "same hashcode" option (see https://bugs.openjdk.org/browse/JDK-8288590) + // On the other hand, kotlinc uses "object identity" a lot. It works properly, + // but it becomes slow as HashMap degrades. So we pass "same hashcode" to test executions only. + testJvmArgs.push('-XX:+UnlockExperimentalVMOptions', '-XX:hashCode=2'); } // Pass locale via _JAVA_OPTIONS so all the forked processes inherit it jvmArgs.push(`-Duser.country=${v.locale.country}`); jvmArgs.push(`-Duser.language=${v.locale.language}`); - if (v.jit === 'hotspot' && Math.random() > 0.5) { + v.java_distribution = v.java_distribution.value; + if (v.java_distribution !== 'semeru' && Math.random() > 0.5) { // The following options randomize instruction selection in JIT compiler // so it might reveal missing synchronization in TestNG code v.name += ', stress JIT'; @@ -164,7 +171,8 @@ include.forEach(v => { jvmArgs.push('-XX:+StressCCP'); } } - v.testExtraJvmArgs = jvmArgs.join(' '); + v.extraJvmArgs = jvmArgs.join(' '); + v.testExtraJvmArgs = testJvmArgs.join(' ::: '); delete v.hash; }); diff --git a/.github/workflows/matrix_builder.js b/.github/workflows/matrix_builder.js index dbd00fb0b..fd765117e 100644 --- a/.github/workflows/matrix_builder.js +++ b/.github/workflows/matrix_builder.js @@ -152,7 +152,13 @@ class MatrixBuilder { return title; } const computeTitle = this.axisByName[axisName].title; - return computeTitle ? computeTitle(value) : value; + if (computeTitle) { + return computeTitle(value); + } + if (typeof value === 'object' && value.hasOwnProperty('value')) { + return value.value; + } + return value; }).filter(Boolean).join(", "); this.rows.push(res); return res; diff --git a/build.gradle b/build.gradle index 8530eeb9e..8eaafb378 100644 --- a/build.gradle +++ b/build.gradle @@ -11,28 +11,3 @@ plugins { wrapper { gradleVersion = '8.0.2' } - -allprojects { - tasks.withType(ProcessForkOptions).configureEach { - // Prevent Gradle build cache reuse for different _JAVA_OPTIONS - inputs.property("ENV:_JAVA_OPTIONS", providers.environmentVariable("_JAVA_OPTIONS")).optional(true) - } - - tasks.withType(JavaCompile).configureEach { - // Prevent Gradle build cache reuse for different _JAVA_OPTIONS - inputs.property("ENV:_JAVA_OPTIONS", providers.environmentVariable("_JAVA_OPTIONS")).optional(true) - } - - tasks.withType(Test).configureEach { - def language = System.getProperty("user.language") ?: "TR" - if (language != null) { - systemProperty("user.language", language) - } - def country = System.getProperty("user.country") ?: "tr" - if (country != null) { - systemProperty("user.country", country) - } - // Tests might depend on timezone, so treat it as an input - inputs.property("ENV:TZ", providers.environmentVariable("TZ")).optional(true) - } -} diff --git a/buildSrc/src/main/groovy/jqwik.common-configuration.gradle b/buildSrc/src/main/groovy/jqwik.common-configuration.gradle index aa91949ae..104c990a8 100644 --- a/buildSrc/src/main/groovy/jqwik.common-configuration.gradle +++ b/buildSrc/src/main/groovy/jqwik.common-configuration.gradle @@ -66,6 +66,34 @@ tasks.withType(Javadoc) { options.addStringOption('Xdoclint:none', '-quiet') } +tasks.withType(ProcessForkOptions).configureEach { + // Prevent Gradle build cache reuse for different _JAVA_OPTIONS + inputs.property("ENV:_JAVA_OPTIONS", providers.environmentVariable("_JAVA_OPTIONS")).optional(true) +} + +tasks.withType(JavaCompile).configureEach { + // Prevent Gradle build cache reuse for different _JAVA_OPTIONS + inputs.property("ENV:_JAVA_OPTIONS", providers.environmentVariable("_JAVA_OPTIONS")).optional(true) +} + +tasks.withType(Test).configureEach { + def language = System.getProperty("user.language") ?: "TR" + if (language != null) { + systemProperty("user.language", language) + } + def country = System.getProperty("user.country") ?: "tr" + if (country != null) { + systemProperty("user.country", country) + } + // Tests might depend on timezone, so treat it as an input + inputs.property("ENV:TZ", providers.environmentVariable("TZ")).optional(true) + + def testExtraJvmArgs = project.findProperty("testExtraJvmArgs") + if (testExtraJvmArgs instanceof String && !testExtraJvmArgs.isEmpty()) { + jvmArgs(testExtraJvmArgs.split(" ::: ")) + } +} + // Enable to get more compiler warnings. // tasks.withType(JavaCompile) { // options.compilerArgs << '-Xlint:unchecked' From 259c1e5f514a7d4bb6f2da8b399a8f435c0306f5 Mon Sep 17 00:00:00 2001 From: Vladimir Sitnikov Date: Tue, 2 May 2023 12:39:07 +0300 Subject: [PATCH 2/2] chore: temporary increase CI jobs to 15 to see if matrix produces illegal combinations --- .github/workflows/gradle.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index d6d4cd0d2..2911c67f4 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -23,7 +23,7 @@ jobs: outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} env: - MATRIX_JOBS: 4 + MATRIX_JOBS: 15 steps: - uses: actions/checkout@v3 - id: set-matrix @@ -36,7 +36,7 @@ jobs: needs: matrix_prep strategy: matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}} - # fail-fast: false + fail-fast: false env: TZ: ${{ matrix.tz }} steps: