Skip to content

Diff of Dev Testing

Changes between revision 1 - Move developer docs from the repository onto the wiki (AhaWiki@1ed71b57) and revision 2 - schemaDump.sh 가 저장소 안 .env 대신 ~/.config/ahawiki 설정에서 자격증명을 읽는다(9-02 체크아웃 소실 때 사본만 없어졌다). dev 스키마가 운영에서 갱신된다는 실측도 기록
--- Dev Testing
+++ Dev Testing
@@ -11,50 +11,52 @@
  * `TestSchema` - `createAll()` 이 덤프에서 모든 테이블을 만든다. 골라 만든 부분집합이 아니다: 외래 키가 테이블들을 묶고 있고, 스펙이 자기가 필요하다고 믿는 것을 나열하는 것이 그 목록이 낡는 방식이다. 인메모리 DB 에서 안 쓰는 테이블은 비용이 없다.
 
 다른 것이 필요한 스펙은 공용 구성을 다시 적는 대신 거기에 얹는 것으로 말한다. `ApiV1FilterSpec` 은 진짜 필터 체인을 돌리므로 `play.http.filters` 만 덮고 나머지는 그대로 둔다.
 
 Guice 애플리케이션이 쓰는 데이터베이스 URL 과 직접 여는 `DriverManager` 연결의 URL 은 같은 `TestApplication.h2Url` 에서 와야 한다. 같은 이름의 철자 둘은 서로 다른 인메모리 데이터베이스 둘이고, 스펙은 불일치가 아니라 없는 테이블로 실패한다.
 
 == 스키마를 참으로 유지하기
 
 스키마를 바꾸면 `schemaDump.sh` 로 덤프를 새로 뜬다. 스펙은 자동으로 따라온다. 스펙이 의존하는 컬럼이 사라지면 조용히 낡는 사본 대신 실패하는 스펙으로 나타난다.
 
-스크립트는 `mysqldump` 가 쓰는 헤더를 지우는데, 지우는 이유가 둘이고 하나로 오해하기 쉽다. 호스트와 데이터베이스 이름은 공개 저장소에 있으면 안 되는 인프라 이름이라 `.env` 를 가리키는 자리로 바꾼다. 서버 버전·완료 시각·`AUTO_INCREMENT` 카운터는 실행마다 바뀌는 잡음일 뿐인데, 두면 안 바뀐 스키마가 diff 로 도착한다. "진짜" 헤더를 되찾겠다고 `sed` 하나를 지우면, 그 줄이 눌러 두고 있던 둘 중 하나가 되돌아온다.
+스크립트는 `mysqldump` 가 쓰는 헤더를 지우는데, 지우는 이유가 둘이고 하나로 오해하기 쉽다. 호스트와 데이터베이스 이름은 공개 저장소에 있으면 안 되는 인프라 이름이라 로컬 설정을 가리키는 자리로 바꾼다. 서버 버전·완료 시각·`AUTO_INCREMENT` 카운터는 실행마다 바뀌는 잡음일 뿐인데, 두면 안 바뀐 스키마가 diff 로 도착한다. "진짜" 헤더를 되찾겠다고 `sed` 하나를 지우면, 그 줄이 눌러 두고 있던 둘 중 하나가 되돌아온다.
 
 읽어 들일 때 손보는 것이 셋 있다. 각각 스키마에 대한 의견 차가 아니라 MySQL 과 H2 의 차이다:
 
 [[[#!Table tsv 1
 손본 것	왜
 외래 키를 `CREATE TABLE` 밖 `ALTER TABLE` 로	덤프는 알파벳 순이라 키가 아직 없는 테이블을 가리키기 일쑤다 — 게다가 `AccessLog` 와 `IpDeny` 는 서로를 참조해서 어떤 순서로도 안 된다
 `tinyint(1)` 을 `BOOLEAN` 으로	MySQL 에는 boolean 이 없어 `tinyint(1)` 로 덤프된다. 그대로 두면 H2 가 Integer 를 돌려주고 Boolean 을 기대하는 파서가 전부 실패한다
 유니크하지 않은 컬럼으로의 외래 키 제거	MySQL 은 아무 인덱스 접두로의 키를 받아 준다. H2 는 대상이 유니크해야 하고 그러려고 유니크 인덱스를 만든다 — `Page (site, name)` 에 그러면 페이지가 두 번째 revision 을 가질 수 없다
 ]]]
 
 셋째 것은 실제 fidelity 손실이다: `Page (site, name)` 으로의 키들은 테스트에서 강제되지 않는다. `TestSchema` 는 그것을 이름이 아니라 대상으로 정한다 — 대상이 유니크하지 않은 키는 전부 빠진다 — 그래서 개수는 덤프가 그때 담고 있는 만큼이지 여기 적어 둘 수는 없다. 2026-08-17 에는 셋이었다:
 
 [[[#!Vim bash
 grep -c 'REFERENCES `Page` (`site`, `name`)' schema/schema.sql
 ]]]
 
 그 밖의 모든 것 — 모든 `NOT NULL`, default, ENUM 값 목록 — 은 운영이 가진 그대로다.
 
 마지막 문장은 보기보다 무겁다. 덤프는 운영이 아니라 개발 스키마에서 뜨기 때문이다. 아래 `--check` 는 커밋된 파일을 그것이 나온 스키마와 비교한다; 그 스키마를 이 주장의 대상인 운영과 비교하는 것은 없다. 한쪽에만 적용된 evolution 은 스펙이 운영에 없는 모양을 테스트하게 만들고, `--check` 는 여전히 파일이 최신이라고 말한다.
 
+'''두 스키마는 결국 같아지지만, 언제인지는 모른다.''' 2026-09-03 실측 — `wiki_aha00a_com` 과 `wiki_aha00a_com_dev` 는 같은 서버의 다른 스키마이고, `Page` 22,748 대 22,747, `Site`·`User` 는 같다. 개발 쪽 `play_evolutions` 의 68·69 행은 '''적용 시각까지 운영과 같다''' — 개발이 운영에서 갱신되며 행을 그대로 물려받았다는 뜻이다. 그래서 evolution 을 배포한 9-02 에는 `--check` 가 그 테이블만큼 차이를 보고했고 하루 뒤에는 통과했다. 갱신이 언제 어떻게 도는지는 이 저장소에 적혀 있지 않으니, '''차이가 사라졌다고 해서 확인이 끝난 것은 아니다''' — 위 문단의 함정은 그대로다.
+
 확인은 덤프 한 번과 `diff` 하나다. 헤더가 맞아떨어지도록 같은 정리를 거치고, 운영 스키마는 운영 저장소가 기록한 호스트와 관리자 자격증명으로 떠서, 커밋된 파일과 비교한다:
 
 [[[#!Vim bash
 ssh <host> "mysqldump --defaults-file=<admin cnf> --default-character-set=utf8mb4 \
   --no-data --no-tablespaces --column-statistics=0 <production schema>" \
   | sed 's/ AUTO_INCREMENT=[0-9]*//g' \
   | sed 's/^-- Dump completed on .*//g' \
   | sed 's/Distrib [0-9]*.[0-9]*.[0-9]*, for .*/Distrib #.#.#, for OS/g' \
-  | sed 's/^-- Host: .*/-- Host: (from .env)    Database: (from .env)/' \
+  | sed 's/^-- Host: .*/-- Host: (from local config)    Database: (from local config)/' \
   | diff schema/schema.sql -
 ]]]
 
 2026-08-17 실측: 동일. 양쪽 다 24개 테이블 488줄. 두 스키마는 갈라지지 않았고, 갈라지면 이것이 알아내는 방법이다.
 
 == 이렇게 만들며 찾은 것
 
 이것이 대체한 손으로 쓴 사본은 운영과 열여섯 군데가 달랐다 — 정수 폭 아홉, VARCHAR(255) 로 선언된 TEXT 컬럼 둘, 진짜 컬럼이라면 거부할 `targetType` 을 스펙이 넣을 수 있도록 VARCHAR 로 선언된 ENUM 컬럼 셋, evolution 55 가 떨어뜨린 `UserSite` 테이블 하나.
 
 덤프로 바꾸자 이번에는 픽스처에서 더 나왔다: 스펙들이 `abbr` 없는 `Site` 행(운영에서는 `NOT NULL`, default 없음), 뒤에 `Page` 가 없는 `PageMeta` 행, 필수 컬럼 여덟 개가 빠진 `AccessLog` 행을 넣고 있었다. 전부, 그것을 받아 줄 만큼 느슨한 스키마를 상대로 통과해 온 것이다.
@@ -79,11 +81,11 @@
  * `schema/schema.sql` 갱신은 여전히 손으로 하는 단계이고, 아무도 덤프하지 않은 스키마 변경은 스펙을 어제의 모양으로 테스트하게 놔둔다. 실패 양상은 전보다 순하다 — 스펙마다 제각각의 발명품 대신 스위트 전체가 하나의 낡은 스키마에서 돈다 — 하지만 그것을 일어나게 만드는 것은 없다.
 
  지금 있는 것은 물어보는 방법이고, 초록 스위트를 믿기 전에 돌려 볼 만큼 싸다:
 
 [[[#!Vim bash
 sh ./schemaDump.sh --check
 ]]]
 
  라이브 스키마를 같은 정리를 거쳐 덤프해 커밋된 파일과 diff 하고, 다르면 그 차이와 함께 0 아닌 코드로 끝난다. 아무것도 쓰지 않는다. 두 경로가 한 함수에서 나오는 것은 일부러다: 그 파이프라인의 사본 둘은 `sed` 하나씩 갈라져, 검사가 있지도 않은 차이를 보고하기 시작한다.
 
- 빌드에 물려 놓지는 않았다. `.env` 와 닿는 데이터베이스가 필요해서, 자격증명 없는 기계의 테스트 실행이 엉뚱한 이유로 실패하게 된다.
+ 빌드에 물려 놓지는 않았다. 로컬 설정과 거기 적힌 데이터베이스가 필요해서, 자격증명 없는 기계의 테스트 실행이 엉뚱한 이유로 실패하게 된다.