From 05c482491db278266aa2b19721ffcb50d5c5b9d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20B=C4=85czkowski?= <36934780+Bouncheck@users.noreply.github.com> Date: Thu, 12 Dec 2024 13:09:52 +0100 Subject: [PATCH] Allow additional `scylla.version` formats (#396) Modifies version parsing logic to try passing the `scylla.version` to the CCM when it can't be parsed as VersionNumber. If CCM manages to run `create` with it, then the usual version number is fetched from `ccm node versionfrombuild` output. To do that we introduce a static version of `execute`. The method body is nearly the same. Functionally should be the same. Previous version now calls the static one. --- .../com/datastax/driver/core/CCMBridge.java | 56 +++++++++++++++++-- .../driver/core/DnsEndpointTests.java | 6 +- 2 files changed, 53 insertions(+), 9 deletions(-) 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 dc9b807c023..00a608171d8 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 @@ -194,6 +194,7 @@ public class CCMBridge implements CCMAccess { static { String inputCassandraVersion = System.getProperty("cassandra.version"); String inputScyllaVersion = System.getProperty("scylla.version"); + GLOBAL_SCYLLA_VERSION_NUMBER = parseScyllaInputVersion(inputScyllaVersion); String installDirectory = System.getProperty("cassandra.directory"); String branch = System.getProperty("cassandra.branch"); @@ -206,8 +207,11 @@ public class CCMBridge implements CCMAccess { installArgs.add("-v git:" + branch.trim().replaceAll("\"", "")); } else if (inputScyllaVersion != null && !inputScyllaVersion.trim().isEmpty()) { installArgs.add(" --scylla "); - installArgs.add("-v release:" + inputScyllaVersion); - + if (isVersionNumber(inputScyllaVersion)) { + installArgs.add("-v release:" + inputScyllaVersion); + } else { + installArgs.add("-v " + inputScyllaVersion); + } // Detect Scylla Enterprise - it should start with // a 4-digit year. if (inputScyllaVersion.matches("\\d{4}\\..*")) { @@ -246,8 +250,6 @@ public class CCMBridge implements CCMAccess { } ENVIRONMENT_MAP = ImmutableMap.copyOf(envMap); - GLOBAL_SCYLLA_VERSION_NUMBER = VersionNumber.parse(inputScyllaVersion); - if (isDse()) { GLOBAL_DSE_VERSION_NUMBER = VersionNumber.parse(inputCassandraVersion); GLOBAL_CASSANDRA_VERSION_NUMBER = CCMBridge.getCassandraVersion(GLOBAL_DSE_VERSION_NUMBER); @@ -338,6 +340,28 @@ public static boolean isWindows() { return osName != null && osName.startsWith("Windows"); } + private static boolean isVersionNumber(String versionString) { + try { + VersionNumber.parse(versionString); + } catch (IllegalArgumentException e) { + return false; + } + return true; + } + + private static VersionNumber parseScyllaInputVersion(String versionString) { + VersionNumber parsedScyllaVersionNumber = null; + try { + parsedScyllaVersionNumber = VersionNumber.parse(versionString); + } catch (IllegalArgumentException e) { + logger.warn( + "Failed to parse scylla.version: " + versionString + ". Trying to get it through CCM.", + e); + parsedScyllaVersionNumber = getScyllaVersionThroughCcm(versionString); + } + return parsedScyllaVersionNumber; + } + private final String clusterName; private final VersionNumber cassandraVersion; @@ -792,7 +816,25 @@ public void setWorkload(int node, Workload... workload) { execute(CCM_COMMAND + " node%d setworkload %s", node, workloadStr); } - private String execute(String command, Object... args) { + private static VersionNumber getScyllaVersionThroughCcm(String versionString) { + File configDir = Files.createTempDir(); + try { + execute(configDir, "ccm create get_version -n 1 --scylla --version %s", versionString); + String versionOutput = execute(configDir, "ccm node1 versionfrombuild"); + return VersionNumber.parse(versionOutput.replace("ccmout> ", "").trim()); + } catch (RuntimeException cause) { + throw new RuntimeException( + "Error during getting Scylla version through ccm commands.", cause); + } finally { + try { + execute(configDir, "ccm remove get_version"); + } catch (Exception ignored) { + } + } + } + + private static String execute(File ccmDir, String command, Object... args) { + Logger logger = CCMBridge.logger; String fullCommand = String.format(command, args) + " --config-dir=" + ccmDir; Closer closer = Closer.create(); // 10 minutes timeout @@ -856,6 +898,10 @@ protected void processLine(String line, int logLevel) { return sw.toString(); } + private String execute(String command, Object... args) { + return execute(this.ccmDir, command, args); + } + /** * Waits for a host to be up by pinging the TCP socket directly, without using the Java driver's * API. diff --git a/driver-core/src/test/java/com/datastax/driver/core/DnsEndpointTests.java b/driver-core/src/test/java/com/datastax/driver/core/DnsEndpointTests.java index 150f7a3a2dc..255f8daf8c4 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/DnsEndpointTests.java +++ b/driver-core/src/test/java/com/datastax/driver/core/DnsEndpointTests.java @@ -47,8 +47,7 @@ public void replace_cluster_test() { logger.info("Queried node has broadcast_address: {}}", address); System.out.flush(); } finally { - assert bridgeA != null; - bridgeA.close(); + if (bridgeA != null) bridgeA.close(); } CCMBridge bridgeB = null; @@ -72,8 +71,7 @@ public void replace_cluster_test() { } catch (InterruptedException e) { throw new RuntimeException(e); } finally { - assert bridgeB != null; - bridgeB.close(); + if (bridgeB != null) bridgeB.close(); } }