Skip to content

test(race): H2 가 못 보는 네이티브 쿼리 4종을 실 MySQL 에서 고정 — SKIP LOCKED·파티션 DDL·daily_logs·피드백 FK - #817

Open
Khyojae wants to merge 1 commit into
mainfrom
test/mysql-race-coverage
Open

Khyojae wants to merge 1 commit into
mainfrom
test/mysql-race-coverage

Conversation

@Khyojae

@Khyojae Khyojae commented Sep 23, 2026

Copy link
Copy Markdown
Member

요약

H2 기본 테스트로는 문법만 확인되던 네이티브 SQL·DDL 4종을 실 MySQL(Testcontainers race 프로파일)에서 동작까지 고정한다. main 코드 변경은 없다.

테스트 고정하는 것 왜 H2로는 안 되나
OutboxSkipLockedRaceTest 발행기 A가 행을 잠근 동안 B는 기다리지 않고 A가 안 잡은 행만 받는다. lease가 만료된 PROCESSING만 회수된다 행 락과 SKIP LOCKED는 InnoDB 동작이다. 지금까지는 PR #63 때 손으로만 확인했다
PoseDataPartitionMaintenanceRaceTest DROP PARTITION·REORGANIZE PARTITION pfuture 실제 실행: 만료 달의 행만 사라짐, 이름 패턴 밖 파티션 보존, 두 번 돌려도 같음, 새 파티션 경계(1일 0시) 기존 테스트는 결정 로직만 보고 JdbcTemplate은 목(mock)이었다. 되돌릴 수 없는 DDL이 한 번도 실행된 적이 없었다
DailyLogNativeQueryRaceTest upsertMemoAndMood: Mood 5개 값이 MySQL ENUM에 모두 들어감, 덮어써도 누적 통계는 보존. recomputeStats: TIMESTAMPDIFF 분 절삭, 날짜 경계, COMPLETED만, 남의 세션 제외, 0으로 덮기 H2는 엔티티에서 스키마를 만들어 ENUM 목록 불일치를 못 본다. MySQL 함수 의미도 확인해야 한다
FeedbackLogFkRaceTest 재작성 배치(rewriteBatchedStatements=true)에서도 원인 체인에 1452가 실려 SESSION_NOT_FOUND로 번역된다. 재전송·혼합 배치의 삽입 건수 기본 테스트는 H2의 SQLState 분기만 돌았다

격리

  • 파티션: race 테스트들은 컨테이너 하나를 같이 쓴다. 그래서 스크래치 스키마에 CREATE TABLE ... LIKE로 Flyway가 만든 진짜 pose_data를 복사하고, 파티션만 «오늘 기준 상대 월»로 다시 짜서 돌린다. 스케줄러는 DATABASE()와 테이블명만으로 동작하므로 main 코드를 바꿀 필요가 없다. root 접속을 위해 MySqlContainerSupport.MYSQL을 protected로 바꿨다.
  • outbox: 전체 스위트에서 캐시된 다른 컨텍스트(스케줄러가 켜진 race 테스트)의 OutboxPublisher가 이 테스트의 행을 먼저 집어 간 일이 실제로 있었다(첫 전체 실행 때 1건 실패). 그래서 행의 시각을 +1일로 밀고 선점 쿼리의 :now에 그 미래 시각을 넘긴다. 실제 발행기는 now()로 조회하므로 이 행들을 절대 집지 못한다.

검증

  • ./gradlew test 전체: 968 tests, 실패 0, 6 skipped. 새 race 테스트 16개는 모두 실제로 돌았다(skip 아님, 로컬 Docker).
  • 테스트가 결함을 잡는지 확인: 선점 쿼리에서 SKIP LOCKED를 빼고 돌리면 OutboxSkipLockedRaceTest가 실패한다(B가 A의 락에 막혀 30초 대기). 확인한 뒤 원복했다.

발견 — #816

FeedbackLogFkRaceTest를 쓰다가 한 배치 안에 같은 (rep, 유형)이 두 번 있으면 MySQL 에러 1869로 배치 전체가 실패하는 것을 찾았다. 이미 커밋된 행과의 중복(재전송)은 문제없다. 지금 AI는 배치를 항상 1건으로 보내므로 운영 경로에서는 나지 않는 잠복 결함이다. 수정 방식이 정해지지 않아 테스트로 고정하지 않고 주석으로 남겼다.

🤖 Generated with Claude Code

…·daily_logs·피드백 FK

- OutboxSkipLockedRaceTest: 발행기 A 가 잠근 동안 B 는 안 기다리고 다른 행만 받음, 만료 lease 만 회수
  (SKIP LOCKED 를 빼면 실패함을 확인 — B 가 A 의 락에 막힘)
- PoseDataPartitionMaintenanceRaceTest: 스크래치 스키마에 실제 pose_data 정의를 복사해 DROP/REORGANIZE 실행
  — 만료 달 행만 사라짐, 패턴 밖 파티션 보존, 멱등, 새 파티션 경계
- DailyLogNativeQueryRaceTest: Mood 전 값이 MySQL ENUM 에 들어감, 덮어쓰기가 누적 통계 보존,
  recomputeStats 의 분 절삭·날짜 경계·COMPLETED 만·남의 세션 제외
- FeedbackLogFkRaceTest: 재작성 배치에서 1452 → SESSION_NOT_FOUND, 재전송 건수. 배치 안 중복은 1869 로
  실패함을 발견(#816) — 고정하지 않고 주석으로 남김
- MySqlContainerSupport.MYSQL 을 protected 로(스크래치 스키마용 root 접속)

전체 ./gradlew test: 968 tests, 실패 0, 6 skipped.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Khyojae Khyojae added ✅ Test ✅ Test java Pull requests that update java code labels Sep 23, 2026
@coderabbitai

coderabbitai Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 11 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository: Shadowfit/init/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: a909fae8-2701-49aa-a05c-3d61f7b6eab0

📥 Commits

Reviewing files that changed from the base of the PR and between 631736e and 4ecbe7f.

📒 Files selected for processing (5)
  • backend/src/test/java/com/shadowfit/repository/outbox/OutboxSkipLockedRaceTest.java
  • backend/src/test/java/com/shadowfit/repository/report/DailyLogNativeQueryRaceTest.java
  • backend/src/test/java/com/shadowfit/service/exercise/FeedbackLogFkRaceTest.java
  • backend/src/test/java/com/shadowfit/service/exercise/PoseDataPartitionMaintenanceRaceTest.java
  • backend/src/test/java/com/shadowfit/support/MySqlContainerSupport.java

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.

@Khyojae

Khyojae commented Sep 23, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

java Pull requests that update java code ✅ Test ✅ Test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant