From 50b4a03fe059b0e16fabd5917fe12d0923f106a0 Mon Sep 17 00:00:00 2001 From: Devin Smith Date: Tue, 24 Oct 2023 09:29:23 -0700 Subject: [PATCH] Update nightly testing to include Java 21 (#4702) This bumps our nightly testing from Java versions [11, 17, 18] to [11, 17, 21], with Java 21 being the latest LTS. Our posture going forward should probably be to try and maintain our LTS set + latest release. Arrow 13 is needed for Java 21 support, https://arrow.apache.org/release/13.0.0.html, apache/arrow#35053. The TestOpenAddressedCanonicalizationCache was updated; otherwise, it consistently failed in Java 21 with a reference to the "0.0" string not becoming dead. I don't suspect there is a larger issue at play here; probably some internization where the JVM itself keeps "0.0" alive. Co-authored-by: Ryan Caudy --- .github/workflows/nightly-check-ci.yml | 8 ++--- ...estOpenAddressedCanonicalizationCache.java | 31 +++++++++++++------ .../configuration/TestConfiguration.java | 6 ++-- buildSrc/src/main/groovy/Classpaths.groovy | 2 +- 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/.github/workflows/nightly-check-ci.yml b/.github/workflows/nightly-check-ci.yml index b8402c0a409..5f501789109 100644 --- a/.github/workflows/nightly-check-ci.yml +++ b/.github/workflows/nightly-check-ci.yml @@ -15,7 +15,7 @@ jobs: fail-fast: false matrix: gradle-task: ['check', 'testSerial', 'testParallel', 'testOutOfBand'] - test-jvm-version: ['11', '17', '18'] + test-jvm-version: ['11', '17', '21'] if: ${{ github.repository_owner == 'deephaven' || github.event_name != 'schedule' }} runs-on: ubuntu-22.04 concurrency: @@ -41,12 +41,12 @@ jobs: distribution: 'temurin' java-version: '17' - - name: Setup JDK 18 - id: setup-java-18 + - name: Setup JDK 21 + id: setup-java-21 uses: actions/setup-java@v3 with: distribution: 'temurin' - java-version: '18' + java-version: '21' - name: Set JAVA_HOME run: echo "JAVA_HOME=${{ steps.setup-java-11.outputs.path }}" >> $GITHUB_ENV diff --git a/Base/src/test/java/io/deephaven/base/cache/TestOpenAddressedCanonicalizationCache.java b/Base/src/test/java/io/deephaven/base/cache/TestOpenAddressedCanonicalizationCache.java index 44ed9fef61c..995b87bceb2 100644 --- a/Base/src/test/java/io/deephaven/base/cache/TestOpenAddressedCanonicalizationCache.java +++ b/Base/src/test/java/io/deephaven/base/cache/TestOpenAddressedCanonicalizationCache.java @@ -3,14 +3,20 @@ */ package io.deephaven.base.cache; -import junit.framework.TestCase; import org.jetbrains.annotations.NotNull; import org.junit.Test; -@SuppressWarnings({"JUnit4AnnotatedMethodInJUnit3TestCase", "UnnecessaryBoxing"}) -public class TestOpenAddressedCanonicalizationCache extends TestCase { +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertNotSame; +import static junit.framework.TestCase.assertSame; +import static junit.framework.TestCase.assertTrue; - @Test +@SuppressWarnings({"UnnecessaryBoxing"}) +public class TestOpenAddressedCanonicalizationCache { + + private static final int MAX_SPIN_CLEANUP_COUNT = 100_000_000; + + @Test(timeout = 10_000) public void testDefaultAdapter() { final OpenAddressedCanonicalizationCache SUT = new OpenAddressedCanonicalizationCache(1, 0.9f); @@ -69,11 +75,12 @@ public void testDefaultAdapter() { assertTrue(3 * cachedIntegers.length / 2 <= SUT.getOccupiedSlots()); assertTrue(3 * cachedIntegers.length >= SUT.getOccupiedSlots()); System.gc(); - while (SUT.getOccupiedSlots() != 3 * cachedIntegers.length / 2) { + for (int i = 0; i < MAX_SPIN_CLEANUP_COUNT && SUT.getOccupiedSlots() != 3 * cachedIntegers.length / 2; ++i) { assertSame(cachedIntegers[0], SUT.getCachedItem(cachedIntegers[0])); // Force cleanup + Thread.onSpinWait(); } - assertEquals(savedOccupancyThreshold, SUT.getOccupancyThreshold()); assertEquals(3 * cachedIntegers.length / 2, SUT.getOccupiedSlots()); + assertEquals(savedOccupancyThreshold, SUT.getOccupancyThreshold()); for (int ii = 0; ii < cachedIntegers.length; ++ii) { if ((ii & 1) == 1) { @@ -138,11 +145,14 @@ public int hashCode(@NotNull Object inputItem) { @Override public String makeCacheableItem(@NotNull Object inputItem) { - return inputItem.toString(); + // Explicitly make our own copy of the input.toString(), so we can be sure there are no uncontrolled + // referrers to cached items. + // noinspection StringOperationCanBeSimplified + return new String(inputItem.toString()); } }; - @Test + @Test(timeout = 10_000) public void testSpecialAdapters() { final OpenAddressedCanonicalizationCache SUT = new OpenAddressedCanonicalizationCache(1, 0.9f); @@ -183,11 +193,12 @@ public void testSpecialAdapters() { assertTrue(cachedStrings.length / 2 <= SUT.getOccupiedSlots()); assertTrue(cachedStrings.length >= SUT.getOccupiedSlots()); System.gc(); - while (SUT.getOccupiedSlots() != cachedStrings.length / 2) { + for (int i = 0; i < MAX_SPIN_CLEANUP_COUNT && SUT.getOccupiedSlots() != cachedStrings.length / 2; ++i) { assertSame(cachedStrings[0], SUT.getCachedItem(cachedStrings[0])); // Force cleanup + Thread.onSpinWait(); } - assertEquals(savedOccupancyThreshold, SUT.getOccupancyThreshold()); assertEquals(cachedStrings.length / 2, SUT.getOccupiedSlots()); + assertEquals(savedOccupancyThreshold, SUT.getOccupancyThreshold()); for (int ii = 0; ii < cachedStrings.length; ii += 2) { final String intString = SUT.getCachedItem(ii, OSA); diff --git a/Configuration/src/test/java/io/deephaven/configuration/TestConfiguration.java b/Configuration/src/test/java/io/deephaven/configuration/TestConfiguration.java index 596b7bae4dd..c408a19dd0e 100644 --- a/Configuration/src/test/java/io/deephaven/configuration/TestConfiguration.java +++ b/Configuration/src/test/java/io/deephaven/configuration/TestConfiguration.java @@ -447,13 +447,13 @@ public void testShowHistory() { "java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n" + "java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)\n", history.get(0).fileName); - } else if ("18".equals(javaVersion)) { + } else if ("21".equals(javaVersion)) { assertEquals( ": io.deephaven.configuration.TestConfiguration.testShowHistory(TestConfiguration.java:428)\n" + - "java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)\n" + "java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)\n" + - "java.base/java.lang.reflect.Method.invoke(Method.java:577)\n", + "java.base/java.lang.reflect.Method.invoke(Method.java:580)\n", history.get(0).fileName); } else { fail("Must add specific test for java version " + javaVersion); diff --git a/buildSrc/src/main/groovy/Classpaths.groovy b/buildSrc/src/main/groovy/Classpaths.groovy index ac329fb3c8c..5cb09e1d7ca 100644 --- a/buildSrc/src/main/groovy/Classpaths.groovy +++ b/buildSrc/src/main/groovy/Classpaths.groovy @@ -46,7 +46,7 @@ class Classpaths { static final String COMMONS_GROUP = 'org.apache.commons' static final String ARROW_GROUP = 'org.apache.arrow' - static final String ARROW_VERSION = '12.0.1' + static final String ARROW_VERSION = '13.0.0' static final String SLF4J_GROUP = 'org.slf4j' static final String SLF4J_VERSION = '2.0.6'