# 모듈 전체를 돌리면 MutualTlsHandshakeContractTest > anUntrustedAuthorityIsAPermanentTlsFailure() FAILED org.opentest4j.AssertionFailedError at MutualTlsHandshakeContractTest.java:168 MutualTlsHandshakeContractTest > anExpiredCertificateIsAPermanentTlsFailure() FAILED org.opentest4j.AssertionFailedError at MutualTlsHandshakeContractTest.java:168 MutualTlsHandshakeContractTest > aHostnameMismatchIsAPermanentTlsFailure() FAILED org.opentest4j.AssertionFailedError at MutualTlsHandshakeContractTest.java:168 283 tests completed, 3 failed > Task :adapter:outbound:httpclient:test FAILED # 멈추는 자리는 두 번째 단언이다 164: private void assertPermanent(Throwable captured) { 165: TransportFailure classified = 166: new ApacheFailureClassifier().classify(captured, AttemptStage.TLS_HANDSHAKE); 167: assertThat(classified.evidence()).isEqualTo(ExecutionEvidence.NOT_SENT); 168: assertThat(classified.stage()).isEqualTo(AttemptStage.TLS_HANDSHAKE); 169: assertThat(classified.category()).isEqualTo(FailureCategory.TLS_PERMANENT); 170: assertThat(classified.category().permanent()).isTrue(); 171: } (167 통과 · 168 실패 · 169 이하 미실행) # 픽스처가 돌려주는 것은 호스트명이다 70: public URI uri(String path) { 71- return server.url(path).uri(); 72- } # 이 컨테이너에서 그 호스트명이 푸는 주소 1:127.0.0.1 localhost 2:::1 localhost ip6-localhost ip6-loopback localhost/127.0.0.1 localhost/0:0:0:0:0:0:0:1 # src 아래의 preferIPv4Stack / preferIPv6Addresses 설정: 0 # 강등이 재시도 판정에 닿는 지점 /** Permanent failures are never retried regardless of evidence, deadline, or budget. */ public boolean permanent() { return this == CONFIGURATION || this == TARGET_REJECTED || this == TLS_PERMANENT || this == SERIALIZATION || this == RESPONSE_TOO_LARGE || this == REDIRECT_REJECTED || this == DEADLINE_EXCEEDED || this == CANCELLED; } 엔진의 가드 순서 if (context.attempt() >= context.maxAttempts()) { return RetryDenied.maxAttempts(); } if (!context.budget().available()) { return RetryDenied.budgetExhausted(); if (context.failureCategory().permanent()) { return RetryDenied.permanentFailure(context.failureCategory().name()); } case CONNECT -> RetryAllowed.of("CONNECT");