Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,11 @@
target/
.idea/
*.iml
.classpath
.project
.settings/
*.swp
workbench.xmi


src/test/resources/cartridge/tmp/*
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## [Unreleased]

- Bump testcontainers to 1.19.3

## [1.0.2] - 2023-11-10

- Make a separate step for building the cartridge ([#94](https://github.com/tarantool/testcontainers-java-tarantool/issues/94))
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
</scm>

<properties>
<testcontainers.version>1.18.0</testcontainers.version>
<testcontainers.version>1.19.3</testcontainers.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<logging.config>${project.basedir}/src/test/resources/logback-test.xml</logging.config>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public class TarantoolCartridgeContainer extends GenericContainer<TarantoolCartr
private static final String ENV_TARANTOOL_DATADIR = "TARANTOOL_DATADIR";
private static final String ENV_TARANTOOL_INSTANCES_FILE = "TARANTOOL_INSTANCES_FILE";
private static final String ENV_TARANTOOL_CLUSTER_COOKIE = "TARANTOOL_CLUSTER_COOKIE";
private static final String healthyCmd = "return require('cartridge').is_healthy()";

private final CartridgeConfigParser instanceFileParser;
private final TarantoolContainerClientHelper clientHelper;
Expand All @@ -120,6 +121,7 @@ public class TarantoolCartridgeContainer extends GenericContainer<TarantoolCartr
private String directoryResourcePath = SCRIPT_RESOURCE_DIRECTORY;
private String instanceDir = INSTANCE_DIR;
private String topologyConfigurationFile;
private String instancesFile;
private SslContext sslContext;

/**
Expand Down Expand Up @@ -205,6 +207,7 @@ private TarantoolCartridgeContainer(ImageFromDockerfile image, String instancesF
if (topologyConfigurationFile == null || topologyConfigurationFile.isEmpty()) {
throw new IllegalArgumentException("Topology configuration file must not be null or empty");
}
this.instancesFile = instancesFile;
this.topologyConfigurationFile = topologyConfigurationFile;
this.instanceFileParser = new CartridgeConfigParser(instancesFile);
this.clientHelper = new TarantoolContainerClientHelper(this);
Expand Down Expand Up @@ -494,17 +497,23 @@ protected void containerIsStarting(InspectContainerResponse containerInfo) {
}

private boolean setupTopology() {
String fileType = topologyConfigurationFile.substring(topologyConfigurationFile.lastIndexOf('.') + 1);

String fileType = topologyConfigurationFile
.substring(topologyConfigurationFile.lastIndexOf('.') + 1);
if (fileType.equals("yml")) {
String replicasetsFileName = topologyConfigurationFile
.substring(topologyConfigurationFile.lastIndexOf('/') + 1);

.substring(topologyConfigurationFile.lastIndexOf('/') + 1);
String instancesFileName = instancesFile
.substring(instancesFile.lastIndexOf('/') + 1);
try {
ExecResult result = execInContainer("cartridge",
"replicasets",
"--run-dir=" + TARANTOOL_RUN_DIR,
"--file=" + replicasetsFileName, "setup", "--bootstrap-vshard");
ExecResult result = execInContainer(
"cartridge",
"replicasets",
"--run-dir=" + TARANTOOL_RUN_DIR,
"--file=" + replicasetsFileName,
"--cfg=" + instancesFileName,
"setup",
"--bootstrap-vshard"
);
if (result.getExitCode() != 0) {
throw new CartridgeTopologyException("Failed to change the app topology via cartridge CLI: "
+ result.getStdout());
Expand Down Expand Up @@ -540,7 +549,7 @@ private void retryingSetupTopology() {
if (!setupTopology()) {
try {
logger().info("Retrying setup topology in 10 seconds");
Thread.sleep(10000);
Thread.sleep(1_000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
Expand All @@ -562,11 +571,12 @@ private void bootstrapVshard() {
@Override
protected void containerIsStarted(InspectContainerResponse containerInfo, boolean reused) {
super.containerIsStarted(containerInfo, reused);
int secondsToWait = 120;

waitUntilRouterIsUp(60);
waitUntilRouterIsUp(secondsToWait);
retryingSetupTopology();
// wait until Roles are configured
waitUntilCartridgeIsHealthy(10);
waitUntilCartridgeIsHealthy(secondsToWait);
bootstrapVshard();

logger().info("Tarantool Cartridge cluster is started");
Expand All @@ -575,49 +585,74 @@ protected void containerIsStarted(InspectContainerResponse containerInfo, boolea
}

private void waitUntilRouterIsUp(int secondsToWait) {
waitUntilTrue(secondsToWait, this::routerIsUp);
if(!waitUntilTrue(secondsToWait, this::routerIsUp)) {
throw new RuntimeException("Timeout exceeded during router starting stage." +
" See the specific error in logs.");
}
}

private void waitUntilCartridgeIsHealthy(int secondsToWait) {
waitUntilTrue(secondsToWait, this::isCartridgeHealthy);
if(!waitUntilTrue(secondsToWait, this::isCartridgeHealthy)) {
throw new RuntimeException("Timeout exceeded during cartridge topology applying stage." +
" See the specific error in logs.");
}
}

private void waitUntilTrue(int secondsToWait, Supplier<Boolean> waitFunc) {
private boolean waitUntilTrue(int secondsToWait, Supplier<Boolean> waitFunc) {
int secondsPassed = 0;
boolean result = waitFunc.get();
while (!result && secondsPassed < secondsToWait) {
result = waitFunc.get();
try {
Thread.sleep(1000);
Thread.sleep(1_000);
secondsPassed++;
} catch (InterruptedException e) {
break;
}
}
if (!result) {
throw new RuntimeException("Failed to change the app topology after retry");
}
return result;
}

private boolean routerIsUp() {
String healthyCmd = " local cartridge = package.loaded['cartridge']" +
" return cartridge ~= nil";
ExecResult result;
try {
List<?> result = executeCommandDecoded(healthyCmd);
return result.get(0).getClass() == Boolean.class && (Boolean) result.get(0);
} catch (Exception e) {
logger().warn("Error while waiting for router instance to be up: " + e.getMessage());
result = executeCommand(healthyCmd);
if (result.getExitCode() != 0 && result.getStderr().contains("Connection refused") &&
result.getStdout().isEmpty()) {
return false;
} else if (result.getExitCode() != 0) {
logger().error("exit code: {}, stdout: {}, stderr: {}",result.getExitCode(), result.getStdout(),
result.getStderr());
return false;
} else {
return true;
}
}catch (Exception e) {
logger().error(e.getMessage());
return false;
}

}

private boolean isCartridgeHealthy() {
String healthyCmd = " local cartridge = package.loaded['cartridge']" +
" return cartridge ~= nil and cartridge.is_healthy()";
ExecResult result;
try {
List<?> result = executeCommandDecoded(healthyCmd);
return result.get(0).getClass() == Boolean.class && (Boolean) result.get(0);
result = executeCommand(healthyCmd);
if (result.getExitCode() != 0) {
logger().error("exitCode: {}, stdout: {}, stderr: {}", result.getExitCode(), result.getStdout(),
result.getStderr());
return false;
} else if (result.getStdout().startsWith("---\n- null\n")){
return false;
} else if (result.getStdout().contains("true")) {
return true;
} else {
logger().warn("exitCode: {}, stdout: {}, stderr: {}", result.getExitCode(), result.getStdout(),
result.getStderr());
return false;
}
} catch (Exception e) {
logger().warn("Error while waiting for cartridge healthy state: " + e.getMessage());
logger().error("Error while waiting for cartridge healthy state: " + e.getMessage());
return false;
}
}
Expand Down
7 changes: 5 additions & 2 deletions src/main/resources/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ ARG TARANTOOL_DATADIR="/tmp/data"
ARG TARANTOOL_LOGDIR="/tmp/log"
ARG TARANTOOL_INSTANCES_FILE="./instances.yml"
ARG TARANTOOL_CLUSTER_COOKIE="testapp-cluster-cookie"
ARG START_DELAY="5s"
ENV START_DELAY=$START_DELAY
ENV TARANTOOL_WORKDIR=$TARANTOOL_WORKDIR
ENV TARANTOOL_RUNDIR=$TARANTOOL_RUNDIR
ENV TARANTOOL_DATADIR=$TARANTOOL_DATADIR
Expand All @@ -31,6 +33,7 @@ ENV TARANTOOL_INSTANCES_FILE=$TARANTOOL_INSTANCES_FILE
ENV TARANTOOL_CLUSTER_COOKIE=$TARANTOOL_CLUSTER_COOKIE
COPY $CARTRIDGE_SRC_DIR $TARANTOOL_WORKDIR
WORKDIR $TARANTOOL_WORKDIR
RUN cartridge build
CMD cartridge start --run-dir=$TARANTOOL_RUNDIR --data-dir=$TARANTOOL_DATADIR \

RUN rm -rf .rocks && cartridge build --verbose
CMD sleep $START_DELAY && cartridge start --run-dir=$TARANTOOL_RUNDIR --data-dir=$TARANTOOL_DATADIR \
--log-dir=$TARANTOOL_LOGDIR --cfg=$TARANTOOL_INSTANCES_FILE