Reputation: 807
I'm trying to simulate that the Mongo database is down when the query is run. I'm using testcontainers with Toxiproxy and Mongo.
In the below test class, test called withLatency work as expected but test withoutConnection is hanging.
Code:
@SpringBootApplication
public class ToxiproxyIssueApplication {
public static void main(String[] args) {
SpringApplication.run(ToxiproxyIssueApplication.class, args);
}
}
@Document
public record Person(String name, int age) {
}
@Repository
public interface PersonRepository extends MongoRepository<Person, String> {
}
The properties file contains:
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
The test:
@Testcontainers
@SpringBootTest(properties = {"spring.main.allow-bean-definition-overriding=true"})
class ToxiproxyIssueApplicationTests {
@Autowired
private PersonRepository personRepository;
private static final Network network = Network.newNetwork();
private static final DockerImageName dockerImageName = DockerImageName.parse("mongo:5.0.5").asCompatibleSubstituteFor("mongo");
@Container
static final MongoDBContainer mongoDbContainer = new MongoDBContainer(dockerImageName)
.withNetwork(network)
.withNetworkAliases("mongo");
// .withReuse(true);
@Container
private static final ToxiproxyContainer toxiproxy = new ToxiproxyContainer("ghcr.io/shopify/toxiproxy:2.6.0")
.withNetwork(network);
private static Proxy mongoProxy;
@DynamicPropertySource
static void mongoProperties(DynamicPropertyRegistry registry) throws IOException {
ToxiproxyClient toxiproxyClient = new ToxiproxyClient(toxiproxy.getHost(), toxiproxy.getControlPort());
mongoProxy = toxiproxyClient.createProxy("mongodb", "0.0.0.0:8666", "mongo:27017");
int port = mongoDbContainer.getMappedPort(27017);
registry.add("spring.data.mongodb.host", toxiproxy::getHost);
registry.add("spring.data.mongodb.port", () -> toxiproxy.getMappedPort(8666));
}
@Test
void withLatency() throws IOException {
mongoProxy.toxics().latency("mongo-latency", ToxicDirection.DOWNSTREAM, 2600).setJitter(100);
var result = personRepository.findAll();
assertThat(result).isEmpty();
}
@Test
void withoutConnection() throws IOException {
mongoProxy.toxics().bandwidth("no-connection-downstream", ToxicDirection.DOWNSTREAM, 0);
mongoProxy.toxics().bandwidth("no-connection-upstream", ToxicDirection.UPSTREAM, 0);
var result = personRepository.findAll();
assertThat(result).isEmpty();
mongoProxy.toxics().get("no-connection-downstream").remove();
mongoProxy.toxics().get("no-connection-upstream").remove();
}
}
When the test is hanging I see in the logs a timeout from the driver:
com.mongodb.MongoSocketReadTimeoutException: Timeout while receiving message
Is there something wrong in my config or is this a testcontainer bug?
P.S the code posted should be enough to reproduce the issue.
Later edit
Based on the discussion from here there is no bug. The client library is the one who provides the behavior. So further research will be conducted on this side.
Upvotes: 0
Views: 471
Reputation: 807
Based on the Toxiproxy documentation, there is the down toxic (https://github.com/Shopify/toxiproxy#down): by disabling the proxy no traffic will be routed.
In java Toxiproxy client library there are some methods to enable and disable the proxy: https://github.com/trekawek/toxiproxy-java/blob/7c5ffc5d7aa4780bd2ea73ad945f0227793a7e3d/src/main/java/eu/rekawek/toxiproxy/Proxy.java#L70-L76
Thus, the mentioned failed test will be rewritten as:
@Test
void withoutConnection() throws IOException {
mongoProxy.disable();
assertThatThrownBy(()->personRepository.findAll()).isInstanceOf(Exception.class);
mongoProxy.enable();
var result = personRepository.findAll();
assertThat(result).isEmpty();
}
Upvotes: 0