使用Testcontainers模拟MongoDB断连时测试挂起问题排查
问题:Testcontainers+Toxiproxy模拟MongoDB不可用时测试挂起
我尝试用Testcontainers搭配Toxiproxy和MongoDB,模拟查询操作时MongoDB不可用的场景。测试类中withLatency测试能正常运行,但withoutConnection测试出现挂起,日志中出现驱动超时信息:
com.mongodb.MongoSocketReadTimeoutException: Timeout while receiving message
想确认是配置存在问题,还是Testcontainers的bug?
补充:提供的代码可复现该问题。
后续编辑:已确认不存在框架bug,该行为由客户端库导致,将针对此方向进一步调研。
项目代码
启动类
@SpringBootApplication public class ToxiproxyIssueApplication { public static void main(String[] args) { SpringApplication.run(ToxiproxyIssueApplication.class, args); } }
实体类
@Document public record Person(String name, int age) { }
Repository接口
@Repository public interface PersonRepository extends MongoRepository<Person, String> { }
配置文件
spring.data.mongodb.host=localhost spring.data.mongodb.port=27017
测试代码
@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(); } }
错误日志
com.mongodb.MongoSocketReadTimeoutException: Timeout while receiving message
内容的提问来源于stack exchange,提问作者florin
相关产品推荐
相关产品推荐

