[Template] 스냅샷 왕복을 실제 MySQL 위에서 본다 [ #395 ] - #397
Merged
Merged
Conversation
#395 를 머지한 뒤 dev 에서 행을 직접 보다가 fetched_at 이 MySQL NOW() 와 9시간 차이나는 것을 봤다. 저장은 UTC 이고 NOW() 는 KST(JDBC URL 이 serverTimezone=Asia/Seoul)라서 그 자체는 정상이지만, 쓸 때와 읽을 때의 변환이 대칭인지는 확인된 적이 없었다. 기존 단위 테스트는 리포지토리를 목으로 두므로 JDBC 를 타지 않는다. 즉 나이 계산이 걸려 있는 구간이 테스트 밖에 있었다. 어긋나면 조용히 망가진다 — 나이가 부풀려지면 상한(기본 24h)에 먼저 걸려 복원이 안 되고, 줄어들면 너무 낡은 목록을 복원한다. 어느 쪽도 예외를 던지지 않는다. 실제 MySQL 위에서 다섯 가지를 본다. 넣은 Instant 가 그대로 읽힌다 (정확히 같은 값) DB 를 거쳐 돌아온 나이가 실제 경과와 같다 (3시간 → 3시간) 상한 판정이 실제 DB 값으로도 맞다 (25h 거부 / 상한 48h 로 늘리면 복원) 두 번 저장하면 UPDATE 로 가고 행이 하나다 (트랜잭션 없이 merge) contentHints·tags·sourceUrl 까지 왕복한다 민감도도 확인했다. fetched_at 을 datetime(6) → datetime 으로 깎으면 "저장한 그 시각이 그대로 읽힌다" 가 실패한다. expected: 2026-09-25T15:45:34.659232Z but was: 2026-09-25T15:45:35Z ddl-auto: validate 는 이 차이를 잡지 않는다. 그 민감도 확인에서 한 번 거짓 통과를 봤다 — 첫 시도에서 "0건 실패" 가 나왔는데, gradle 은 실패했고 내가 직전 실행의 결과 XML 을 읽고 있었다. 결과 파일을 지우고 총 건수까지 세니 제대로 1건 실패로 나왔다. 실패 수만 세면 "테스트가 안 돌았다" 와 "전부 통과했다" 가 같은 값으로 보인다. 전체 1762건 통과(직전 1757 + 신규 5), 실패 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013y8USoCXTsRTATAhy88M93
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#396 을 머지한 뒤 dev 에서 스냅샷 행을 직접 보다가 발견한 검증 공백을 메운다. 프로덕션 코드 변경 없음 — 테스트만 추가한다.
무엇을 봤나
fetched_at이 UTC 로 저장되고 MySQLNOW()는 KST 다(JDBC URL 이serverTimezone=Asia/Seoul). Sep 25 16:14 UTC = Sep 26 01:14 KST — 기동 직후 받은 것이니 값 자체는 맞다.문제는 그게 아니라, 쓸 때와 읽을 때의 변환이 대칭인지 확인된 적이 없었다는 것이다.
왜 기존 테스트로는 부족했나
TemplateCatalogSnapshotStoreTest는 리포지토리를 목으로 둔다. Jackson 왕복은 진짜를 태웠지만 JDBC 는 타지 않는다. 나이 계산이 걸려 있는 구간이 테스트 밖에 있었다.어긋나면 조용히 망가진다.
어느 쪽도 예외를 던지지 않는다. 그래서 테스트가 없으면 아무도 모른다.
추가한 것 — 실제 MySQL 위 5건
Instant가 그대로 읽힌다contentHints·tags·sourceUrl까지 왕복민감도 — 이 테스트가 정말 잡는가
fetched_at을datetime(6)→datetime으로 깎고 돌렸다.ddl-auto: validate는 이 차이를 잡지 않는다. 컬럼 타입 이름만 보기 때문이다.그 확인에서 거짓 통과를 한 번 봤다
첫 시도에서 "0건 실패" 가 나왔다. 실제로는 gradle 이 실패했고, 내가 직전 실행의 결과 XML 을 읽고 있었다. 결과 디렉터리를 지우고 총 건수까지 세니 제대로 1건 실패가 나왔다.
실패 수만 세면 "테스트가 안 돌았다" 와 "전부 통과했다" 가 같은 값으로 보인다. 이 세션에서 같은 모양의 함정을 이미 한 번 겪었다(
ElementTree의 falsy element).검증
전체 1762건 통과(직전 1757 + 신규 5), 실패 0, skip 12.
참고 — #395 는 이미 닫혔다(PR #396). 이 PR 은 그 구현의 검증 공백만 메운다.
🤖 Generated with Claude Code
https://claude.ai/code/session_013y8USoCXTsRTATAhy88M93