From db9921026d894cb1feb3617f86ac2f7105d307d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20B=C4=85czkowski?= Date: Mon, 20 Jan 2025 15:12:04 +0100 Subject: [PATCH 1/2] Expose Scylla version through CCM interfaces Adds `getScyllaVersion()` to CCMAccess, CCMCache, ReadOnlyCCMAccess. Adds `scyllaVersion` field to CCMBridge.Builder class. Some tests for Scylla and Cassandra have very high code overlap. This change will make it possible to adjust a few lines in a method instead of repeating a whole test method with different cluster version requirement. --- .../com/datastax/driver/core/CCMAccess.java | 7 +++++ .../com/datastax/driver/core/CCMBridge.java | 31 +++++++++++++++++-- .../com/datastax/driver/core/CCMCache.java | 5 +++ .../datastax/driver/core/CCMTestsSupport.java | 5 +++ 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/driver-core/src/test/java/com/datastax/driver/core/CCMAccess.java b/driver-core/src/test/java/com/datastax/driver/core/CCMAccess.java index b6714f07fee..8a91c6fb1c1 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/CCMAccess.java +++ b/driver-core/src/test/java/com/datastax/driver/core/CCMAccess.java @@ -54,6 +54,13 @@ enum Workload { */ VersionNumber getDSEVersion(); + /** + * Returns the Scylla version of this CCM cluster if this is a Scylla cluster, otherwise null. + * + * @return The version of this CCM cluster. + */ + VersionNumber getScyllaVersion(); + /** @return The config directory for this CCM cluster. */ File getCcmDir(); diff --git a/driver-core/src/test/java/com/datastax/driver/core/CCMBridge.java b/driver-core/src/test/java/com/datastax/driver/core/CCMBridge.java index 00a608171d8..62f674a8852 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/CCMBridge.java +++ b/driver-core/src/test/java/com/datastax/driver/core/CCMBridge.java @@ -368,6 +368,8 @@ private static VersionNumber parseScyllaInputVersion(String versionString) { private final VersionNumber dseVersion; + private final VersionNumber scyllaVersion; + private final int storagePort; private final int thriftPort; @@ -402,6 +404,7 @@ protected CCMBridge( String clusterName, VersionNumber cassandraVersion, VersionNumber dseVersion, + VersionNumber scyllaVersion, String ipPrefix, int storagePort, int thriftPort, @@ -415,6 +418,7 @@ protected CCMBridge( this.clusterName = clusterName; this.cassandraVersion = cassandraVersion; this.dseVersion = dseVersion; + this.scyllaVersion = scyllaVersion; this.ipPrefix = ipPrefix; this.storagePort = storagePort; this.thriftPort = thriftPort; @@ -489,6 +493,11 @@ public VersionNumber getDSEVersion() { return dseVersion; } + @Override + public VersionNumber getScyllaVersion() { + return scyllaVersion; + } + @Override public File getCcmDir() { return ccmDir; @@ -1000,6 +1009,7 @@ public static class Builder { private int[] jmxPorts = {}; private boolean start = true; private boolean dse = isDse(); + private boolean scylla = GLOBAL_SCYLLA_VERSION_NUMBER != null; private boolean startSniProxy = false; private VersionNumber version = null; private final Set createOptions = new LinkedHashSet(); @@ -1091,8 +1101,8 @@ public Builder notStarted() { } /** - * The Cassandra or DSE version to use. If not specified the globally configured version is used - * instead. + * The Cassandra or DSE or Scylla version to use. If not specified the globally configured + * version is used instead. */ public Builder withVersion(VersionNumber version) { this.version = version; @@ -1105,6 +1115,12 @@ public Builder withDSE(boolean dse) { return this; } + /** Indicates whether or not this cluster is meant to be a Scylla cluster. */ + public Builder withScylla(boolean scylla) { + this.scylla = scylla; + return this; + } + /** * Free-form options that will be added at the end of the {@code ccm create} command (defaults * to {@link #CASSANDRA_INSTALL_ARGS} if this is never called). @@ -1175,17 +1191,26 @@ public CCMBridge build() { VersionNumber dseVersion; VersionNumber cassandraVersion; + VersionNumber scyllaVersion; boolean versionConfigured = this.version != null; // No version was explicitly provided, fallback on global config. if (!versionConfigured) { + scyllaVersion = GLOBAL_SCYLLA_VERSION_NUMBER; dseVersion = GLOBAL_DSE_VERSION_NUMBER; cassandraVersion = GLOBAL_CASSANDRA_VERSION_NUMBER; } else if (dse) { // given version is the DSE version, base cassandra version on DSE version. + scyllaVersion = null; dseVersion = this.version; cassandraVersion = getCassandraVersion(dseVersion); + } else if (scylla) { + scyllaVersion = this.version; + dseVersion = null; + // Versions from 5.1 to 6.2.0 seem to report release_version 3.0.8 in system_local + cassandraVersion = VersionNumber.parse("3.0.8"); } else { // given version is cassandra version. + scyllaVersion = null; dseVersion = null; cassandraVersion = this.version; } @@ -1240,6 +1265,7 @@ public CCMBridge build() { clusterName, cassandraVersion, dseVersion, + scyllaVersion, ipPrefix, storagePort, thriftPort, @@ -1449,6 +1475,7 @@ public boolean equals(Object o) { if (ipPrefix != builder.ipPrefix) return false; if (dse != builder.dse) return false; + if (scylla != builder.scylla) return false; if (!Arrays.equals(nodes, builder.nodes)) return false; if (version != null ? !version.equals(builder.version) : builder.version != null) return false; diff --git a/driver-core/src/test/java/com/datastax/driver/core/CCMCache.java b/driver-core/src/test/java/com/datastax/driver/core/CCMCache.java index 3329073555d..254e2cae12c 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/CCMCache.java +++ b/driver-core/src/test/java/com/datastax/driver/core/CCMCache.java @@ -64,6 +64,11 @@ public VersionNumber getDSEVersion() { return ccm.getDSEVersion(); } + @Override + public VersionNumber getScyllaVersion() { + return ccm.getScyllaVersion(); + } + @Override public File getCcmDir() { return ccm.getCcmDir(); diff --git a/driver-core/src/test/java/com/datastax/driver/core/CCMTestsSupport.java b/driver-core/src/test/java/com/datastax/driver/core/CCMTestsSupport.java index b390eed9f70..ee2aaceb06a 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/CCMTestsSupport.java +++ b/driver-core/src/test/java/com/datastax/driver/core/CCMTestsSupport.java @@ -110,6 +110,11 @@ public VersionNumber getDSEVersion() { return delegate.getDSEVersion(); } + @Override + public VersionNumber getScyllaVersion() { + return delegate.getScyllaVersion(); + } + @Override public InetSocketAddress addressOfNode(int n) { return delegate.addressOfNode(n); From d4cb04806d1f3df2f7418ddbcbbd40ff68284477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20B=C4=85czkowski?= Date: Mon, 20 Jan 2025 15:31:10 +0100 Subject: [PATCH 2/2] Adjust StateListenerTest In newer Scylla versions ccm node decomission first causes DOWN event to be sent and then REMOVE. This change adjusts the expected event so that the test passes. --- .../com/datastax/driver/core/StateListenerTest.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/driver-core/src/test/java/com/datastax/driver/core/StateListenerTest.java b/driver-core/src/test/java/com/datastax/driver/core/StateListenerTest.java index eb77f2bf2ca..ab574d8a4f4 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/StateListenerTest.java +++ b/driver-core/src/test/java/com/datastax/driver/core/StateListenerTest.java @@ -52,7 +52,15 @@ public void should_receive_events_when_node_states_change() throws InterruptedEx ccm().start(1); listener.waitForEvent(); - listener.setExpectedEvent(REMOVE); + // Different expectation for Scylla versions since 6.0.0 and 2024.2, both included + VersionNumber scyllaVer = ccm().getScyllaVersion(); + if (scyllaVer != null + && ((scyllaVer.getMajor() >= 6 && scyllaVer.getMajor() <= 9) + || (scyllaVer.getMajor() >= 2024 && scyllaVer.getMinor() >= 2))) { + listener.setExpectedEvent(DOWN); + } else { + listener.setExpectedEvent(REMOVE); + } ccm().decommission(2); listener.waitForEvent(); }