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 b4fd752  Add conditional workload loading in tests and improve test 
infrastructure (#49)
b4fd752 is described below

commit b4fd752fa3034cf5f183419d300fce24f111f981
Author: Jon Haddad <j...@jonhaddad.com>
AuthorDate: Tue Aug 5 14:26:11 2025 -0400

    Add conditional workload loading in tests and improve test infrastructure 
(#49)
    
    - Add @RequireDSE, @RequireMVs, @RequireAccord annotations for conditional 
plugin loading
    - Make Plugin.getPluginsForTesting() accept environment map for better 
testability
    - Add comprehensive tests for plugin filtering in RequireAnnotationsTest
    - Add useOptimizer property to Run class for disabling rate limiter 
optimizer in tests
    - Fix ParquetCollectorTest compilation warning with proper null handling
    - Refactor CassandraTestBase to use instance-level connections for parallel 
test execution
      - Each test class now manages its own CqlSession
      - Prevents connection conflicts between test classes
    
    Closes #48
---
 README.md                                          |  53 ++++++
 .../com/rustyrazorblade/easycassstress/Plugin.kt   |  25 +++
 .../easycassstress/RequireAccord.kt}               |  36 +----
 .../rustyrazorblade/easycassstress/RequireDSE.kt}  |  36 +----
 .../rustyrazorblade/easycassstress/RequireMVs.kt}  |  36 +----
 .../rustyrazorblade/easycassstress/commands/Run.kt |  24 ++-
 .../easycassstress/workloads/DSESearch.kt          |   2 +
 .../easycassstress/workloads/MaterializedViews.kt  |   2 +
 .../easycassstress/workloads/TxnCounter.kt         |   2 +
 .../easycassstress/RequireAnnotationsTest.kt       | 180 +++++++++++++++++++++
 .../collector/ParquetCollectorTest.kt              |   2 +-
 .../integration/AllPluginsBasicTest.kt             |  10 +-
 .../integration/CassandraTestBase.kt               |  44 +++--
 .../easycassstress/integration/FlagsTest.kt        |   2 +
 14 files changed, 330 insertions(+), 124 deletions(-)

diff --git a/README.md b/README.md
index afe8430..df37b50 100644
--- a/README.md
+++ b/README.md
@@ -54,3 +54,56 @@ Time series workload with Cassandra Authentication enabled:
 # Generating docs
 
 Docs are served out of /docs and can be rebuild using `./gradlew docs`.
+
+# Testing
+
+## Running Tests
+
+To run the test suite:
+
+    ./gradlew test
+
+## Special Workloads
+
+Some workloads require specific features or configurations that may not be 
available in all Cassandra deployments. These workloads are marked with special 
annotations and are skipped by default when running tests.
+
+### DSE-Specific Workloads
+
+Workloads that require DataStax Enterprise (DSE) features are marked with the 
`@RequireDSE` annotation.
+
+Currently, the following workloads require DSE:
+- `DSESearch` - Uses DSE Search (Solr) functionality
+
+To run tests that require DSE, set the `TEST_DSE` environment variable:
+
+    TEST_DSE=1 ./gradlew test
+
+### Materialized Views Workloads
+
+Workloads that use Materialized Views are marked with the `@RequireMVs` 
annotation. Materialized Views are not enabled by default. 
+
+Currently, the following workloads require Materialized Views:
+- `MaterializedViews` - Tests materialized view functionality
+
+To run tests that require Materialized Views, set the `TEST_MVS` environment 
variable:
+
+    TEST_MVS=1 ./gradlew test
+
+### Accord Workloads
+
+Workloads that use Accord (available in Cassandra 6.0+) are marked with the 
`@RequireAccord` annotation.
+
+Currently, the following workloads require Accord:
+- `TxnCounter` - Tests Accord transaction functionality
+
+To run tests that require Accord, set the `TEST_ACCORD` environment variable:
+
+    TEST_ACCORD=1 ./gradlew test
+
+### Running All Tests
+
+To run all tests including DSE, Materialized Views, and Accord workloads:
+
+    TEST_DSE=1 TEST_MVS=1 TEST_ACCORD=1 ./gradlew test
+
+Make sure you have the appropriate Cassandra configuration and features 
enabled before running these specialized tests.
diff --git a/src/main/kotlin/com/rustyrazorblade/easycassstress/Plugin.kt 
b/src/main/kotlin/com/rustyrazorblade/easycassstress/Plugin.kt
index 1853e12..a7de0b3 100644
--- a/src/main/kotlin/com/rustyrazorblade/easycassstress/Plugin.kt
+++ b/src/main/kotlin/com/rustyrazorblade/easycassstress/Plugin.kt
@@ -67,6 +67,31 @@ data class Plugin(
 
             return result
         }
+
+        /**
+         * Returns plugins suitable for testing, filtering out those requiring
+         * special environments unless corresponding environment variables are 
set.
+         */
+        fun getPluginsForTesting(envVars: Map<String, String> = 
System.getenv()): Map<String, Plugin> {
+            val allPlugins = getPlugins()
+            val testDSE = envVars["TEST_DSE"] == "1"
+            val testMVs = envVars["TEST_MVS"] == "1"
+            val testAccord = envVars["TEST_ACCORD"] == "1"
+
+            return allPlugins.filterValues { plugin ->
+                // Check if the plugin class has @RequireDSE, @RequireMVs, or 
@RequireAccord annotations
+                val requiresDSE = 
plugin.cls.isAnnotationPresent(RequireDSE::class.java)
+                val requiresMVs = 
plugin.cls.isAnnotationPresent(RequireMVs::class.java)
+                val requiresAccord = 
plugin.cls.isAnnotationPresent(RequireAccord::class.java)
+
+                // Include the plugin if:
+                // - It doesn't require DSE, MVs, or Accord, OR
+                // - It requires DSE AND TEST_DSE is set, OR
+                // - It requires MVs AND TEST_MVS is set, OR
+                // - It requires Accord AND TEST_ACCORD is set to "1"
+                (!requiresDSE || testDSE) && (!requiresMVs || testMVs) && 
(!requiresAccord || testAccord)
+            }
+        }
     }
 
     /**
diff --git 
a/src/test/kotlin/com/rustyrazorblade/easycassstress/integration/FlagsTest.kt 
b/src/main/kotlin/com/rustyrazorblade/easycassstress/RequireAccord.kt
similarity index 50%
copy from 
src/test/kotlin/com/rustyrazorblade/easycassstress/integration/FlagsTest.kt
copy to src/main/kotlin/com/rustyrazorblade/easycassstress/RequireAccord.kt
index 15e2c75..44707da 100644
--- 
a/src/test/kotlin/com/rustyrazorblade/easycassstress/integration/FlagsTest.kt
+++ b/src/main/kotlin/com/rustyrazorblade/easycassstress/RequireAccord.kt
@@ -15,35 +15,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.rustyrazorblade.easycassstress.integration
-
-import com.rustyrazorblade.easycassstress.commands.Run
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
+package com.rustyrazorblade.easycassstress
 
 /**
- * Simple tests for various flags that don't required dedicated testing
+ * Marks a workload as requiring Accord.
+ * Tests for workloads annotated with this will be skipped by default
+ * unless the TEST_ACCORD environment variable is set to "1".
  */
-class FlagsTest : CassandraTestBase() {
-    var keyvalue = Run("placeholder")
-
-    @BeforeEach
-    fun resetRunners() {
-        cleanupKeyspace()
-        keyvalue =
-            Run("placeholder").apply {
-                profile = "KeyValue"
-                iterations = 100
-                host = ip
-                dc = localDc
-                replication = "{'class': 'SimpleStrategy', 
'replication_factor':1 }"
-            }
-    }
-
-    @Test
-    fun csvTest() {
-        keyvalue.apply {
-            csvFile = "test.csv"
-        }.execute()
-    }
-}
+@Target(AnnotationTarget.CLASS)
+@Retention(AnnotationRetention.RUNTIME)
+annotation class RequireAccord
diff --git 
a/src/test/kotlin/com/rustyrazorblade/easycassstress/integration/FlagsTest.kt 
b/src/main/kotlin/com/rustyrazorblade/easycassstress/RequireDSE.kt
similarity index 50%
copy from 
src/test/kotlin/com/rustyrazorblade/easycassstress/integration/FlagsTest.kt
copy to src/main/kotlin/com/rustyrazorblade/easycassstress/RequireDSE.kt
index 15e2c75..b4fa8a9 100644
--- 
a/src/test/kotlin/com/rustyrazorblade/easycassstress/integration/FlagsTest.kt
+++ b/src/main/kotlin/com/rustyrazorblade/easycassstress/RequireDSE.kt
@@ -15,35 +15,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.rustyrazorblade.easycassstress.integration
-
-import com.rustyrazorblade.easycassstress.commands.Run
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
+package com.rustyrazorblade.easycassstress
 
 /**
- * Simple tests for various flags that don't required dedicated testing
+ * Marks a workload as requiring DataStax Enterprise (DSE).
+ * Tests for workloads annotated with this will be skipped by default
+ * unless the TEST_DSE environment variable is set.
  */
-class FlagsTest : CassandraTestBase() {
-    var keyvalue = Run("placeholder")
-
-    @BeforeEach
-    fun resetRunners() {
-        cleanupKeyspace()
-        keyvalue =
-            Run("placeholder").apply {
-                profile = "KeyValue"
-                iterations = 100
-                host = ip
-                dc = localDc
-                replication = "{'class': 'SimpleStrategy', 
'replication_factor':1 }"
-            }
-    }
-
-    @Test
-    fun csvTest() {
-        keyvalue.apply {
-            csvFile = "test.csv"
-        }.execute()
-    }
-}
+@Target(AnnotationTarget.CLASS)
+@Retention(AnnotationRetention.RUNTIME)
+annotation class RequireDSE
diff --git 
a/src/test/kotlin/com/rustyrazorblade/easycassstress/integration/FlagsTest.kt 
b/src/main/kotlin/com/rustyrazorblade/easycassstress/RequireMVs.kt
similarity index 50%
copy from 
src/test/kotlin/com/rustyrazorblade/easycassstress/integration/FlagsTest.kt
copy to src/main/kotlin/com/rustyrazorblade/easycassstress/RequireMVs.kt
index 15e2c75..1dd7f4b 100644
--- 
a/src/test/kotlin/com/rustyrazorblade/easycassstress/integration/FlagsTest.kt
+++ b/src/main/kotlin/com/rustyrazorblade/easycassstress/RequireMVs.kt
@@ -15,35 +15,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.rustyrazorblade.easycassstress.integration
-
-import com.rustyrazorblade.easycassstress.commands.Run
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
+package com.rustyrazorblade.easycassstress
 
 /**
- * Simple tests for various flags that don't required dedicated testing
+ * Marks a workload as requiring Materialized Views.
+ * Tests for workloads annotated with this will be skipped by default
+ * unless the TEST_MVS environment variable is set.
  */
-class FlagsTest : CassandraTestBase() {
-    var keyvalue = Run("placeholder")
-
-    @BeforeEach
-    fun resetRunners() {
-        cleanupKeyspace()
-        keyvalue =
-            Run("placeholder").apply {
-                profile = "KeyValue"
-                iterations = 100
-                host = ip
-                dc = localDc
-                replication = "{'class': 'SimpleStrategy', 
'replication_factor':1 }"
-            }
-    }
-
-    @Test
-    fun csvTest() {
-        keyvalue.apply {
-            csvFile = "test.csv"
-        }.execute()
-    }
-}
+@Target(AnnotationTarget.CLASS)
+@Retention(AnnotationRetention.RUNTIME)
+annotation class RequireMVs
diff --git a/src/main/kotlin/com/rustyrazorblade/easycassstress/commands/Run.kt 
b/src/main/kotlin/com/rustyrazorblade/easycassstress/commands/Run.kt
index d49594b..456ce74 100644
--- a/src/main/kotlin/com/rustyrazorblade/easycassstress/commands/Run.kt
+++ b/src/main/kotlin/com/rustyrazorblade/easycassstress/commands/Run.kt
@@ -286,6 +286,8 @@ class Run(
     @Parameter(names = ["--hdr"], description = "Print HDR Histograms using 
this prefix")
     var hdrHistogramPrefix = ""
 
+    var useOptimizer = true
+
     val session by lazy {
         // Build a programmatic config
         var configLoaderBuilder =
@@ -411,13 +413,19 @@ class Run(
         val metrics = createMetrics()
 
         // set up the rate limiter optimizer and put it on a schedule
-        var optimizer = RateLimiterOptimizer(rateLimiter, metrics, 
maxReadLatency, maxWriteLatency)
-        optimizer.reset()
-
-        // Schedule the optimizer to run periodically
-        Timer().schedule(10000, 5000) {
-            optimizer.execute()
-        }
+        val optimizer =
+            if (useOptimizer) {
+                val opt = RateLimiterOptimizer(rateLimiter, metrics, 
maxReadLatency, maxWriteLatency)
+                opt.reset()
+
+                // Schedule the optimizer to run periodically
+                Timer().schedule(10000, 5000) {
+                    opt.execute()
+                }
+                opt
+            } else {
+                null
+            }
 
         var runnersExecuted = 0L
 
@@ -434,7 +442,7 @@ class Run(
 
             // since the populate workload is going to be substantially 
different
             // from the test workload, we need to reset the optimizer
-            optimizer.reset()
+            optimizer?.reset()
 
             metrics.startReporting()
             println("Prometheus metrics are available at 
http://localhost:$prometheusPort/";)
diff --git 
a/src/main/kotlin/com/rustyrazorblade/easycassstress/workloads/DSESearch.kt 
b/src/main/kotlin/com/rustyrazorblade/easycassstress/workloads/DSESearch.kt
index 29baa0c..0280a67 100644
--- a/src/main/kotlin/com/rustyrazorblade/easycassstress/workloads/DSESearch.kt
+++ b/src/main/kotlin/com/rustyrazorblade/easycassstress/workloads/DSESearch.kt
@@ -22,6 +22,7 @@ import com.datastax.oss.driver.api.core.cql.PreparedStatement
 import com.fasterxml.jackson.annotation.JsonInclude
 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
 import com.rustyrazorblade.easycassstress.PartitionKey
+import com.rustyrazorblade.easycassstress.RequireDSE
 import com.rustyrazorblade.easycassstress.StressContext
 import com.rustyrazorblade.easycassstress.WorkloadParameter
 import com.rustyrazorblade.easycassstress.generators.Field
@@ -30,6 +31,7 @@ import 
com.rustyrazorblade.easycassstress.generators.functions.Book
 import com.rustyrazorblade.easycassstress.generators.functions.Random
 import java.util.concurrent.ThreadLocalRandom
 
+@RequireDSE
 class DSESearch : IStressProfile {
     val table: String = "dse_search"
     val minValueTextSize = 5
diff --git 
a/src/main/kotlin/com/rustyrazorblade/easycassstress/workloads/MaterializedViews.kt
 
b/src/main/kotlin/com/rustyrazorblade/easycassstress/workloads/MaterializedViews.kt
index 933b924..bc90b5a 100644
--- 
a/src/main/kotlin/com/rustyrazorblade/easycassstress/workloads/MaterializedViews.kt
+++ 
b/src/main/kotlin/com/rustyrazorblade/easycassstress/workloads/MaterializedViews.kt
@@ -20,6 +20,7 @@ package com.rustyrazorblade.easycassstress.workloads
 import com.datastax.oss.driver.api.core.CqlSession
 import com.datastax.oss.driver.api.core.cql.PreparedStatement
 import com.rustyrazorblade.easycassstress.PartitionKey
+import com.rustyrazorblade.easycassstress.RequireMVs
 import com.rustyrazorblade.easycassstress.StressContext
 import com.rustyrazorblade.easycassstress.generators.Field
 import com.rustyrazorblade.easycassstress.generators.FieldFactory
@@ -29,6 +30,7 @@ import 
com.rustyrazorblade.easycassstress.generators.functions.LastName
 import com.rustyrazorblade.easycassstress.generators.functions.USCities
 import java.util.concurrent.ThreadLocalRandom
 
+@RequireMVs
 class MaterializedViews : IStressProfile {
     override fun prepare(session: CqlSession) {
         insert = session.prepare("INSERT INTO person (name, age, city) values 
(?, ?, ?)")
diff --git 
a/src/main/kotlin/com/rustyrazorblade/easycassstress/workloads/TxnCounter.kt 
b/src/main/kotlin/com/rustyrazorblade/easycassstress/workloads/TxnCounter.kt
index 3ed4c9a..5ff6349 100644
--- a/src/main/kotlin/com/rustyrazorblade/easycassstress/workloads/TxnCounter.kt
+++ b/src/main/kotlin/com/rustyrazorblade/easycassstress/workloads/TxnCounter.kt
@@ -2,6 +2,7 @@ package com.rustyrazorblade.easycassstress.workloads
 
 import com.datastax.oss.driver.api.core.CqlSession
 import com.rustyrazorblade.easycassstress.PartitionKey
+import com.rustyrazorblade.easycassstress.RequireAccord
 import com.rustyrazorblade.easycassstress.StressContext
 import com.rustyrazorblade.easycassstress.WorkloadParameter
 
@@ -42,6 +43,7 @@ enum class Impl {
  * cassandra-easy-stress run TxnCounter --workload.postfix=test_run1
  * ```
  */
+@RequireAccord
 class TxnCounter : IStressProfile {
     @WorkloadParameter("Which type of transaction system to use")
     var impl = Impl.LWT
diff --git 
a/src/test/kotlin/com/rustyrazorblade/easycassstress/RequireAnnotationsTest.kt 
b/src/test/kotlin/com/rustyrazorblade/easycassstress/RequireAnnotationsTest.kt
new file mode 100644
index 0000000..ce3170c
--- /dev/null
+++ 
b/src/test/kotlin/com/rustyrazorblade/easycassstress/RequireAnnotationsTest.kt
@@ -0,0 +1,180 @@
+/*
+ * 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.
+ */
+package com.rustyrazorblade.easycassstress
+
+import org.assertj.core.api.Assertions.assertThat
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+
+class RequireAnnotationsTest {
+    private lateinit var allPlugins: Map<String, Plugin>
+
+    @BeforeEach
+    fun setup() {
+        allPlugins = Plugin.getPlugins()
+    }
+
+    @Test
+    fun testGetPluginsForTestingFiltersCorrectly() {
+        val testingPlugins = Plugin.getPluginsForTesting()
+
+        assertThat(System.getenv("TEST_DSE")).isNull()
+        assertThat(System.getenv("TEST_MVS")).isNull()
+
+        // Verify DSESearch, MaterializedViews, TxnCounter exist in all plugins
+        assertThat(allPlugins).containsKey("DSESearch")
+        assertThat(allPlugins).containsKey("MaterializedViews")
+        assertThat(allPlugins).containsKey("TxnCounter")
+
+        assertThat(testingPlugins).doesNotContainKey("MaterializedViews")
+        assertThat(testingPlugins).doesNotContainKey("DSESearch")
+        assertThat(testingPlugins).doesNotContainKey("TxnCounter")
+    }
+
+    @Test
+    fun testDSEPluginFilteredWithoutEnvVar() {
+        // Test with empty environment
+        val emptyEnv = emptyMap<String, String>()
+        val testingPlugins = Plugin.getPluginsForTesting(emptyEnv)
+
+        // DSESearch should be filtered out
+        assertThat(testingPlugins).doesNotContainKey("DSESearch")
+
+        // Other non-annotated plugins should still be present
+        assertThat(testingPlugins).containsKey("BasicTimeSeries")
+        assertThat(testingPlugins).containsKey("KeyValue")
+    }
+
+    @Test
+    fun testDSEPluginIncludedWithEnvVar() {
+        // Test with TEST_DSE set
+        val envWithDSE = mapOf("TEST_DSE" to "1")
+        val testingPlugins = Plugin.getPluginsForTesting(envWithDSE)
+
+        // DSESearch should be included
+        assertThat(testingPlugins).containsKey("DSESearch")
+
+        // But MaterializedViews and TxnCounter should still be filtered out
+        assertThat(testingPlugins).doesNotContainKey("MaterializedViews")
+        assertThat(testingPlugins).doesNotContainKey("TxnCounter")
+    }
+
+    @Test
+    fun testMVsPluginFilteredWithoutEnvVar() {
+        // Test with empty environment
+        val emptyEnv = emptyMap<String, String>()
+        val testingPlugins = Plugin.getPluginsForTesting(emptyEnv)
+
+        // MaterializedViews should be filtered out
+        assertThat(testingPlugins).doesNotContainKey("MaterializedViews")
+
+        // Other non-annotated plugins should still be present
+        assertThat(testingPlugins).containsKey("BasicTimeSeries")
+        assertThat(testingPlugins).containsKey("KeyValue")
+    }
+
+    @Test
+    fun testMVsPluginIncludedWithEnvVar() {
+        // Test with TEST_MVS set
+        val envWithMVs = mapOf("TEST_MVS" to "1")
+        val testingPlugins = Plugin.getPluginsForTesting(envWithMVs)
+
+        // MaterializedViews should be included
+        assertThat(testingPlugins).containsKey("MaterializedViews")
+
+        // But DSESearch and TxnCounter should still be filtered out
+        assertThat(testingPlugins).doesNotContainKey("DSESearch")
+        assertThat(testingPlugins).doesNotContainKey("TxnCounter")
+    }
+
+    @Test
+    fun testAccordPluginFilteredWithoutEnvVar() {
+        // Test with empty environment
+        val emptyEnv = emptyMap<String, String>()
+        val testingPlugins = Plugin.getPluginsForTesting(emptyEnv)
+
+        // TxnCounter should be filtered out
+        assertThat(testingPlugins).doesNotContainKey("TxnCounter")
+
+        // Other non-annotated plugins should still be present
+        assertThat(testingPlugins).containsKey("BasicTimeSeries")
+        assertThat(testingPlugins).containsKey("KeyValue")
+    }
+
+    @Test
+    fun testAccordPluginIncludedWithEnvVar() {
+        // Test with TEST_ACCORD set to "1"
+        val envWithAccord = mapOf("TEST_ACCORD" to "1")
+        val testingPlugins = Plugin.getPluginsForTesting(envWithAccord)
+
+        // TxnCounter should be included
+        assertThat(testingPlugins).containsKey("TxnCounter")
+
+        // But DSESearch and MaterializedViews should still be filtered out
+        assertThat(testingPlugins).doesNotContainKey("DSESearch")
+        assertThat(testingPlugins).doesNotContainKey("MaterializedViews")
+    }
+
+    @Test
+    fun testAccordRequiresSpecificValue() {
+        // Test that TEST_ACCORD requires value "1", not just any value
+        val envWithWrongAccord = mapOf("TEST_ACCORD" to "true")
+        val testingPlugins = Plugin.getPluginsForTesting(envWithWrongAccord)
+
+        // TxnCounter should be filtered out because TEST_ACCORD != "1"
+        assertThat(testingPlugins).doesNotContainKey("TxnCounter")
+    }
+
+    @Test
+    fun testMultipleEnvVarsSet() {
+        // Test with all environment variables set
+        val envWithAll =
+            mapOf(
+                "TEST_DSE" to "1",
+                "TEST_MVS" to "1",
+                "TEST_ACCORD" to "1",
+            )
+        val testingPlugins = Plugin.getPluginsForTesting(envWithAll)
+
+        // All annotated plugins should be included
+        assertThat(testingPlugins).containsKey("DSESearch")
+        assertThat(testingPlugins).containsKey("MaterializedViews")
+        assertThat(testingPlugins).containsKey("TxnCounter")
+
+        // And all other plugins should still be present
+        assertThat(testingPlugins).containsKey("BasicTimeSeries")
+        assertThat(testingPlugins).containsKey("KeyValue")
+    }
+
+    @Test
+    fun testPluginAnnotations() {
+        // Verify the correct annotations are present on the plugins
+        val dsePlugin = allPlugins["DSESearch"]
+        val mvPlugin = allPlugins["MaterializedViews"]
+        val txnPlugin = allPlugins["TxnCounter"]
+
+        assertThat(dsePlugin).isNotNull
+        
assertThat(dsePlugin!!.cls.isAnnotationPresent(RequireDSE::class.java)).isTrue
+
+        assertThat(mvPlugin).isNotNull
+        
assertThat(mvPlugin!!.cls.isAnnotationPresent(RequireMVs::class.java)).isTrue
+
+        assertThat(txnPlugin).isNotNull
+        
assertThat(txnPlugin!!.cls.isAnnotationPresent(RequireAccord::class.java)).isTrue
+    }
+}
diff --git 
a/src/test/kotlin/com/rustyrazorblade/easycassstress/collector/ParquetCollectorTest.kt
 
b/src/test/kotlin/com/rustyrazorblade/easycassstress/collector/ParquetCollectorTest.kt
index 0801d81..b9a5f5a 100644
--- 
a/src/test/kotlin/com/rustyrazorblade/easycassstress/collector/ParquetCollectorTest.kt
+++ 
b/src/test/kotlin/com/rustyrazorblade/easycassstress/collector/ParquetCollectorTest.kt
@@ -46,7 +46,7 @@ internal class ParquetCollectorTest {
 
         Assertions.assertThat(expected).exists().isFile.doesNotHave(
             object : Condition<File>() {
-                override fun matches(value: File?): Boolean = 
Files.toByteArray(value).equals(unexpectedBytes)
+                override fun matches(value: File?): Boolean = value?.let { 
Files.toByteArray(it).contentEquals(unexpectedBytes) } ?: false
             },
         )
     }
diff --git 
a/src/test/kotlin/com/rustyrazorblade/easycassstress/integration/AllPluginsBasicTest.kt
 
b/src/test/kotlin/com/rustyrazorblade/easycassstress/integration/AllPluginsBasicTest.kt
index 30cf4c6..cc75bf0 100644
--- 
a/src/test/kotlin/com/rustyrazorblade/easycassstress/integration/AllPluginsBasicTest.kt
+++ 
b/src/test/kotlin/com/rustyrazorblade/easycassstress/integration/AllPluginsBasicTest.kt
@@ -34,7 +34,6 @@ annotation class AllPlugins
  */
 class AllPluginsBasicTest : CassandraTestBase() {
     lateinit var run: Run
-    var prometheusPort = 9600
 
     /**
      * Annotate a test with @AllPlugins
@@ -42,7 +41,7 @@ class AllPluginsBasicTest : CassandraTestBase() {
     companion object {
         @JvmStatic
         fun getPlugins() =
-            Plugin.getPlugins().values.filter {
+            Plugin.getPluginsForTesting().values.filter {
                 it.name != "Demo"
             }
     }
@@ -63,11 +62,12 @@ class AllPluginsBasicTest : CassandraTestBase() {
         run.apply {
             host = ip
             profile = plugin.name
-            iterations = 1000
-            rate = 100L
+            iterations = 200
+            rate = 50L
             partitionValues = 1000
-            prometheusPort = prometheusPort++
+            prometheusPort = 0
             threads = 2
+            useOptimizer = false
             replication = "{'class': 'SimpleStrategy', 'replication_factor':1 
}"
             dc = localDc // Use the datacenter from the base class
         }.execute()
diff --git 
a/src/test/kotlin/com/rustyrazorblade/easycassstress/integration/CassandraTestBase.kt
 
b/src/test/kotlin/com/rustyrazorblade/easycassstress/integration/CassandraTestBase.kt
index 3bebd1e..691cfc2 100644
--- 
a/src/test/kotlin/com/rustyrazorblade/easycassstress/integration/CassandraTestBase.kt
+++ 
b/src/test/kotlin/com/rustyrazorblade/easycassstress/integration/CassandraTestBase.kt
@@ -22,12 +22,14 @@ import 
com.datastax.oss.driver.api.core.config.DefaultDriverOption
 import com.datastax.oss.driver.api.core.config.DriverConfigLoader
 import org.junit.jupiter.api.AfterAll
 import org.junit.jupiter.api.BeforeAll
+import org.junit.jupiter.api.TestInstance
 import java.net.InetSocketAddress
 
 /**
  * Base class for Cassandra integration tests
  * Provides common setup logic for connection handling
  */
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
 abstract class CassandraTestBase {
     companion object {
         // Connection parameters with environment variable fallbacks
@@ -43,33 +45,29 @@ abstract class CassandraTestBase {
                 .withString(DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT, 
"30s")
                 
.withString(DefaultDriverOption.CONNECTION_SET_KEYSPACE_TIMEOUT, "10s")
                 .build()
+    }
 
-        // Shared session for all tests
-        val connection = createSession()
+    // Instance-level connection for each test class
+    protected lateinit var connection: CqlSession
 
-        // Initialize the session
-        private fun createSession(): CqlSession {
-            println("Connecting to Cassandra at $ip using datacenter $localDc")
-            return CqlSession.builder()
-                .addContactPoint(InetSocketAddress(ip, 9042))
-                .withLocalDatacenter(localDc)
-                .withConfigLoader(configLoader)
-                .build()
-        }
+    @BeforeAll
+    fun setupClass() {
+        // Create connection for this test class
+        println("Connecting to Cassandra at $ip using datacenter $localDc")
+        connection = CqlSession.builder()
+            .addContactPoint(InetSocketAddress(ip, 9042))
+            .withLocalDatacenter(localDc)
+            .withConfigLoader(configLoader)
+            .build()
 
-        @JvmStatic
-        @BeforeAll
-        fun setupClass() {
-            // Ensure keyspace doesn't exist before tests
-            connection.execute("DROP KEYSPACE IF EXISTS easy_cass_stress")
-        }
+        // Ensure keyspace doesn't exist before tests
+        connection.execute("DROP KEYSPACE IF EXISTS easy_cass_stress")
+    }
 
-        @JvmStatic
-        @AfterAll
-        fun teardownClass() {
-            // Clean up resources after tests
-            connection.close()
-        }
+    @AfterAll
+    fun teardownClass() {
+        // Clean up resources after tests
+        connection.close()
     }
 
     // Cleanup before each test case
diff --git 
a/src/test/kotlin/com/rustyrazorblade/easycassstress/integration/FlagsTest.kt 
b/src/test/kotlin/com/rustyrazorblade/easycassstress/integration/FlagsTest.kt
index 15e2c75..00855dd 100644
--- 
a/src/test/kotlin/com/rustyrazorblade/easycassstress/integration/FlagsTest.kt
+++ 
b/src/test/kotlin/com/rustyrazorblade/easycassstress/integration/FlagsTest.kt
@@ -36,6 +36,8 @@ class FlagsTest : CassandraTestBase() {
                 iterations = 100
                 host = ip
                 dc = localDc
+                useOptimizer = false
+                prometheusPort = 0
                 replication = "{'class': 'SimpleStrategy', 
'replication_factor':1 }"
             }
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to