Skip to content

[Test] 업로드 성공 응답의 DB·GCS 복원 판정 계약 - #561

Merged
Gimini-3 merged 1 commit into
developfrom
test/dr-upload-recovery-contract
Oct 18, 2026
Merged

Gimini-3 merged 1 commit into
developfrom
test/dr-upload-recovery-contract

Conversation

@Gimini-3

Copy link
Copy Markdown
Contributor

목적

Refs #560

기존 복원 기록은 DB·GCS 복원과 일부 기능 재개를 각각 확인했지만, 클라이언트가 성공 응답을 받은 업로드 전체가 최초 복원 상태에 남았는지 판정하는 연결 원장이 없었습니다. 후속 격리 복구 실험에서 사용하는 응답 원장·입력 고정·최초 감사 관문을 추가합니다.

성공 기준은 응답 ID 4종과 DB 관계, 보존 원본의 SHA-256·크기·고정 generation을 대조하고, 최초 감사가 저장되기 전에 Worker·Flyway·수선을 허용하지 않는 것입니다. 이번 변경은 실제 복구 계측을 완료했다는 보고가 아닙니다.

테스트 환경

  • 기반: 4cfe9666ac3a670bb72c8cd4d933bc7d7238fce0; 제출 구현: e62c579a184855c2aa55be192371ca130be6075a.
  • 로컬 Python 표준 라이브러리와 합성 JSON. 연산자는 제어 가능한 로컬 자식 프로세스이며 DB·Docker·GCP·BGE-M3·Ollama를 호출하지 않았습니다.
  • 기존 Barman/GCS 도구와 ha_evidence의 내구성 파일 쓰기를 재사용합니다. 개인 환경 파일·공개 서비스 설정 변경은 없습니다.
  • 실행별 로그와 결과는 실행 요약에 분리했습니다. 개인 경로·인프라 식별자는 공개 로그에서 제외했습니다.

테스트 방법

  1. 전송·HTTP 응답을 DB 외부 JSONL에 기록합니다. 200/201에는 documentId·documentVersionId·fileObjectId·embeddingJobId 4종을 요구합니다. 응답 미수신과 HTTP 오류는 DB 존재 여부와 별개로 남깁니다.
  2. 기준 백업·완결 WAL·외부 identity·보존 객체 버전을 고정합니다. 준비 조건 미충족이나 고정 입력 변경 시 실행을 거부합니다.
  3. restore → snapshot까지만 실행하고 최초 DB·원본 상태를 별도 파일에 보존합니다. Worker·Flyway·수선·원본 접근이 먼저 실행됐으면 기동하지 않습니다.
  4. 기능 코호트 복원과 관계·원본 대조가 통과한 경우에만 activate를 호출합니다. 중간 ACK 누락, 객체 누락·해시·버전 불일치를 주입해 관문을 확인합니다.
  5. 기존 다운로드·검색·Job 재개·새 업로드·인덱싱·다운로드의 관측 시각과 표본 수를 분리합니다. 최종 수렴 감사가 초기 손실을 덮어쓰지 않도록 확인합니다.
  6. 정리는 finally에서 시도합니다. 정리 계획 누락은 실행 전 거부하며, 정리 확인 실패·실행 중단·필수 단계 실패는 INCOMPLETE로 판정합니다.

명령: python3 -m unittest discover -s scripts/opensql -p test_dr_recovery.py -v

관측 결과

실행 ID 표본·결과 판정과 근거
DR-CONTRACT-20261018-R1 26개: 성공 21·실패 3·오류 2, 종료 1 연산자 파일명 준비 문제로 미통과. 원래 로그 보존
DR-CONTRACT-20261018-R2 26개: 성공 26·실패 0·오류 0, 종료 0 파일명 수정 후 재실행 통과
DR-CONTRACT-20261018-R3 33개: 성공 33·실패 0·오류 0, 0.689초 고정 generation과 증거 필드 제한 포함 통과
DR-CONTRACT-20261018-R4 36개: 성공 36·실패 0·오류 0, 0.769초 최종 감사 원본 의존·잘못된 기능 응답 기록·감사 뒤 경합 차단 포함 통과
  • 최초 ACK 1건 누락 후 최종 합성 스냅샷에서 복구돼도 초기 손실 1건을 유지했습니다.
  • 준비·최초 감사 미충족 시 activate 미호출을 확인했습니다. 잘못된 기능 응답의 민감한 값은 결과 파일에 남지 않았습니다.
  • 기존 CI 작업은 보존하고 외부 연결 없는 recovery-contract 작업을 추가했습니다.

검증 과정에서 확인된 사항

  • 첫 실행의 operator.py가 Python 표준 operator 모듈을 가려 import 순환이 발생했습니다. controlled_driver.py로 수정한 뒤 회차를 구분해 재실행했습니다. 최초 회차를 통과로 바꾸지 않았습니다.
  • 객체 generation은 원본 버킷 숫자와 같아야 한다는 조건이 아닙니다. 복사 후 새로 부여된 보존 객체의 generation을 입력에 고정하고 그 버전을 읽었다는 관측과 대조합니다.
  • 이 제어기는 연산자가 내는 JSON 확인값을 검증합니다. boolean 확인값 자체가 실제 VM 접근 차단·WAL 연결·정리 성공을 독립적으로 증명하지 않습니다. 실제 SQL·보존 객체 읽기·HTTP 결과와 연결하는 격리 실행은 후속 작업입니다.
  • cutoff는 입력 고정 시각입니다. 실제 장애 시각과 차이가 있으면 별도 기록해야 하며, 현재 로컬 계약 통과를 OpenSQL RPO 0·공개 서비스 RTO·실제 모델 검색 복구 성공으로 표현하지 않습니다.

설계: 업로드 복원 판정 계약

@coderabbitai

coderabbitai Bot commented Oct 18, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Repository: DocGrid/docgrid/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: df5bfbff-278f-41e8-8ff4-7e865b4e177f
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Gimini-3
Gimini-3 merged commit 3bff887 into develop Oct 18, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant