diff --git a/.github/unsafe/armeria-remove-JCTools.patch b/.github/unsafe/armeria-remove-JCTools.patch new file mode 100644 index 00000000000..d8af9e6ee2f --- /dev/null +++ b/.github/unsafe/armeria-remove-JCTools.patch @@ -0,0 +1,92 @@ +From f371066409daaf55739eb60e1ef0d9f42b21ac2a Mon Sep 17 00:00:00 2001 +From: Trask Stalnaker +Date: Sat, 20 Sep 2025 15:36:51 -0700 +Subject: [PATCH] Remove JCTools + +--- + .../java/com/linecorp/armeria/common/ExceptionSampler.java | 5 ++--- + .../linecorp/armeria/common/stream/DefaultStreamMessage.java | 4 ++-- + core/src/main/java/com/linecorp/armeria/server/Server.java | 4 ++-- + 3 files changed, 6 insertions(+), 7 deletions(-) + +diff --git a/core/src/main/java/com/linecorp/armeria/common/ExceptionSampler.java b/core/src/main/java/com/linecorp/armeria/common/ExceptionSampler.java +index 87afd2074..b5c1c2470 100644 +--- a/core/src/main/java/com/linecorp/armeria/common/ExceptionSampler.java ++++ b/core/src/main/java/com/linecorp/armeria/common/ExceptionSampler.java +@@ -18,10 +18,9 @@ package com.linecorp.armeria.common; + import static java.util.Objects.requireNonNull; + + import java.util.Map; ++import java.util.concurrent.ConcurrentHashMap; + import java.util.function.Function; + +-import org.jctools.maps.NonBlockingHashMap; +- + import com.google.common.base.MoreObjects; + + import com.linecorp.armeria.common.util.Sampler; +@@ -29,7 +28,7 @@ import com.linecorp.armeria.common.util.Sampler; + final class ExceptionSampler implements Sampler> { + + private final Map, Sampler>> samplers = +- new NonBlockingHashMap<>(); ++ new ConcurrentHashMap<>(); + private final Function, + ? extends Sampler>> samplerFactory; + private final String spec; +diff --git a/core/src/main/java/com/linecorp/armeria/common/stream/DefaultStreamMessage.java b/core/src/main/java/com/linecorp/armeria/common/stream/DefaultStreamMessage.java +index e9328f03e..12173e999 100644 +--- a/core/src/main/java/com/linecorp/armeria/common/stream/DefaultStreamMessage.java ++++ b/core/src/main/java/com/linecorp/armeria/common/stream/DefaultStreamMessage.java +@@ -22,9 +22,9 @@ import static java.util.Objects.requireNonNull; + + import java.util.Queue; + import java.util.concurrent.CompletableFuture; ++import java.util.concurrent.ConcurrentLinkedQueue; + import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; + +-import org.jctools.queues.MpscChunkedArrayQueue; + import org.reactivestreams.Subscriber; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; +@@ -109,7 +109,7 @@ public class DefaultStreamMessage extends AbstractStreamWriter { + */ + @Deprecated + public DefaultStreamMessage() { +- queue = new MpscChunkedArrayQueue<>(INITIAL_CAPACITY, 1 << 30); ++ queue = new ConcurrentLinkedQueue<>(); + } + + @Override +diff --git a/core/src/main/java/com/linecorp/armeria/server/Server.java b/core/src/main/java/com/linecorp/armeria/server/Server.java +index 6b8b0b557..0c3eed942 100644 +--- a/core/src/main/java/com/linecorp/armeria/server/Server.java ++++ b/core/src/main/java/com/linecorp/armeria/server/Server.java +@@ -37,6 +37,7 @@ import java.util.Set; + import java.util.concurrent.CompletableFuture; + import java.util.concurrent.CompletionException; + import java.util.concurrent.CompletionStage; ++import java.util.concurrent.ConcurrentHashMap; + import java.util.concurrent.ExecutionException; + import java.util.concurrent.Executor; + import java.util.concurrent.ExecutorService; +@@ -51,7 +52,6 @@ import java.util.stream.Collectors; + + import javax.net.ssl.SSLSession; + +-import org.jctools.maps.NonBlockingHashSet; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; + +@@ -119,7 +119,7 @@ public final class Server implements ListenableAsyncCloseable { + + private final UpdatableServerConfig config; + private final StartStopSupport startStop; +- private final Set serverChannels = new NonBlockingHashSet<>(); ++ private final Set serverChannels = ConcurrentHashMap.newKeySet(); + private final ReentrantLock lock = new ReentrantShortLock(); + @GuardedBy("lock") + private final Map activePorts = new LinkedHashMap<>(); +-- +2.51.0.windows.1 + diff --git a/.github/unsafe/armeria-update-Caffeine.patch b/.github/unsafe/armeria-update-Caffeine.patch new file mode 100644 index 00000000000..534d062bd04 --- /dev/null +++ b/.github/unsafe/armeria-update-Caffeine.patch @@ -0,0 +1,117 @@ +From d6276724f7f432af4693e9d786ecfcaddb73e505 Mon Sep 17 00:00:00 2001 +From: Trask Stalnaker +Date: Sat, 20 Sep 2025 21:48:43 -0700 +Subject: [PATCH] Update Caffeine + +--- + .../src/main/java/com/linecorp/armeria/common/Flags.java | 2 +- + .../armeria/internal/common/util/CertificateUtil.java | 9 ++++++--- + .../linecorp/armeria/server/file/FileServiceConfig.java | 2 +- + dependencies.toml | 5 ++--- + gradle.properties | 4 ++-- + 5 files changed, 12 insertions(+), 10 deletions(-) + +diff --git a/core/src/main/java/com/linecorp/armeria/common/Flags.java b/core/src/main/java/com/linecorp/armeria/common/Flags.java +index 57671a686..e1dd6eb3b 100644 +--- a/core/src/main/java/com/linecorp/armeria/common/Flags.java ++++ b/core/src/main/java/com/linecorp/armeria/common/Flags.java +@@ -1722,7 +1722,7 @@ public final class Flags { + if ("off".equals(value)) { + return allowOff; + } +- CaffeineSpec.parse(value); ++ var unused = CaffeineSpec.parse(value); + return true; + } catch (Exception e) { + return false; +diff --git a/core/src/main/java/com/linecorp/armeria/internal/common/util/CertificateUtil.java b/core/src/main/java/com/linecorp/armeria/internal/common/util/CertificateUtil.java +index a343428a3..48698e3ea 100644 +--- a/core/src/main/java/com/linecorp/armeria/internal/common/util/CertificateUtil.java ++++ b/core/src/main/java/com/linecorp/armeria/internal/common/util/CertificateUtil.java +@@ -57,6 +57,8 @@ public final class CertificateUtil { + + private static final Logger logger = LoggerFactory.getLogger(CertificateUtil.class); + ++ private static final String NO_HOSTNAME_FOUND = ""; ++ + private static final LoadingCache hostnameCache = + Caffeine.newBuilder() + .weakKeys() +@@ -73,11 +75,11 @@ public final class CertificateUtil { + + logger.warn("No common name or subject alternative name found " + + "in certificate: {}", cert); +- return null; ++ return NO_HOSTNAME_FOUND; + } catch (Exception e) { + logger.warn("Failed to get the common name or subject alternative name name " + + "from a certificate: {}", cert, e); +- return null; ++ return NO_HOSTNAME_FOUND; + } + }); + +@@ -136,7 +138,8 @@ public final class CertificateUtil { + if (!(certificate instanceof X509Certificate)) { + return null; + } +- return hostnameCache.get((X509Certificate) certificate); ++ final String hostname = hostnameCache.get((X509Certificate) certificate); ++ return NO_HOSTNAME_FOUND.equals(hostname) ? null : hostname; + } + + public static List toX509Certificates(File file) throws CertificateException { +diff --git a/core/src/main/java/com/linecorp/armeria/server/file/FileServiceConfig.java b/core/src/main/java/com/linecorp/armeria/server/file/FileServiceConfig.java +index 8766acd95..b6b8a1b62 100644 +--- a/core/src/main/java/com/linecorp/armeria/server/file/FileServiceConfig.java ++++ b/core/src/main/java/com/linecorp/armeria/server/file/FileServiceConfig.java +@@ -72,7 +72,7 @@ public final class FileServiceConfig { + return null; + } + try { +- CaffeineSpec.parse(entryCacheSpec); ++ var unused = CaffeineSpec.parse(entryCacheSpec); + } catch (Exception e) { + throw new IllegalArgumentException("invalid cache spec: " + entryCacheSpec, e); + } +diff --git a/dependencies.toml b/dependencies.toml +index 22c366f47..bfd54bcce 100644 +--- a/dependencies.toml ++++ b/dependencies.toml +@@ -15,8 +15,7 @@ brave6 = "6.3.0" + brotli4j = "1.18.0" + # Don"t upgrade bucket4j to 7.6.1 or 8.x that requires Java 11. The module name also has been changed to "com.bucket4j" + bucket4j = "7.6.0" +-# Don"t upgrade Caffeine to 3.x that requires Java 11. +-caffeine = "2.9.3" ++caffeine = "3.2.2" + cglib = "3.3.0" + checkerframework = "2.5.6" + checkstyle = "10.3.2" +@@ -325,7 +324,7 @@ javadocs = "https://javadoc.io/doc/com.github.vladimir-bukhtoyarov/bucket4j-core + module = "com.github.ben-manes.caffeine:caffeine" + version.ref = "caffeine" + exclusions = "com.google.errorprone:error_prone_annotations" +-javadocs = "https://www.javadoc.io/doc/com.github.ben-manes.caffeine/caffeine/2.9.3/" ++javadocs = "https://www.javadoc.io/doc/com.github.ben-manes.caffeine/caffeine/3.2.2/" + relocations = { from = "com.github.benmanes.caffeine", to = "com.linecorp.armeria.internal.shaded.caffeine" } + + [libraries.cglib] +diff --git a/gradle.properties b/gradle.properties +index de5b05013..5ab06b436 100644 +--- a/gradle.properties ++++ b/gradle.properties +@@ -12,8 +12,8 @@ licenseUrl=https://www.apache.org/license/LICENSE-2.0.txt + scmUrl=https://github.com/line/armeria + scmConnection=scm:git:https://github.com/line/armeria.git + scmDeveloperConnection=scm:git:ssh://git@github.com/line/armeria.git +-javaSourceCompatibility=1.8 +-javaTargetCompatibility=1.8 ++javaSourceCompatibility=11 ++javaTargetCompatibility=11 + publishUrlForRelease=https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/ + publishUrlForSnapshot=https://central.sonatype.com/repository/maven-snapshots/ + publishUsernameProperty=ossrhUsername +-- +2.51.0.windows.1 + diff --git a/.github/unsafe/build-custom-armeria.sh b/.github/unsafe/build-custom-armeria.sh new file mode 100755 index 00000000000..18d9a1f49f8 --- /dev/null +++ b/.github/unsafe/build-custom-armeria.sh @@ -0,0 +1,27 @@ +#!/bin/bash +set -e + +VERSION="1.33.3" +CURR_DIR="$(pwd)" + +cd "$(mktemp -d)" + +# Clone Armeria repository +git clone --depth 1 --branch "armeria-${VERSION}" https://github.com/line/armeria.git + +cd armeria + +# Apply patch to remove Unsafe usage +git apply "${CURR_DIR}/.github/unsafe/armeria-remove-JCTools.patch" +git apply "${CURR_DIR}/.github/unsafe/armeria-update-Caffeine.patch" + +# Build the core module (shaded JAR includes all dependencies) +./gradlew :core:shadedJar -x javadoc -x :docs-client:nodeSetup -x :docs-client:npmSetup -x :docs-client:npmInstall -x :docs-client:eslint -x :docs-client:lint -x :docs-client:buildWeb -x :docs-client:copyWeb + +# Download the original POM file +curl -sL -o "armeria-${VERSION}.pom" "https://repo1.maven.org/maven2/com/linecorp/armeria/armeria/${VERSION}/armeria-${VERSION}.pom" + +# Install core JAR to Maven local repository with POM +mvn install:install-file -q \ + -Dfile="core/build/libs/armeria-untrimmed-${VERSION}.jar" \ + -DpomFile="armeria-${VERSION}.pom" diff --git a/.github/unsafe/build-custom-protobuf.sh b/.github/unsafe/build-custom-protobuf.sh new file mode 100755 index 00000000000..35a41316baa --- /dev/null +++ b/.github/unsafe/build-custom-protobuf.sh @@ -0,0 +1,35 @@ +#!/bin/bash +set -e + +VERSION="4.32.1" + +cd "$(mktemp -d)" + +# Download original artifact and extract +curl -sL -o "protobuf-java-${VERSION}.jar" "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/${VERSION}/protobuf-java-${VERSION}.jar" + +# Extract JAR +mkdir classes +cd classes +jar -xf "../protobuf-java-${VERSION}.jar" +cd .. + +# Clone protobuf repository +git clone --depth 1 --branch "v32.1" https://github.com/protocolbuffers/protobuf.git + +# Apply patch to remove Unsafe usage +sed -i 's/private static final sun\.misc\.Unsafe UNSAFE = getUnsafe();/private static final sun.misc.Unsafe UNSAFE = null;/' protobuf/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java + +# Compile modified classes +javac -cp protobuf-java-${VERSION}.jar -d classes protobuf/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java + +# Create new JAR with modified classes +jar -cf "protobuf-java-${VERSION}.jar" -C classes . + +# Download the original POM file +curl -sL -o "protobuf-java-${VERSION}.pom" "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/${VERSION}/protobuf-java-${VERSION}.pom" + +# Install to Maven local repository with POM +mvn install:install-file -q \ + -Dfile="protobuf-java-${VERSION}.jar" \ + -DpomFile="protobuf-java-${VERSION}.pom" diff --git a/.github/unsafe/prioritize-maven-local.sh b/.github/unsafe/prioritize-maven-local.sh new file mode 100755 index 00000000000..d50ed6ffe61 --- /dev/null +++ b/.github/unsafe/prioritize-maven-local.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e + +# Move mavenLocal() before mavenCentral() in the repositories block +sed -i '/repositories {/,/}/ { + /mavenCentral()/d + /mavenLocal()/d + /repositories {/a\ mavenLocal() + /repositories {/a\ mavenCentral() +}' "settings.gradle.kts" diff --git a/.github/unsafe/update-lmax-disruptor.sh b/.github/unsafe/update-lmax-disruptor.sh new file mode 100755 index 00000000000..23341b3105d --- /dev/null +++ b/.github/unsafe/update-lmax-disruptor.sh @@ -0,0 +1,30 @@ +#!/bin/bash +set -e + +# Add Java 11 compile target and disruptor version update to opencensus-shim build file +cat >> opencensus-shim/build.gradle.kts << 'EOF' + +tasks.withType().configureEach { + options.release.set(11) +} + +configurations.all { + resolutionStrategy.force("com.lmax:disruptor:4.0.0") +} +EOF + +# Add targeted disruptor fix to exporters/otlp/all for JdkHttpSender tests +if ! grep -q "resolutionStrategy.force.*disruptor.*4.0.0" exporters/otlp/all/build.gradle.kts; then + # Replace the existing afterEvaluate block with the complete version + sed -i '/afterEvaluate {/,/^}$/c\ +afterEvaluate {\ + tasks.named("compileTestJdkHttpSenderJava") {\ + options.release.set(11)\ + }\ +\ + // Force disruptor 4.0.0 for JdkHttpSender tests to prevent conflicts with mockserver\ + configurations.named("testJdkHttpSenderRuntimeClasspath") {\ + resolutionStrategy.force("com.lmax:disruptor:4.0.0")\ + }\ +}' exporters/otlp/all/build.gradle.kts +fi diff --git a/.github/workflows/unsafe.yml b/.github/workflows/unsafe.yml new file mode 100644 index 00000000000..9596700a5ba --- /dev/null +++ b/.github/workflows/unsafe.yml @@ -0,0 +1,60 @@ +name: Unsafe disabled test + +on: + push: + branches: + - main + - release/* + pull_request: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + unsafe-disabled-test: + name: Unsafe disabled test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - id: setup-java-test + name: Set up Java 24 for tests + uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 + with: + distribution: temurin + java-version: 24 + + - id: setup-java + name: Set up Java for build + uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 + with: + distribution: temurin + java-version: 17 + + - name: Set up gradle + uses: gradle/actions/setup-gradle@ed408507eac070d1f99cc633dbcf757c94c7933a # v4.4.3 + + - name: Build custom protobuf-java that doesn't require Unsafe + run: ./.github/unsafe/build-custom-protobuf.sh + + - name: Build custom armeria that doesn't require Unsafe + run: ./.github/unsafe/build-custom-armeria.sh + + - name: Prioritize Maven local repository to pick up custom builds + run: ./.github/unsafe/prioritize-maven-local.sh + + - name: Update to LMAX Disruptor version that doesn't require Unsafe + run: ./.github/unsafe/update-lmax-disruptor.sh + + - name: Build and test + run: > + ./gradlew build + -PdisableUnsafe=true + -PtestJavaVersion=24 + "-Porg.gradle.java.installations.paths=${{ steps.setup-java-test.outputs.path }}" + "-Porg.gradle.java.installations.auto-download=false" diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 18ed4de9779..d0d3b1316f8 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -70,6 +70,7 @@ dependencyCheck { } val testJavaVersion = gradle.startParameter.projectProperties.get("testJavaVersion")?.let(JavaVersion::toVersion) +val disableUnsafe = gradle.startParameter.projectProperties.get("disableUnsafe")?.toBoolean() ?: false tasks { withType().configureEach { @@ -114,6 +115,10 @@ tasks { ) } + if (disableUnsafe) { + jvmArgs("--sun-misc-unsafe-memory-access=deny") + } + val defaultMaxRetries = if (System.getenv().containsKey("CI")) 2 else 0 val maxTestRetries = gradle.startParameter.projectProperties["maxTestRetries"]?.toInt() ?: defaultMaxRetries diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 42065705b5d..dacc69aecdf 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -92,7 +92,7 @@ val DEPENDENCIES = listOf( "org.codehaus.mojo:animal-sniffer-annotations:1.24", "org.jctools:jctools-core:4.0.5", "org.junit-pioneer:junit-pioneer:1.9.1", - "org.mock-server:mockserver-netty:5.15.0:shaded", + "com.github.tomakehurst:wiremock-jre8:2.35.2", "org.skyscreamer:jsonassert:1.5.3", "com.android.tools:desugar_jdk_libs:2.1.5", ) diff --git a/exporters/otlp/testing-internal/build.gradle.kts b/exporters/otlp/testing-internal/build.gradle.kts index f4459686389..0112dc1220e 100644 --- a/exporters/otlp/testing-internal/build.gradle.kts +++ b/exporters/otlp/testing-internal/build.gradle.kts @@ -34,7 +34,7 @@ dependencies { implementation("com.linecorp.armeria:armeria-junit5") implementation("io.github.netmikey.logunit:logunit-jul") implementation("org.assertj:assertj-core") - implementation("org.mock-server:mockserver-netty") + implementation("com.github.tomakehurst:wiremock-jre8") } // Skip OWASP dependencyCheck task on test module diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index 4714ea5a542..0e0e81ce36b 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -13,6 +13,8 @@ import static org.junit.jupiter.api.Named.named; import static org.junit.jupiter.params.provider.Arguments.arguments; +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.client.WireMock; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; import com.linecorp.armeria.common.HttpRequest; @@ -101,7 +103,6 @@ import org.junit.jupiter.params.provider.ArgumentsSource; import org.junit.jupiter.params.provider.ValueSource; import org.junit.jupiter.params.support.ParameterDeclarations; -import org.mockserver.integration.ClientAndServer; import org.slf4j.event.Level; import org.slf4j.event.LoggingEvent; @@ -648,30 +649,35 @@ void nonRetryableError(int code) { @Test void proxy() { - // configure mockserver to proxy to the local OTLP server - InetSocketAddress serverSocketAddress = server.httpSocketAddress(); - try (ClientAndServer clientAndServer = - ClientAndServer.startClientAndServer( - serverSocketAddress.getHostName(), serverSocketAddress.getPort()); - TelemetryExporter exporter = - exporterBuilder() - // Configure exporter with server endpoint, and proxy options to route through - // mockserver proxy - .setEndpoint(server.httpUri() + path) - .setProxyOptions( - ProxyOptions.create( - InetSocketAddress.createUnresolved("localhost", clientAndServer.getPort()))) - .build()) { + // configure wiremock to proxy to the local OTLP server + WireMockServer wireMockServer = new WireMockServer(0); + wireMockServer.start(); + + // Configure WireMock to proxy all requests to the actual server + wireMockServer.stubFor( + WireMock.any(WireMock.anyUrl()) + .willReturn(WireMock.aResponse().proxiedFrom(server.httpUri().toString()))); + + try (TelemetryExporter exporter = + exporterBuilder() + // Configure exporter with server endpoint, and proxy options to route through + // wiremock proxy + .setEndpoint(server.httpUri() + path) + .setProxyOptions( + ProxyOptions.create( + InetSocketAddress.createUnresolved("localhost", wireMockServer.port()))) + .build()) { List telemetry = Collections.singletonList(generateFakeTelemetry()); assertThat(exporter.export(telemetry).join(10, TimeUnit.SECONDS).isSuccess()).isTrue(); - // assert that mock server received request - assertThat(clientAndServer.retrieveRecordedRequests(new org.mockserver.model.HttpRequest())) - .hasSize(1); + // assert that wiremock server received request + wireMockServer.verify(1, WireMock.anyRequestedFor(WireMock.anyUrl())); // assert that server received telemetry from proxy, and is as expected List expectedResourceTelemetry = toProto(telemetry); assertThat(exportedResourceTelemetry).containsExactlyElementsOf(expectedResourceTelemetry); + } finally { + wireMockServer.stop(); } } diff --git a/sdk/trace-shaded-deps/src/test/java/io/opentelemetry/sdk/trace/internal/JcToolsTest.java b/sdk/trace-shaded-deps/src/test/java/io/opentelemetry/sdk/trace/internal/JcToolsTest.java index edb0168d2ce..84d4afd6ab7 100644 --- a/sdk/trace-shaded-deps/src/test/java/io/opentelemetry/sdk/trace/internal/JcToolsTest.java +++ b/sdk/trace-shaded-deps/src/test/java/io/opentelemetry/sdk/trace/internal/JcToolsTest.java @@ -43,7 +43,7 @@ void drain_ArrayBlockingQueue() { void drain_MessagePassingQueue() { // Arrange batch.add("Test3"); - Queue queue = new MpscArrayQueue<>(10); + Queue queue = JcTools.newFixedSizeQueue(10); queue.add("Test1"); queue.add("Test2"); @@ -58,7 +58,7 @@ void drain_MessagePassingQueue() { @Test void drain_MaxBatch() { // Arrange - Queue queue = new MpscArrayQueue<>(10); + Queue queue = JcTools.newFixedSizeQueue(10); queue.add("Test1"); queue.add("Test2"); @@ -79,7 +79,10 @@ void newFixedSize_MpscQueue() { Queue objects = JcTools.newFixedSizeQueue(capacity); // Assert - assertThat(objects).isInstanceOf(MpscArrayQueue.class); + assertThat(objects) + .satisfiesAnyOf( + queue -> assertThat(queue).isInstanceOf(MpscArrayQueue.class), + queue -> assertThat(queue).isInstanceOf(ArrayBlockingQueue.class)); } @Test @@ -92,7 +95,7 @@ void capacity_MpscQueue() { long queueSize = JcTools.capacity(queue); // Assert - assertThat(queueSize).isGreaterThan(capacity); + assertThat(queueSize).isGreaterThanOrEqualTo(capacity); } @Test