This is an automated email from the ASF dual-hosted git repository.
rustyrazorblade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cassandra-easy-stress.git
The following commit(s) were added to refs/heads/main by this push:
new 2f2f9bf feat(build): support JDK 21 and 25, migrate build.gradle to
Kotlin DSL
2f2f9bf is described below
commit 2f2f9bfbb78fffa32508cc58afe11b83665632e5
Author: Jon Haddad <[email protected]>
AuthorDate: Fri Aug 14 12:42:19 2026 -0700
feat(build): support JDK 21 and 25, migrate build.gradle to Kotlin DSL
- Target whichever JDK is actually compiling (21 or 25) instead of a fixed
floor; add JDK 25 to the CI test matrix alongside 21 (current + next LTS)
- Default the launch script and Docker image to Generational ZGC,
JDK-version-aware (JDK 23+ removed the explicit flag)
- Upgrade Gradle 8.14.3 -> 9.7.0 (required: Gradle before 9.1.0 can't run
its own daemon on JDK 25) and convert build.gradle to Kotlin DSL
- Upgrade Kotlin 2.2.20 -> 2.4.10 (JDK 25 as an explicit compile target
requires Kotlin 2.3+)
- Bump jib 3.3.0 -> 3.5.4 and kover 0.9.2 -> 0.9.9 for Gradle 9 / Kotlin
2.4 compatibility; bump testcontainers 1.19.8 -> 2.0.5, fixing local
Docker-integration-test connectivity
- Bump mockk, junit-jupiter/junit-platform, and
hadoop-common/hadoop-mapreduce-client-common for JDK 21+ bytecode and JDK 24+
Security Manager removal compatibility
- Fix Gradle 9/10 deprecations in the build script and a real blocker
introduced during the Kotlin DSL conversion (illegal task-container mutation
breaking ./gradlew tasks/testAllVersions)
---
.github/workflows/ci.yml | 24 +-
.github/workflows/gradle-publish-disttar.yml | 4 +-
.github/workflows/publish-release.yml | 4 +-
README.md | 8 +-
bin/cassandra-easy-stress | 13 +-
build.gradle | 297 -----------------------
build.gradle.kts | 348 +++++++++++++++++++++++++++
gradle/libs.versions.toml | 19 +-
gradle/wrapper/gradle-wrapper.jar | Bin 59536 -> 43764 bytes
gradle/wrapper/gradle-wrapper.properties | 4 +-
gradlew | 47 ++--
gradlew.bat | 41 ++--
12 files changed, 448 insertions(+), 361 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 9a18b79..69fb725 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -18,7 +18,7 @@ jobs:
strategy:
matrix:
- java: [17, 21]
+ java: [21, 25]
test-task: ["test40", "test41", "test50"]
fail-fast: false
@@ -44,10 +44,10 @@ jobs:
- name: Checkout code
uses: actions/checkout@v6
- - name: Set up JDK 17
+ - name: Set up JDK 21
uses: actions/setup-java@v5
with:
- java-version: 17
+ java-version: 21
distribution: "temurin"
cache: "gradle"
@@ -62,10 +62,10 @@ jobs:
- name: Checkout code
uses: actions/checkout@v6
- - name: Set up JDK 17
+ - name: Set up JDK 21
uses: actions/setup-java@v5
with:
- java-version: 17
+ java-version: 21
distribution: "temurin"
cache: "gradle"
@@ -80,10 +80,10 @@ jobs:
- name: Checkout code
uses: actions/checkout@v6
- - name: Set up JDK 17
+ - name: Set up JDK 21
uses: actions/setup-java@v5
with:
- java-version: 17
+ java-version: 21
distribution: "temurin"
cache: "gradle"
@@ -99,10 +99,10 @@ jobs:
- name: Checkout code
uses: actions/checkout@v6
- - name: Set up JDK 17
+ - name: Set up JDK 21
uses: actions/setup-java@v5
with:
- java-version: 17
+ java-version: 21
distribution: "temurin"
cache: "gradle"
@@ -122,10 +122,10 @@ jobs:
- name: Checkout code
uses: actions/checkout@v6
- - name: Set up JDK 17
+ - name: Set up JDK 21
uses: actions/setup-java@v5
with:
- java-version: 17
+ java-version: 21
distribution: "temurin"
cache: "gradle"
@@ -225,7 +225,7 @@ jobs:
- **Artifact Size**: ${{ steps.artifact.outputs.artifact_size }}
- **Workflow Run**: ${{ github.server_url }}/${{ github.repository
}}/actions/runs/${{ github.run_id }}
- **Commit**: ${{ github.sha }}
- - **Java Version**: 17 (Temurin)
+ - **Java Version**: 21 (Temurin)
### Usage
diff --git a/.github/workflows/gradle-publish-disttar.yml
b/.github/workflows/gradle-publish-disttar.yml
index 0acb1e6..2ec3b6c 100644
--- a/.github/workflows/gradle-publish-disttar.yml
+++ b/.github/workflows/gradle-publish-disttar.yml
@@ -17,10 +17,10 @@ jobs:
steps:
- uses: actions/checkout@v6
- - name: Set up JDK 17
+ - name: Set up JDK 21
uses: actions/setup-java@v5
with:
- java-version: '17'
+ java-version: '21'
distribution: 'temurin'
cache: 'gradle'
server-id: github # Value of the distributionManagement/repository/id
field of the pom.xml
diff --git a/.github/workflows/publish-release.yml
b/.github/workflows/publish-release.yml
index 7386e37..92ca42e 100644
--- a/.github/workflows/publish-release.yml
+++ b/.github/workflows/publish-release.yml
@@ -15,10 +15,10 @@ jobs:
- name: Checkout code
uses: actions/checkout@v6
- - name: Set up JDK 17
+ - name: Set up JDK 21
uses: actions/setup-java@v5
with:
- java-version: '17'
+ java-version: '21'
distribution: 'temurin'
cache: 'gradle'
diff --git a/README.md b/README.md
index e9d0046..bdf60b0 100644
--- a/README.md
+++ b/README.md
@@ -264,13 +264,13 @@ If `CASSANDRA_VERSION` is not set, it defaults to "5.0".
The GitHub Actions CI workflow (`.github/workflows/ci.yml`) runs on every push
and pull request.
**Test matrix:**
-- **Java versions**: 17 and 21
+- **Java versions**: 21 and 25 (current + next LTS)
- **Cassandra versions**: 4.0, 4.1, 5.0
This creates 6 test jobs total:
-- Cassandra 4.0 on Java 17 and 21
-- Cassandra 4.1 on Java 17 and 21
-- Cassandra 5.0 on Java 17 and 21
+- Cassandra 4.0 on Java 21 and 25
+- Cassandra 4.1 on Java 21 and 25
+- Cassandra 5.0 on Java 21 and 25
**Workflow steps:**
diff --git a/bin/cassandra-easy-stress b/bin/cassandra-easy-stress
index 99267d6..6ad5d08 100755
--- a/bin/cassandra-easy-stress
+++ b/bin/cassandra-easy-stress
@@ -6,7 +6,18 @@ cd $BASE_STRESS_DIR
JAR=$(find build/libs -name '*-all.jar' | tail -n 1)
-java -jar $JAR "$@"
+# Generational ZGC by default; set JAVA_OPTS to override (e.g. to select a
+# different collector). JDK 23+ made generational collection the only ZGC
+# mode and removed -XX:+ZGenerational, so only pass it on older JDKs.
+JAVA_MAJOR_VERSION=$(java -version 2>&1 | awk -F'"' '/version/ {print $2}' |
cut -d. -f1)
+if [ "$JAVA_MAJOR_VERSION" -ge 23 ] 2>/dev/null; then
+ DEFAULT_GC_OPTS="-XX:+UseZGC"
+else
+ DEFAULT_GC_OPTS="-XX:+UseZGC -XX:+ZGenerational"
+fi
+JAVA_OPTS="${JAVA_OPTS:-$DEFAULT_GC_OPTS}"
+
+java $JAVA_OPTS -jar $JAR "$@"
diff --git a/build.gradle b/build.gradle
deleted file mode 100644
index 4041edc..0000000
--- a/build.gradle
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-plugins {
- alias(libs.plugins.jib)
- alias(libs.plugins.kotlin.jvm)
- alias(libs.plugins.kotlin.serialization)
- alias(libs.plugins.nebula.ospackage)
- alias(libs.plugins.nebula.ospackage.application)
- alias(libs.plugins.ktlint)
- alias(libs.plugins.detekt)
- alias(libs.plugins.shadow)
- alias(libs.plugins.kover)
-}
-
-
-apply plugin: 'idea'
-apply plugin: 'java'
-apply plugin: 'kotlin'
-apply plugin: 'application'
-
-group 'org.apache.cassandra'
-
-sourceCompatibility = 11
-
-application {
- applicationName = "cassandra-easy-stress"
- mainClassName = "org.apache.cassandra.easystress.MainKt"
-}
-
-repositories {
- mavenCentral()
-}
-
-dependencies {
- implementation libs.jcommander
- implementation libs.commons.text
- implementation libs.commons.math3
-
- // Java driver v4
- implementation libs.cassandra.driver.core
- implementation libs.jackson.module.kotlin
-
- implementation libs.reflections
-
- // Logging
- implementation libs.log4j.api
- implementation libs.log4j.core
- implementation libs.log4j.api.kotlin
- implementation libs.kotlin.reflect
- // maps the datastax driver slf4j calls to log4j
- implementation libs.log4j.slf4j18.impl
-
- // needed for yaml logging configurations
- implementation libs.jackson.databind
- implementation libs.jackson.dataformat.yaml
-
- // Metrics
- implementation libs.dropwizard.metrics.core
- implementation libs.prometheus.simpleclient
- implementation libs.prometheus.simpleclient.dropwizard
- implementation libs.prometheus.simpleclient.httpserver
-
- implementation libs.guava
- implementation libs.mordant
- implementation libs.progressbar
- implementation libs.hdrhistogram
- implementation libs.agrona // can't use the 2.x or 1.23+ line as it
requires JDK 17
-
- // Parquet support
- implementation libs.parquet.hadoop
- implementation libs.hadoop.common
- implementation libs.hadoop.mapreduce.client.common
-
- // MCP Server dependencies
- implementation (libs.mcp.sdk) {
- exclude group: 'org.slf4j', module: 'slf4j-api'
- }
- implementation (libs.ktor.server.core) {
- exclude group: 'org.slf4j', module: 'slf4j-api'
- }
- implementation (libs.ktor.server.cio) {
- exclude group: 'org.slf4j', module: 'slf4j-api'
- }
- implementation (libs.ktor.server.content.negotiation) {
- exclude group: 'org.slf4j', module: 'slf4j-api'
- }
- implementation (libs.ktor.serialization.kotlinx.json) {
- exclude group: 'org.slf4j', module: 'slf4j-api'
- }
- implementation (libs.ktor.server.sse) {
- exclude group: 'org.slf4j', module: 'slf4j-api'
- }
-
- // Test dependencies
- testImplementation libs.junit.jupiter.engine
- testImplementation libs.junit.jupiter.params
- testImplementation libs.assertj.core
- testImplementation libs.kotlin.test.junit
- testImplementation libs.mockk
- testImplementation libs.kotlinx.coroutines.test
- testImplementation platform(libs.testcontainers.bom)
- testImplementation libs.testcontainers.core
- testImplementation libs.testcontainers.cassandra
-
-}
-
-compileKotlin {
- kotlinOptions.jvmTarget = JavaVersion.VERSION_11
-}
-compileTestKotlin {
- kotlinOptions.jvmTarget = JavaVersion.VERSION_11
-}
-
-sourceSets {
- main.java.srcDirs += "src/main/kotlin"
- test.java.srcDirs += "src/test/kotlin"
-}
-
-test {
- useJUnitPlatform()
-
- // Make Gradle aware of CASSANDRA_VERSION environment variable
- // This ensures tests rerun when the version changes
- def cassandraVersion = System.getenv("CASSANDRA_VERSION") ?: "5.0"
- inputs.property("cassandraVersion", cassandraVersion)
-
- // Pass environment variable to test JVM
- environment "CASSANDRA_VERSION", cassandraVersion
-}
-
-// Create individual test tasks for each Cassandra version
-["4.0", "4.1", "5.0"].each { version ->
- def versionName = version.replace(".", "")
- tasks.register("test${versionName}", Test) {
- group = "Verification"
- description = "Run tests against Cassandra ${version}"
-
- useJUnitPlatform()
-
- // Set the Cassandra version for this test task
- environment "CASSANDRA_VERSION", version
- inputs.property("cassandraVersion", version)
-
- // Use same test sources and classpath as main test task
- testClassesDirs = sourceSets.test.output.classesDirs
- classpath = sourceSets.test.runtimeClasspath
-
- doFirst {
- println ""
- println "=" * 80
- println "Testing Cassandra ${version}"
- println "=" * 80
- }
-
- doLast {
- println ""
- println "✅ Cassandra ${version} tests PASSED"
- }
- }
-}
-
-task testAllVersions {
- group = "Verification"
- description = "Run tests against all Cassandra versions (4.0, 4.1, 5.0)"
-
- // Depend on all version-specific test tasks
- dependsOn tasks.test40, tasks.test41, tasks.test50
-
- // Ensure sequential execution
- tasks.test41.mustRunAfter tasks.test40
- tasks.test50.mustRunAfter tasks.test41
-
- doFirst {
- println ""
- println "=" * 80
- println "Running tests against all Cassandra versions: 4.0, 4.1, 5.0"
- println "=" * 80
- }
-
- doLast {
- println ""
- println "=" * 80
- println "Test Summary"
- println "=" * 80
- println "✅ Cassandra 4.0: PASSED"
- println "✅ Cassandra 4.1: PASSED"
- println "✅ Cassandra 5.0: PASSED"
- println "=" * 80
- println ""
- }
-}
-
-task docs(type:Exec) {
- dependsOn("shadowJar")
- dependsOn("generateExamples")
-
- environment "CASSANDRA_EASY_STRESS_VERSION", "${version}"
- commandLine 'docker-compose', 'up', 'docs'
- group = "Documentation"
- description = "Build website documentation"
-}
-
-task generateExamples(type: Exec) {
- dependsOn("shadowJar")
- commandLine "manual/generate_examples.sh"
- group = "Documentation"
- description = "Generate examples for documentation"
-}
-
-jib {
- to {
- image = "ghcr.io/${System.getenv('GITHUB_REPOSITORY') ?:
'apache/cassandra-easy-stress'}"
- tags = ["latest"]
- }
- from {
- image = "eclipse-temurin:17-jre"
- }
-}
-
-ospackage {
- os = LINUX
- link("/usr/local/bin/cassandra-easy-stress",
"/opt/cassandra-easy-stress/bin/cassandra-easy-stress" )
- packager "Jon Haddad"
- maintainer "Jon Haddad"
- vendor "Rustyrazorblade Consulting"
- url "http://rustyrazorblade.com/cassandra-easy-stress/"
- license "Apache License 2.0"
- description "Stress Tool for Apache Cassandra by Rustyrazorblade
Consulting"
-}
-
-buildDeb {
- distribution "weezy,bionic,xenial,jessie"
- requires("openjdk-8-jre")
- group = "build"
-}
-
-buildRpm {
- requires("java-1.8.0-openjdk")
- user "root"
- group = "build"
-}
-
-task buildAll {
- group = "build"
- dependsOn "buildDeb"
- dependsOn "buildRpm"
- dependsOn "distTar"
-}
-
-tasks.distTar {
- compression = Compression.GZIP
- archiveExtension.set("tar.gz")
-}
-
-assemble.mustRunAfter clean
-
-applicationDistribution.from("LICENSE.txt") {
- into ""
-}
-
-wrapper {
- distributionType = Wrapper.DistributionType.ALL
-}
-targetCompatibility = JavaVersion.VERSION_11
-
-detekt {
- toolVersion = "1.23.7"
- source = files("src/main/kotlin", "src/test/kotlin")
- parallel = true
- config = files("$projectDir/detekt-config.yml")
- buildUponDefaultConfig = true
- allRules = false
- baseline = file("$projectDir/detekt-baseline.xml")
- disableDefaultRuleSets = false
- debug = false
- ignoreFailures = false
- ignoredBuildTypes = ["release"]
- ignoredFlavors = ["production"]
- ignoredVariants = ["productionRelease"]
- autoCorrect = false
-}
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
index 0000000..160320a
--- /dev/null
+++ b/build.gradle.kts
@@ -0,0 +1,348 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.netflix.gradle.plugins.deb.Deb
+import com.netflix.gradle.plugins.rpm.Rpm
+import io.gitlab.arturbosch.detekt.Detekt
+import io.gitlab.arturbosch.detekt.DetektCreateBaselineTask
+import org.jetbrains.kotlin.gradle.dsl.JvmTarget
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+import org.redline_rpm.header.Os
+
+plugins {
+ idea
+ java
+ application
+ alias(libs.plugins.jib)
+ alias(libs.plugins.kotlin.jvm)
+ alias(libs.plugins.kotlin.serialization)
+ alias(libs.plugins.nebula.ospackage)
+ alias(libs.plugins.nebula.ospackage.application)
+ alias(libs.plugins.ktlint)
+ alias(libs.plugins.detekt)
+ alias(libs.plugins.shadow)
+ alias(libs.plugins.kover)
+}
+
+apply(plugin = "kotlin")
+
+group = "org.apache.cassandra"
+
+// Target whatever JDK is actually running the build (21 or 25 in CI) rather
+// than pinning a fixed floor here -- the release-artifact-building CI jobs
+// (build, build-check, create-test-artifact) are the single source of truth
+// for what the shipped artifact requires, and they're pinned to JDK 21.
+java {
+ sourceCompatibility = JavaVersion.current()
+ targetCompatibility = JavaVersion.current()
+}
+
+application {
+ applicationName = "cassandra-easy-stress"
+ mainClass = "org.apache.cassandra.easystress.MainKt"
+}
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ implementation(libs.jcommander)
+ implementation(libs.commons.text)
+ implementation(libs.commons.math3)
+
+ // Java driver v4
+ implementation(libs.cassandra.driver.core)
+ implementation(libs.jackson.module.kotlin)
+
+ implementation(libs.reflections)
+
+ // Logging
+ implementation(libs.log4j.api)
+ implementation(libs.log4j.core)
+ implementation(libs.log4j.api.kotlin)
+ implementation(libs.kotlin.reflect)
+ // maps the datastax driver slf4j calls to log4j
+ implementation(libs.log4j.slf4j18.impl)
+
+ // needed for yaml logging configurations
+ implementation(libs.jackson.databind)
+ implementation(libs.jackson.dataformat.yaml)
+
+ // Metrics
+ implementation(libs.dropwizard.metrics.core)
+ implementation(libs.prometheus.simpleclient)
+ implementation(libs.prometheus.simpleclient.dropwizard)
+ implementation(libs.prometheus.simpleclient.httpserver)
+
+ implementation(libs.guava)
+ implementation(libs.mordant)
+ implementation(libs.progressbar)
+ implementation(libs.hdrhistogram)
+ // Pinned to 1.22.0; the project now targets JDK 21, so the 2.x/1.23+
+ // line's former JDK 17 requirement is no longer a blocker -- upgrading
+ // is possible but left out of scope here.
+ implementation(libs.agrona)
+
+ // Parquet support
+ implementation(libs.parquet.hadoop)
+ implementation(libs.hadoop.common)
+ implementation(libs.hadoop.mapreduce.client.common)
+
+ // MCP Server dependencies
+ implementation(libs.mcp.sdk) {
+ exclude(group = "org.slf4j", module = "slf4j-api")
+ }
+ implementation(libs.ktor.server.core) {
+ exclude(group = "org.slf4j", module = "slf4j-api")
+ }
+ implementation(libs.ktor.server.cio) {
+ exclude(group = "org.slf4j", module = "slf4j-api")
+ }
+ implementation(libs.ktor.server.content.negotiation) {
+ exclude(group = "org.slf4j", module = "slf4j-api")
+ }
+ implementation(libs.ktor.serialization.kotlinx.json) {
+ exclude(group = "org.slf4j", module = "slf4j-api")
+ }
+ implementation(libs.ktor.server.sse) {
+ exclude(group = "org.slf4j", module = "slf4j-api")
+ }
+
+ // Test dependencies
+ testImplementation(libs.junit.jupiter.engine)
+ testImplementation(libs.junit.jupiter.params)
+ testRuntimeOnly(libs.junit.platform.launcher)
+ testImplementation(libs.assertj.core)
+ testImplementation(libs.kotlin.test.junit)
+ testImplementation(libs.mockk)
+ testImplementation(libs.kotlinx.coroutines.test)
+ testImplementation(platform(libs.testcontainers.bom))
+ testImplementation(libs.testcontainers.core)
+ testImplementation(libs.testcontainers.cassandra)
+}
+
+// Target whatever JDK is actually running the build, matching the java {}
+// block above -- see the comment there.
+tasks.withType<KotlinCompile>().configureEach {
+ compilerOptions {
+ jvmTarget.set(JvmTarget.fromTarget(JavaVersion.current().majorVersion))
+ }
+}
+
+sourceSets {
+ main {
+ java.srcDirs("src/main/kotlin")
+ }
+ test {
+ java.srcDirs("src/test/kotlin")
+ }
+}
+
+tasks.test {
+ useJUnitPlatform()
+
+ // Make Gradle aware of CASSANDRA_VERSION environment variable
+ // This ensures tests rerun when the version changes
+ val cassandraVersion = System.getenv("CASSANDRA_VERSION") ?: "5.0"
+ inputs.property("cassandraVersion", cassandraVersion)
+
+ // Pass environment variable to test JVM
+ environment("CASSANDRA_VERSION", cassandraVersion)
+}
+
+// Create individual test tasks for each Cassandra version
+listOf("4.0", "4.1", "5.0").forEach { version ->
+ val versionName = version.replace(".", "")
+ tasks.register<Test>("test$versionName") {
+ group = "Verification"
+ description = "Run tests against Cassandra $version"
+
+ useJUnitPlatform()
+
+ // Set the Cassandra version for this test task
+ environment("CASSANDRA_VERSION", version)
+ inputs.property("cassandraVersion", version)
+
+ // Use same test sources and classpath as main test task
+ testClassesDirs =
+ sourceSets.test
+ .get()
+ .output.classesDirs
+ classpath = sourceSets.test.get().runtimeClasspath
+
+ doFirst {
+ println()
+ println("=".repeat(80))
+ println("Testing Cassandra $version")
+ println("=".repeat(80))
+ }
+
+ doLast {
+ println()
+ println("✅ Cassandra $version tests PASSED")
+ }
+ }
+}
+
+// Ensure sequential execution
+tasks.named("test41") { mustRunAfter(tasks.named("test40")) }
+tasks.named("test50") { mustRunAfter(tasks.named("test41")) }
+
+tasks.register("testAllVersions") {
+ group = "Verification"
+ description = "Run tests against all Cassandra versions (4.0, 4.1, 5.0)"
+
+ // Depend on all version-specific test tasks
+ dependsOn(tasks.named("test40"), tasks.named("test41"),
tasks.named("test50"))
+
+ doFirst {
+ println()
+ println("=".repeat(80))
+ println("Running tests against all Cassandra versions: 4.0, 4.1, 5.0")
+ println("=".repeat(80))
+ }
+
+ doLast {
+ println()
+ println("=".repeat(80))
+ println("Test Summary")
+ println("=".repeat(80))
+ println("✅ Cassandra 4.0: PASSED")
+ println("✅ Cassandra 4.1: PASSED")
+ println("✅ Cassandra 5.0: PASSED")
+ println("=".repeat(80))
+ println()
+ }
+}
+
+tasks.register<Exec>("docs") {
+ dependsOn("shadowJar")
+ dependsOn("generateExamples")
+
+ environment("CASSANDRA_EASY_STRESS_VERSION", project.version.toString())
+ commandLine("docker-compose", "up", "docs")
+ group = "Documentation"
+ description = "Build website documentation"
+}
+
+tasks.register<Exec>("generateExamples") {
+ dependsOn("shadowJar")
+ commandLine("manual/generate_examples.sh")
+ group = "Documentation"
+ description = "Generate examples for documentation"
+}
+
+// JDK 23+ removed -XX:+ZGenerational (generational collection is ZGC's only
+// mode there); keep this in sync with the JDK-version check in
+// bin/cassandra-easy-stress.
+val jibBaseJdkVersion = 21
+val jibGcOpts =
+ if (jibBaseJdkVersion >= 23) "-XX:+UseZGC" else "-XX:+UseZGC
-XX:+ZGenerational"
+
+jib {
+ to {
+ image = "ghcr.io/${System.getenv("GITHUB_REPOSITORY") ?:
"apache/cassandra-easy-stress"}"
+ tags = setOf("latest")
+ }
+ from {
+ image = "eclipse-temurin:$jibBaseJdkVersion-jre"
+ }
+ container {
+ // Generational ZGC by default; override at "docker run" time with
+ // -e JAVA_TOOL_OPTIONS="..." to select a different collector.
+ environment = mapOf("JAVA_TOOL_OPTIONS" to jibGcOpts)
+ }
+}
+
+ospackage {
+ os = Os.LINUX
+ link("/usr/local/bin/cassandra-easy-stress",
"/opt/cassandra-easy-stress/bin/cassandra-easy-stress")
+ packager = "Jon Haddad"
+ maintainer = "Jon Haddad"
+ vendor = "Rustyrazorblade Consulting"
+ url = "http://rustyrazorblade.com/cassandra-easy-stress/"
+ license = "Apache License 2.0"
+ description = "Stress Tool for Apache Cassandra by Rustyrazorblade
Consulting"
+}
+
+tasks.named<Deb>("buildDeb") {
+ distribution = "weezy,bionic,xenial,jessie"
+ requires("openjdk-21-jre")
+ group = "build"
+}
+
+tasks.named<Rpm>("buildRpm") {
+ requires("java-21-openjdk")
+ user = "root"
+ group = "build"
+}
+
+tasks.register("buildAll") {
+ group = "build"
+ dependsOn("buildDeb")
+ dependsOn("buildRpm")
+ dependsOn("distTar")
+}
+
+tasks.distTar {
+ compression = Compression.GZIP
+ archiveExtension.set("tar.gz")
+}
+
+tasks.assemble {
+ mustRunAfter(tasks.clean)
+}
+
+distributions {
+ main {
+ contents {
+ from("LICENSE.txt") {
+ into("")
+ }
+ }
+ }
+}
+
+tasks.wrapper {
+ distributionType = Wrapper.DistributionType.ALL
+}
+
+detekt {
+ toolVersion = "1.23.8"
+ source.setFrom(files("src/main/kotlin", "src/test/kotlin"))
+ parallel = true
+ config.setFrom(files("$projectDir/detekt-config.yml"))
+ buildUponDefaultConfig = true
+ allRules = false
+ baseline = file("$projectDir/detekt-baseline.xml")
+ disableDefaultRuleSets = false
+ debug = false
+ ignoreFailures = false
+ ignoredBuildTypes = listOf("release")
+ ignoredFlavors = listOf("production")
+ ignoredVariants = listOf("productionRelease")
+ autoCorrect = false
+}
+
+tasks.withType<Detekt>().configureEach {
+ jvmTarget = "21"
+}
+tasks.withType<DetektCreateBaselineTask>().configureEach {
+ jvmTarget = "21"
+}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 10d134a..5d9f65f 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,11 +1,11 @@
[versions]
-kotlin = "2.2.20"
-jib = "3.3.0"
+kotlin = "2.4.10"
+jib = "3.5.4"
nebula-ospackage = "12.1.1"
ktlint = "14.0.1"
detekt = "1.23.8"
shadow = "9.2.2"
-kover = "0.9.2"
+kover = "0.9.9"
jcommander = "1.82"
commons-text = "1.3"
@@ -26,15 +26,15 @@ progressbar = "0.7.2"
hdrhistogram = "2.1.12"
agrona = "1.22.0"
parquet = "1.15.2"
-hadoop = "3.4.1"
-junit = "5.1.0"
-junit-params = "5.4.0"
+hadoop = "3.4.3"
+junit = "6.1.3"
+junit-params = "6.1.3"
assertj = "3.9.1"
-mockk = "1.12.7"
+mockk = "1.14.3"
coroutines-test = "1.9.0"
mcp-sdk = "0.7.2"
ktor = "3.3.0"
-testcontainers = "1.19.8"
+testcontainers = "2.0.5"
[libraries]
jcommander = { module = "com.beust:jcommander", version.ref = "jcommander" }
@@ -73,6 +73,7 @@ hadoop-mapreduce-client-common = { module =
"org.apache.hadoop:hadoop-mapreduce-
junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine",
version.ref = "junit" }
junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params",
version.ref = "junit-params" }
+junit-platform-launcher = { module =
"org.junit.platform:junit-platform-launcher", version.ref = "junit" }
assertj-core = { module = "org.assertj:assertj-core", version.ref = "assertj" }
kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit" }
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect" }
@@ -80,7 +81,7 @@ mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
kotlinx-coroutines-test = { module =
"org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref =
"coroutines-test" }
testcontainers-bom = { module = "org.testcontainers:testcontainers-bom",
version.ref = "testcontainers" }
testcontainers-core = { module = "org.testcontainers:testcontainers" }
-testcontainers-cassandra = { module = "org.testcontainers:cassandra" }
+testcontainers-cassandra = { module =
"org.testcontainers:testcontainers-cassandra" }
mcp-sdk = { module = "io.modelcontextprotocol:kotlin-sdk", version.ref =
"mcp-sdk" }
ktor-server-core = { module = "io.ktor:ktor-server-core-jvm", version.ref =
"ktor" }
diff --git a/gradle/wrapper/gradle-wrapper.jar
b/gradle/wrapper/gradle-wrapper.jar
index 7454180..1b33c55 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and
b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties
b/gradle/wrapper/gradle-wrapper.properties
index e69d040..d953c1f 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.0-all.zip
+networkTimeout=10000
+validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index 1b6c787..23d15a9 100755
--- a/gradlew
+++ b/gradlew
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+# SPDX-License-Identifier: Apache-2.0
+#
##############################################################################
#
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
-#
https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#
https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -80,13 +82,11 @@ do
esac
done
-APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
-
-APP_NAME="Gradle"
+# This is normally unused
+# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to
pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+# Discard cd standard output in case $CDPATH is set
(https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) ||
exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -114,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
@@ -133,22 +133,29 @@ location of your Java installation."
fi
else
JAVACMD=java
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no
'java' command could be found in your PATH.
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found
in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
+ fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is
checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is
checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -193,18 +200,28 @@ if "$cygwin" || "$msys" ; then
done
fi
-# Collect all arguments for the java command;
-# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
-# shell script including quotes and variable substitutions, so put them in
-# double quotes to make sure that they get re-expanded; and
-# * put everything else in single quotes, so that it's not re-expanded.
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to
pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to
contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is
an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
- org.gradle.wrapper.GradleWrapperMain \
+ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes
removed.
diff --git a/gradlew.bat b/gradlew.bat
index ac1b06f..5eed7ee 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -13,8 +13,10 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
+@rem SPDX-License-Identifier: Apache-2.0
+@rem
-@if "%DEBUG%" == "" @echo off
+@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,7 +27,8 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto execute
+if %ERRORLEVEL% equ 0 goto execute
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your
PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your
PATH. 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
goto fail
@@ -56,32 +59,34 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+set CLASSPATH=
@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS%
"-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%"
org.gradle.wrapper.GradleWrapperMain %*
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS%
"-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar
"%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
+if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code
instead of
rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]