Skip to content

e2e: failover spec 이 구조적으로 통과 불가 — pod 삭제로는 failover 가 트리거되지 않는다 #322

Description

@KeiaiLab-PHIL

증상

test/e2e/failover_test.go:116 이 nightly 에서 항상 실패합니다 — primary pod 강제 삭제 후 3분을 기다려도 status.currentPrimarypod-0 그대로입니다.

Expected
    <string>: vk-failover-test-0
    <string>: vk-failover-test-0

진단: 타이밍이 아니라 구조적 불가

실패 시점 덤프(#320)에서 세 pod 모두 Running 이고 pod-0 이 3분 전 재생성돼 있었습니다. 코드를 보면 이유가 명확합니다.

internal/controller/failover.go 의 판정:

ready, since, err := r.podReadyState(ctx, curPrimary, v.Namespace)
if ready { return }                                              // ①
if since.IsZero() || time.Since(since) < failoverNotReadyThreshold { return }  // ②

그리고 podReadyState 는 pod 이 NotFound 일 때 since = time.Time{}(zero) 를 반환합니다.

따라서 pod 삭제 시나리오는 두 구간 모두에서 failover 가 차단됩니다:

  • 삭제 직후(부재)since.IsZero() → ② 에서 종료
  • StatefulSet 이 재생성 후 → pod 이 곧 Ready → ① 에서 종료

즉 아무리 오래 기다려도 통과할 수 없습니다. 타임아웃을 올려도 소용없습니다.

제품 동작은 타당해 보입니다

since.IsZero() 가드는 "pod 이 없는 동안(=STS 가 재생성 중)에는 failover 하지 않는다" 는 의도로 읽힙니다 — 롤링 재시작마다 불필요한 failover 를 막는 합리적 설계입니다. 고쳐야 할 쪽은 테스트의 시뮬레이션 방식입니다.

필요한 것: primary 가 존재하면서 NotReady 인 상태

failover 는 "pod 이 존재하고 Ready=False 인 상태가 threshold 이상 지속" 일 때만 트리거됩니다. 테스트가 그 상태를 만들어야 합니다.

후보:

  1. valkey-cli DEBUG SLEEP <n> 으로 primary 이벤트 루프를 막아 readiness probe 실패 유도 — pod 객체는 유지됨. 주의: Redis/Valkey 7+ 는 enable-debug-command 로 DEBUG 를 기본 제한하므로 사용 가능 여부 확인 필요.
  2. NetworkPolicy 로 primary 격리 — 무겁지만 확실.
  3. readiness probe 대상 포트를 일시 차단.

어느 쪽이든 실제로 readiness 가 뒤집히는지 를 e2e 로 확인해야 하므로, 선택은 검증과 함께 진행하는 게 맞습니다.

배경

이 spec 은 e2e 가 CI 에 연결되기 전까지(#312) 한 번도 실행된 적이 없어 이 문제가 드러나지 않았습니다. 동일 계열로 이미 수리된 것: -timeout 미지정(구조적 통과 불가), CRD 설치 순서 난수, major 승급 정책 위반, valkey-cli 경고 혼입(#321).

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions