# 주제: DestructiveOperationGuard 의 6개 검사 중 2개가 어떤 테스트에도 도달하지 않으며, # 클래스 javadoc 은 그 2개를 세지 않는다 # revision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 # DestructiveOperationGuard.authorize 의 실제 분기 (DestructiveOperationGuard.java:54-93) # 1) dryRun -> 무조건 통과 (:54-56) # 2) !adminCredentialPresent -> ADMIN_CREDENTIAL_REQUIRED (:57-61) # 3) approval 부재 -> APPROVAL_REQUIRED (:62-67) # 4) !isValidAt(now) -> APPROVAL_EXPIRED (:68-71) # 5) operation 불일치 -> APPROVAL_OPERATION_MISMATCH (:72-83) # 6) source 불일치 -> APPROVAL_SOURCE_MISMATCH (:84-93) # # 클래스 javadoc (:12-15): # "Four conditions, all required. The caller must hold the admin credential … The approval must # be present and inside its validity window. And a dry run is always permitted …" # -> 1~4만 서술한다. 5, 6은 언급되지 않는다. # (5번 분기에는 별도 인라인 주석이 있다: "A guard that only checks presence and window # lets a verified redrive approval authorise a destination deletion." — 즉 의도된 검사다.) # command: git grep -n "\.authorize(" -- src | grep -i "messaging" # exit: 0 src/messaging/messaging-admin-api/src/test/java/.../DestructiveOperationGuardTest.java:56,67,84,96,107 (테스트 5건) src/messaging/messaging-admin-runtime/src/main/java/.../RedriveService.java:97 src/messaging/messaging-admin-runtime/src/main/java/.../ReplayService.java:59 # => guard.authorize 를 부르는 테스트는 DestructiveOperationGuardTest 의 5건이 전부다. # 그 5건이 도달하는 분기: # anApplicationRuntimeCannotRedrive -> 2 (ADMIN_CREDENTIAL_REQUIRED) # anAdminRuntimeStillNeedsAnApproval -> 3 (APPROVAL_REQUIRED) # anExpiredApprovalDoesNotAuthorise -> 4 (APPROVAL_EXPIRED) # aDryRunIsAlwaysPermitted -> 1 # anApprovedAdminOperationIsAuthorised -> 통과 # => 분기 5, 6 에 도달하는 테스트가 없다. # 주목: 유일하게 불일치 조합을 넘기는 테스트가 있으나 앞 분기에서 먼저 걸린다. # DestructiveOperationGuardTest.java:52-59 anApplicationRuntimeCannotRedrive # guard = new DestructiveOperationGuard(false) <- 자격증명 없음 # guard.authorize(DestructiveOperation.REDRIVE, ORDERS, Optional.of(VALID), false, NOW) # VALID 는 :24-25 에서 DestructiveOperation.REPLAY 로 만들어진 승인이다. # -> operation 이 실제로 불일치(REDRIVE vs REPLAY)하지만, # 분기 2가 먼저 던지므로 단언은 "admin credential" 이다. 분기 5는 실행되지 않는다. # command: git grep -n "APPROVAL_OPERATION_MISMATCH\|APPROVAL_SOURCE_MISMATCH" -- src | grep -v "messaging-admin-api/src/main" # exit: 1 (출력 없음) # => 두 에러 코드를 단언하는 테스트가 저장소 전체에 없다. # (동명 개념은 ApprovedReplayPlan / ApprovedRedrivePlan 생성자에도 있고 그쪽은 # messaging-admin-runtime 의 ApprovalForgeryTest 가 행위로 검증한다: # anApprovalForAReplayCannotAuthoriseARedrive, aVerifiedApprovalForTheWrongSourceCannotBeAttached. # 그러나 그것은 record 생성자이지 guard 의 분기가 아니다 — 서로 다른 코드다.) # ---- 배선 ---- # command: git grep -nE "new ([a-zA-Z0-9_.]+\.)?DestructiveOperationGuard\s*\(" -- src src/messaging/messaging-admin-api/src/test/java/.../DestructiveOperationGuardTest.java:52,64,74,92,103 src/messaging/messaging-admin-runtime/src/test/java/.../RedriveResumptionTest.java:142 new DestructiveOperationGuard(true) src/messaging/messaging-spring-boot-starter/src/main/java/.../MessagingAdminAutoConfiguration.java:40 return new DestructiveOperationGuard(false); # => 프로덕션 생성은 1건이며 adminCredentialPresent=false 로 고정이다. 이는 의도된 설계이고 # 주석이 명시한다("An operator tool overrides this bean with true."). # 결과적으로 부팅된 애플리케이션에서는 분기 2에서 항상 멈추므로 3~6은 도달 불가다. # ---- ApprovalVerifier 배선 ---- # command: git grep -n "implements ApprovalVerifier" -- src src/messaging/messaging-admin-api/.../HmacApprovalVerifier.java:26 # command: git grep -nE "new ([a-zA-Z0-9_.]+\.)?HmacApprovalVerifier\s*\(" -- src | grep "/src/main/" # exit: 1 (출력 없음) — src/main 생성 0건, src/test 생성 5건 # => 부팅된 애플리케이션에는 ApprovalVerifier 빈이 없다. VerifiedApproval 을 만들 수 있는 주체가 # 프로덕션 배선에 존재하지 않는다. (스타터 javadoc 이 이 스탠스를 명시한다: # "an operator tool that needs purge or delete registers one itself".)