diff --git a/pom.xml b/pom.xml index add9853..ad5b812 100644 --- a/pom.xml +++ b/pom.xml @@ -263,4 +263,4 @@ https://oss.sonatype.org/service/local/staging/deploy/maven2/ - \ No newline at end of file + diff --git a/src/main/java/org/testcontainers/containers/TarantoolCartridgeContainer.java b/src/main/java/org/testcontainers/containers/TarantoolCartridgeContainer.java index c2c82f6..86e39ef 100644 --- a/src/main/java/org/testcontainers/containers/TarantoolCartridgeContainer.java +++ b/src/main/java/org/testcontainers/containers/TarantoolCartridgeContainer.java @@ -102,8 +102,9 @@ public class TarantoolCartridgeContainer extends GenericContainer image, String instancesFile, String topologyConfigurationFile) { super(image); if (instancesFile == null || instancesFile.isEmpty()) { throw new IllegalArgumentException("Instance file name must not be null or empty"); } + if (topologyConfigurationFile == null || topologyConfigurationFile.isEmpty()) { + throw new IllegalArgumentException("Topology configuration file must not be null or empty"); + } + String fileType = topologyConfigurationFile.substring(topologyConfigurationFile.lastIndexOf('.') + 1); + if (fileType.equals("lua")) { + this.topologyConfigurationFile = topologyConfigurationFile; + }else{ + this.replicasetsFileName = topologyConfigurationFile.substring(topologyConfigurationFile.lastIndexOf('/')+1); + } this.instanceFileParser = new CartridgeConfigParser(instancesFile); - this.topologyConfigurationFile = topologyConfigurationFile; this.clientHelper = new TarantoolContainerClientHelper(this); } @@ -435,7 +443,6 @@ protected void configure() { if (!getDirectoryBinding().isEmpty()) { withFileSystemBind(getDirectoryBinding(), getInstanceDir(), BindMode.READ_WRITE); } - if (useFixedPorts) { for (Integer port : instanceFileParser.getExposablePorts()) { addFixedExposedPort(port, port); @@ -451,21 +458,55 @@ protected void containerIsStarting(InspectContainerResponse containerInfo) { } private boolean setupTopology() { - try { - executeScript(topologyConfigurationFile).get(); - // The client connection will be closed after that command - } catch (Exception e) { - if (e instanceof ExecutionException) { - if (e.getCause() instanceof TimeoutException) { - return true; - // Do nothing, the cluster is reloading - } else if (e.getCause() instanceof TarantoolConnectionException) { - // Probably cluster is not ready - logger().error("Failed to setup topology: {}", e.getMessage()); - return false; + if (topologyConfigurationFile == null) { + String runDirPath = null; + try { + Container.ExecResult envVariablesContainer = this.execInContainer("env"); + String stdout = envVariablesContainer.getStdout(); + int exitCode = envVariablesContainer.getExitCode(); + if (exitCode != 0) { + logger().error("Failed to bootstrap replica sets topology: {}", stdout); + } + int startInd = stdout.lastIndexOf(ENV_TARANTOOL_RUNDIR + "="); + try { + runDirPath = stdout.substring(startInd, + stdout.indexOf('\n', startInd)).split("=")[1]; + } catch (Exception e) { + logger().error("Missing dir-run environment variable: {}", e.getMessage()); + } + + } catch (Exception e) { + logger().error("Failed to get environment variables: {}", e.getMessage()); + } + + try { + Container.ExecResult lsResult = this.execInContainer("cartridge", "replicasets", "--run-dir=" + runDirPath, + "--file=" + this.replicasetsFileName, "setup", "--bootstrap-vshard"); + String stdout = lsResult.getStdout(); + int exitCode = lsResult.getExitCode(); + if (exitCode != 0) { + logger().error("Failed to bootstrap replica sets topology: {}", stdout); + } + } catch (Exception e) { + logger().error("Failed to bootstrap replica sets topology: {}", e.getMessage()); + } + } else { + try { + executeScript(topologyConfigurationFile).get(); + // The client connection will be closed after that command + } catch (Exception e) { + if (e instanceof ExecutionException) { + if (e.getCause() instanceof TimeoutException) { + return true; + // Do nothing, the cluster is reloading + } else if (e.getCause() instanceof TarantoolConnectionException) { + // Probably cluster is not ready + logger().error("Failed to setup topology: {}", e.getMessage()); + return false; + } + } else { + throw new RuntimeException("Failed to change the app topology", e); } - } else { - throw new RuntimeException("Failed to change the app topology", e); } } return true; diff --git a/src/test/java/org/testcontainers/containers/TarantoolCartridgeContainerReplicasetsTest.java b/src/test/java/org/testcontainers/containers/TarantoolCartridgeContainerReplicasetsTest.java new file mode 100644 index 0000000..aa03637 --- /dev/null +++ b/src/test/java/org/testcontainers/containers/TarantoolCartridgeContainerReplicasetsTest.java @@ -0,0 +1,42 @@ +package org.testcontainers.containers; + +import org.junit.jupiter.api.Test; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.output.Slf4jLogConsumer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.utility.MountableFile; + +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; + +public class TarantoolCartridgeContainerReplicasetsTest { + + @Test + public void test_ClusterContainer_StartsSuccessfully_ifFilesAreCopiedUnderRoot() throws Exception { + Map buildArgs = new HashMap() { + { + put("TARANTOOL_SERVER_USER", "root"); + put("TARANTOOL_SERVER_UID", "0"); + put("TARANTOOL_SERVER_GROUP", "root"); + put("TARANTOOL_SERVER_GID", "0"); + } + }; + TarantoolCartridgeContainer container = + new TarantoolCartridgeContainer( + "Dockerfile", + "testcontainers-java-tarantool:test", + "cartridge/instances.yml", + "cartridge/replicasets.yml", + buildArgs) + .withCopyFileToContainer(MountableFile.forClasspathResource("cartridge"), "/app") + .withStartupTimeout(Duration.ofSeconds(300)) + .withLogConsumer(new Slf4jLogConsumer( + LoggerFactory.getLogger(TarantoolCartridgeContainerReplicasetsTest.class))); + + container.start(); + CartridgeContainerTestUtils.executeProfileReplaceSmokeTest(container); + if(container.isRunning()) + container.stop(); + } +} diff --git a/src/test/resources/cartridge/replicasets.yml b/src/test/resources/cartridge/replicasets.yml new file mode 100644 index 0000000..18fcb20 --- /dev/null +++ b/src/test/resources/cartridge/replicasets.yml @@ -0,0 +1,18 @@ +router: + instances: + - router + roles: + - failover-coordinator + - vshard-router + - app.roles.custom + - app.roles.api_router + all_rw: false +s-1: + instances: + - s1-master + roles: + - vshard-storage + - app.roles.api_storage + weight: 1 + all_rw: false + vshard_group: default