Skip to content

Commit 56da7f3

Browse files
committed
Fix problem if topology isn't applied correctly
1 parent dda7e9c commit 56da7f3

8 files changed

+109
-9
lines changed

src/main/java/org/testcontainers/containers/TarantoolCartridgeContainer.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import com.github.dockerjava.api.command.InspectContainerResponse;
44
import io.tarantool.driver.exceptions.TarantoolConnectionException;
5+
6+
import org.testcontainers.containers.exceptions.CartridgeTopologyException;
57
import org.testcontainers.images.builder.ImageFromDockerfile;
68

79
import java.net.URL;
@@ -478,16 +480,21 @@ private boolean setupTopology() {
478480
"--run-dir=" + TARANTOOL_RUN_DIR,
479481
"--file=" + replicasetsFileName, "setup", "--bootstrap-vshard");
480482
if (result.getExitCode() != 0) {
481-
throw new RuntimeException("Failed to change the app topology via cartridge CLI: "
482-
+ result.getStdout());
483+
throw new CartridgeTopologyException("Failed to change the app topology via cartridge CLI: "
484+
+ result.getStdout());
483485
}
484486
} catch (Exception e) {
485-
throw new RuntimeException("Failed to change the app topology: " + e.getMessage());
487+
throw new CartridgeTopologyException(e);
486488
}
487489

488490
} else {
489491
try {
490-
executeScript(topologyConfigurationFile).get();
492+
List<?> res = executeScript(topologyConfigurationFile).get();
493+
if (res.size() >= 2 && res.get(1) != null && res.get(1) instanceof Map) {
494+
HashMap<?, ?> error = ((HashMap<?, ?>) res.get(1));
495+
// that means topology already exists
496+
return error.get("str").toString().contains("collision with another server");
497+
}
491498
// The client connection will be closed after that command
492499
} catch (Exception e) {
493500
if (e instanceof ExecutionException) {
@@ -500,7 +507,7 @@ private boolean setupTopology() {
500507
return false;
501508
}
502509
} else {
503-
throw new RuntimeException("Failed to change the app topology", e);
510+
throw new CartridgeTopologyException(e);
504511
}
505512
}
506513
}
@@ -516,7 +523,7 @@ private void retryingSetupTopology() {
516523
throw new RuntimeException(e);
517524
}
518525
if (!setupTopology()) {
519-
throw new RuntimeException("Failed to change the app topology after retry");
526+
throw new CartridgeTopologyException("Failed to change the app topology after retry");
520527
}
521528
}
522529
}

src/main/java/org/testcontainers/containers/TarantoolContainerClientHelper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public CompletableFuture<List<?>> executeScript(String scriptResourcePath) {
7575
String scriptName = Paths.get(scriptResourcePath).getFileName().toString();
7676
String containerPath = normalizePath(Paths.get(TMP_DIR, scriptName));
7777
container.copyFileToContainer(MountableFile.forClasspathResource(scriptResourcePath), containerPath);
78-
return executeCommand(String.format("dofile('%s')", containerPath));
78+
return executeCommand(String.format("return dofile('%s')", containerPath));
7979
}
8080

8181
public CompletableFuture<List<?>> executeCommand(String command, Object... arguments) {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.testcontainers.containers.exceptions;
2+
3+
/**
4+
* Base class for Cartridge runtime exceptions
5+
*
6+
* @author Artyom Dubinin
7+
*/
8+
public abstract class CartridgeContainerException extends TarantoolContainerException {
9+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.testcontainers.containers.exceptions;
2+
3+
public class CartridgeTopologyException extends TarantoolContainerException {
4+
5+
static final String errorMsg = "Failed to change the app topology";
6+
7+
public CartridgeTopologyException(String message) {
8+
super(message);
9+
}
10+
11+
public CartridgeTopologyException(Throwable cause) {
12+
super(errorMsg, cause);
13+
}
14+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.testcontainers.containers.exceptions;
2+
3+
/**
4+
* Base class for Tarantool runtime exceptions
5+
*
6+
* @author Artyom Dubinin
7+
*/
8+
public abstract class TarantoolContainerException extends RuntimeException {
9+
public TarantoolContainerException(String message) {
10+
super(message);
11+
}
12+
13+
public TarantoolContainerException() {
14+
super();
15+
}
16+
17+
public TarantoolContainerException(Throwable cause) {
18+
super(cause);
19+
}
20+
21+
public TarantoolContainerException(String message, Throwable cause) {
22+
super(message, cause);
23+
}
24+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/**
2+
* Exception classes for internal client errors to be translated to user
3+
*/
4+
package org.testcontainers.containers.exceptions;

src/test/java/org/testcontainers/containers/TarantoolCartridgeBootstrapFromLuaWithFixedPortsTest.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
package org.testcontainers.containers;
22

33
import org.junit.jupiter.api.Test;
4+
import org.rnorth.ducttape.RetryCountExceededException;
45
import org.slf4j.LoggerFactory;
6+
import org.testcontainers.containers.exceptions.CartridgeTopologyException;
57
import org.testcontainers.containers.output.Slf4jLogConsumer;
68
import org.testcontainers.junit.jupiter.Container;
79
import org.testcontainers.junit.jupiter.Testcontainers;
810
import org.testcontainers.utility.MountableFile;
911

1012
import java.time.Duration;
1113

14+
import static org.junit.Assert.assertThrows;
15+
import static org.junit.jupiter.api.Assertions.assertEquals;
16+
1217
/**
1318
* @author Alexey Kuzin
1419
*/
@@ -21,8 +26,8 @@ public class TarantoolCartridgeBootstrapFromLuaWithFixedPortsTest {
2126
"Dockerfile",
2227
"cartridge/instances_fixedport.yml",
2328
"cartridge/topology_fixedport.lua")
24-
.withCopyFileToContainer(MountableFile.forClasspathResource("cartridge"), "/app")
25-
.withCopyFileToContainer(MountableFile.forClasspathResource("cartridge/instances_fixedport.yml"),"/app/instances.yml")
29+
.withDirectoryBinding("cartridge")
30+
.withEnv("TARANTOOL_INSTANCES_FILE", "instances_fixedport.yml")
2631
.withStartupTimeout(Duration.ofSeconds(300))
2732
.withUseFixedPorts(true)
2833
.withAPIPort(18081)
@@ -34,4 +39,25 @@ public class TarantoolCartridgeBootstrapFromLuaWithFixedPortsTest {
3439
public void test_StaticClusterContainer_StartsSuccessfully_ifFilesAreCopied() throws Exception {
3540
CartridgeContainerTestUtils.executeProfileReplaceSmokeTest(container);
3641
}
42+
43+
@Test
44+
public void test_retryingSetupTopology_shouldWork() {
45+
try (TarantoolCartridgeContainer testContainer =
46+
new TarantoolCartridgeContainer(
47+
"Dockerfile",
48+
"cartridge/instances.yml",
49+
"cartridge/incorrect_topology.lua")
50+
.withDirectoryBinding("cartridge")
51+
.withLogConsumer(new Slf4jLogConsumer(
52+
LoggerFactory.getLogger(TarantoolCartridgeBootstrapFromLuaWithFixedPortsTest.class)))) {
53+
ContainerLaunchException ex = assertThrows(ContainerLaunchException.class, testContainer::start);
54+
Throwable cause = ex.getCause();
55+
assertEquals(RetryCountExceededException.class, cause.getClass());
56+
cause = cause.getCause();
57+
assertEquals(ContainerLaunchException.class, cause.getClass());
58+
cause = cause.getCause();
59+
assertEquals(CartridgeTopologyException.class, cause.getClass());
60+
assertEquals("Failed to change the app topology after retry", cause.getMessage());
61+
}
62+
}
3763
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
cartridge = require('cartridge')
2+
replicasets = { {
3+
alias = 'app-router',
4+
roles = { 'vshard-router', 'app.roles.custom', 'app.roles.api_router' },
5+
join_servers = { { uri = 'localhost:3301' } }
6+
}, {
7+
alias = 's1-storage',
8+
roles = { 'vshard-storage', 'app.roles.api_storage' },
9+
join_servers = { { uri = 'localhost:3302' } }
10+
},
11+
{
12+
alias = 's2-storage',
13+
roles = { 'vshard-storage', 'app.roles.api_storage' },
14+
join_servers = { { uri = 'localhost:3303' } }
15+
} }
16+
return cartridge.admin_edit_topology({ replicasets = replicasets })

0 commit comments

Comments
 (0)