Skip to content

Commit e604c7c

Browse files
committed
Allow arbitrary Scylla versions in CcmBridge
Until now, the versions passed through `ccm.version` property would be considered invalid if cannot be parsed to one of the known formats. Now if the parsing fails, the property will be passed to ccm commands 'as is' which ccm will treat as directory name in local repository. Numbered version then will be fetched through setting up a makeshift cluster and asking ccm for it.
1 parent 492a4c9 commit e604c7c

File tree

1 file changed

+70
-11
lines changed
  • test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm

1 file changed

+70
-11
lines changed

test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/CcmBridge.java

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import java.io.FileOutputStream;
3333
import java.io.IOException;
3434
import java.io.OutputStream;
35+
import java.io.PrintWriter;
36+
import java.io.StringWriter;
3537
import java.nio.file.Files;
3638
import java.nio.file.Path;
3739
import java.util.ArrayList;
@@ -61,17 +63,18 @@ public class CcmBridge implements AutoCloseable {
6163

6264
private static final Logger LOG = LoggerFactory.getLogger(CcmBridge.class);
6365

64-
public static final Version VERSION =
65-
Objects.requireNonNull(Version.parse(System.getProperty("ccm.version", "4.0.0")));
66+
public static final Boolean SCYLLA_ENABLEMENT = Boolean.getBoolean("ccm.scylla");
67+
68+
public static final String CCM_VERSION_PROPERTY = System.getProperty("ccm.version", "4.0.0");
69+
70+
public static final Version VERSION = Objects.requireNonNull(parseCcmVersion());
6671

6772
public static final String INSTALL_DIRECTORY = System.getProperty("ccm.directory");
6873

6974
public static final String BRANCH = System.getProperty("ccm.branch");
7075

7176
public static final Boolean DSE_ENABLEMENT = Boolean.getBoolean("ccm.dse");
7277

73-
public static final Boolean SCYLLA_ENABLEMENT = Boolean.getBoolean("ccm.scylla");
74-
7578
public static final Boolean SCYLLA_ENTERPRISE =
7679
String.valueOf(VERSION.getMajor()).matches("\\d{4}");
7780

@@ -232,6 +235,45 @@ private static boolean isWindows() {
232235
return System.getProperty("os.name", "").toLowerCase(Locale.US).contains("win");
233236
}
234237

238+
private static Version parseCcmVersion() {
239+
String versionString = CCM_VERSION_PROPERTY;
240+
Version result = null;
241+
try {
242+
result = Version.parse(versionString);
243+
return result;
244+
} catch (IllegalArgumentException ex) {
245+
LOG.warn(
246+
"Failed to parse ccm.version property \'{}\' as Version instance. Attempting to fetch it through \'ccm node versionfrombuild\'",
247+
versionString);
248+
}
249+
Path configDir = null;
250+
try {
251+
configDir = Files.createTempDirectory("ccmParseVer");
252+
configDir.toFile().deleteOnExit();
253+
execute(
254+
CommandLine.parse(
255+
String.format(
256+
"ccm create get_version -n 1 %s --version %s --config-dir=%s",
257+
(SCYLLA_ENABLEMENT ? "--scylla" : " "), versionString, configDir)));
258+
String output =
259+
execute(
260+
CommandLine.parse(
261+
String.format("ccm node1 versionfrombuild --config-dir=%s", configDir)));
262+
result = Version.parse(output.trim());
263+
LOG.info("Cluster reports that {} corresponds to version {}", versionString, result);
264+
} catch (IOException e) {
265+
throw new RuntimeException(e);
266+
} finally {
267+
try {
268+
if (configDir != null) {
269+
execute(CommandLine.parse("ccm remove get_version --config-dir=" + configDir));
270+
}
271+
} catch (Exception ignored) {
272+
}
273+
}
274+
return result;
275+
}
276+
235277
public Optional<Version> getScyllaVersion() {
236278
return SCYLLA_ENABLEMENT ? Optional.of(VERSION) : Optional.empty();
237279
}
@@ -264,7 +306,15 @@ public Version getCassandraVersion() {
264306
}
265307
}
266308

267-
private String getCcmVersionString(Version version) {
309+
private String getCcmVersionString(String propertyString) {
310+
Version version = null;
311+
try {
312+
version = Version.parse(propertyString);
313+
} catch (IllegalArgumentException ex) {
314+
// In case it's not a recognized version pattern, use raw string.
315+
// If parseCcmVersion has not failed execution it should be usable.
316+
return propertyString;
317+
}
268318
if (SCYLLA_ENABLEMENT) {
269319
// Scylla OSS versions before 5.1 had RC versioning scheme of 5.0.rc3.
270320
// Scylla OSS versions after (and including 5.1) have RC versioning of 5.1.0-rc3.
@@ -307,7 +357,7 @@ public void create() {
307357
createOptions.add("-v git:" + BRANCH.trim().replaceAll("\"", ""));
308358

309359
} else {
310-
createOptions.add("-v " + getCcmVersionString(VERSION));
360+
createOptions.add("-v " + getCcmVersionString(CCM_VERSION_PROPERTY));
311361
}
312362
if (DSE_ENABLEMENT) {
313363
createOptions.add("--dse");
@@ -497,21 +547,26 @@ private void executeCheckLogError() {
497547
execute(CommandLine.parse(command));
498548
}
499549

500-
private void execute(CommandLine cli) {
501-
LOG.info("Executing: " + cli);
550+
private static String execute(CommandLine cli) {
551+
Logger logger = CcmBridge.LOG;
552+
logger.info("Executing: " + cli);
502553
ExecuteWatchdog watchDog = new ExecuteWatchdog(TimeUnit.MINUTES.toMillis(10));
554+
StringWriter sw = new StringWriter();
555+
final PrintWriter pw = new PrintWriter(sw);
503556
try (LogOutputStream outStream =
504557
new LogOutputStream() {
505558
@Override
506559
protected void processLine(String line, int logLevel) {
507-
LOG.info("ccmout> {}", line);
560+
logger.info("ccmout> {}", line);
561+
pw.println(line);
508562
}
509563
};
510564
LogOutputStream errStream =
511565
new LogOutputStream() {
512566
@Override
513567
protected void processLine(String line, int logLevel) {
514-
LOG.error("ccmerr> {}", line);
568+
logger.error("ccmerr> {}", line);
569+
pw.println(line);
515570
}
516571
}) {
517572
Executor executor = new DefaultExecutor();
@@ -521,15 +576,19 @@ protected void processLine(String line, int logLevel) {
521576

522577
int retValue = executor.execute(cli, ENVIRONMENT_MAP);
523578
if (retValue != 0) {
524-
LOG.error("Non-zero exit code ({}) returned from executing ccm command: {}", retValue, cli);
579+
logger.error(
580+
"Non-zero exit code ({}) returned from executing ccm command: {}", retValue, cli);
525581
}
526582
} catch (IOException ex) {
527583
if (watchDog.killedProcess()) {
528584
throw new RuntimeException("The command '" + cli + "' was killed after 10 minutes");
529585
} else {
530586
throw new RuntimeException("The command '" + cli + "' failed to execute", ex);
531587
}
588+
} finally {
589+
pw.close();
532590
}
591+
return sw.toString();
533592
}
534593

535594
@Override

0 commit comments

Comments
 (0)