You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在集成测试中Mock GCP Secret Manager以测试重试与错误处理?

测试GCP Secret Manager客户端重试与错误处理的可行方案

1. 官方GCP Secret Manager Emulator

这是最贴近真实生产环境的方案,官方支持模拟各类gRPC错误(连接重置、超时等),完全兼容你使用的客户端版本。

配置步骤:

  • 安装并启动Emulator:
    gcloud components install secret-manager-emulator
    gcloud beta emulators secret-manager start --host-port=localhost:8085
    
  • 在Spring Boot测试中指定Emulator地址,覆盖默认生产环境配置:
    @TestConfiguration
    public class SecretManagerTestConfig {
        @Bean
        public SecretManagerClient secretManagerClient() throws IOException {
            SecretManagerSettings settings = SecretManagerSettings.newBuilder()
                    .setEndpoint("localhost:8085")
                    .setCredentialsProvider(FixedCredentialsProvider.create(NoCredentials.getInstance()))
                    .build();
            return SecretManagerClient.create(settings);
        }
    }
    
  • 模拟错误:通过Emulator的控制API(或直接构造gRPC错误响应)返回指定错误码,比如UNAVAILABLE(模拟连接重置)、DEADLINE_EXCEEDED(模拟超时),触发客户端的重试逻辑。

2. Testcontainers 集成GCP Emulator

适合自动化集成测试,无需手动启动Emulator,测试用例可自动拉起Emulator容器:

依赖(添加到pom.xml):

<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>gcloud</artifactId>
    <version>1.19.0</version>
    <scope>test</scope>
</dependency>

测试类示例:

@SpringBootTest
@Testcontainers
public class SecretManagerRetryTest {
    @Container
    private static final GCloudEmulatorContainer secretManagerEmulator = new GCloudEmulatorContainer(
            "gcr.io/google.com/cloudsdktool/google-cloud-cli:latest")
            .withEmulator("secret-manager")
            .withExposedPorts(8085);

    @Autowired
    private SecretManagerClient client;

    @BeforeEach
    void setup() {
        // 配置客户端指向容器内的Emulator
        System.setProperty("secretmanager.emulator.host", secretManagerEmulator.getHost());
        System.setProperty("secretmanager.emulator.port", String.valueOf(secretManagerEmulator.getMappedPort(8085)));
    }

    @Test
    void testRetryOnConnectionReset() {
        // 模拟gRPC UNAVAILABLE错误,验证客户端重试逻辑
        // 可通过Emulator的控制接口注入错误响应
        // 省略具体断言逻辑
    }
}

3. gRPC Mock Server 直接Mock服务端

如果需要更细粒度的错误控制,可使用gRPC Mock Server直接模拟Secret Manager的gRPC服务,返回自定义错误:

依赖(添加到pom.xml):

<dependency>
    <groupId>io.grpc</groupId>
    <artifactId>grpc-testing</artifactId>
    <version>1.59.0</version>
    <scope>test</scope>
</dependency>

测试示例:

public class SecretManagerGrpcMockTest {
    private Server server;
    private SecretManagerClient client;

    @BeforeEach
    void setup() throws IOException {
        // 创建Mock gRPC Server,返回UNAVAILABLE错误
        server = ServerBuilder.forPort(0)
                .addService(new SecretManagerGrpc.SecretManagerImplBase() {
                    @Override
                    public void accessSecretVersion(AccessSecretVersionRequest request,
                                                    StreamObserver<AccessSecretVersionResponse> responseObserver) {
                        responseObserver.onError(Status.UNAVAILABLE.withDescription("Connection reset").asRuntimeException());
                    }
                })
                .build()
                .start();

        // 配置客户端连接到Mock Server
        SecretManagerSettings settings = SecretManagerSettings.newBuilder()
                .setEndpoint("localhost:" + server.getPort())
                .setCredentialsProvider(FixedCredentialsProvider.create(NoCredentials.getInstance()))
                .build();
        client = SecretManagerClient.create(settings);
    }

    @AfterEach
    void teardown() {
        server.shutdown();
        client.close();
    }

    @Test
    void testRetryOnUnavailable() {
        // 调用客户端方法,验证重试次数是否符合预期
        // 可通过CountDownLatch或Mockito验证重试逻辑
    }
}

注意事项:

  • 确保客户端的重试配置正确(默认情况下,Google Cloud客户端已内置重试逻辑,但可通过SecretManagerSettings自定义重试参数)
  • 测试时需覆盖生产环境的凭证配置,避免调用真实GCP服务

内容的提问来源于stack exchange,提问作者joe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 08:30:16