서버 하나의 일관성 점검을 했다. 본체 코드와 config.yaml과 config.example.yaml과 배포 스크립트 둘과 README.md를 한 번에 놓고 교차로 대조했더니 다섯 가지가 나왔다.
Table of contents
Open Table of contents
증상 — 도움말과 코드의 세 가지 불일치
첫째는 기본값이 어긋난 것으로, argparse 인자 정의의 help=에는 기본값이 0.7이라고 적혀 있는데 코드에서 실제로 쓰는 default=는 0.0이었다. 도움말을 읽고 기본값이 0.7이겠거니 하고 인자를 안 넘기면 0.0으로 동작하는데, 결과가 예상과 다른 것보다 왜 다른지 짐작할 단서가 없다는 쪽이 더 문제다.
둘째는 기본값이 아예 없는 인자였다. 값을 안 주면 None이 되고, 뒤에서 os.environ으로 채우려 하는데 그것도 없으면 유효하지 않은 값이라는 오류로 시작 자체가 실패한다. 기본값이 있으면 안 주고도 뜨는데 없으면 안 뜨니 처음 쓰는 사람이 그 자리에서 막힌다. 게다가 오류 문구가 값이 유효하지 않다고만 말해서 아무것도 안 넘겼다는 사실이 안 드러난다.
셋째는 도움말이 말한 동작이 코드에 아예 없는 경우로, --session-id를 안 주면 uuid4로 만들어 준다고 적혀 있는데 코드는 고정 문자열을 쓰고 있었고 생성하는 부분 자체가 어디에도 없었다.
원인 — 도움말이 낡는 이유
셋이 형태는 달라도 도움말이 코드를 따라가지 못했다는 같은 자리에서 나왔다. 처음에는 둘이 맞아 있었을 텐데 그 뒤로 코드만 고쳐지면서 벌어졌을 가능성이 크다.
도움말이 특히 잘 낡는 이유가 있다. 그것은 실행에 영향을 주지 않는 문자열이라 틀려도 아무것도 안 깨지고, 테스트도 문자열의 내용까지는 보지 않는다. 코드가 잘못되면 어딘가에서 터지지만 도움말이 잘못되면 조용하다.
주의 — 배포 스크립트의 누락과 삭제 위험
넷째는 배포 스크립트의 파일 목록에서 한 파일이 빠진 것인데, 다른 환경용 스크립트에는 그 파일이 들어 있었으니 의도적으로 뺀 것이 아니라 한쪽에만 누락된 것으로 보인다.
이런 종류가 진단하기 어렵다. 같은 설정이 한 환경에서는 되고 다른 환경에서는 안 된다는 말이 나오면 코드는 같으니 환경 문제로 의심하게 되는데, 실제 원인은 배포 목록에 있다. 코드가 아니라 배포 스크립트를 봐야 하는 종류의 증상이다.
다섯째는 deploy-prod.sh가 rsync --delete를 쓰면서 config.yaml을 --exclude에 안 넣은 것이었다. 로컬에 없고 서버에만 있는 파일은 그 옵션 때문에 지워진다. 다만 항상 터지지는 않는다. 로컬에도 그 파일이 있으면 덮어쓰는 데서 끝나고, 저장소를 새로 받아 그 파일이 없는 환경에서 배포할 때만 삭제가 일어난다.
조치 — 교차 대조가 찾아낸 것
이 다섯을 찾은 방법이 이 점검에서 남은 것이다. 한 파일씩 봐서는 절반밖에 안 나온다. 도움말과 코드의 불일치는 같은 파일 안에 있으니 그 파일만 봐도 찾을 수 있지만, 배포 목록에서 무엇이 빠졌는지는 그 스크립트만 봐서는 알 수 없다. 빠진 것은 거기에 없기 때문이다.
없는 것을 찾으려면 있어야 할 것의 목록이 따로 필요한데 그 목록을 만들어 주는 것이 같은 역할을 하는 다른 파일이었다. 두 배포 스크립트의 목록을 나란히 놓고 대조하니 빠진 파일이 바로 드러났다.
판단 기준 — 같은 역할끼리 비교한다
점검 방식에 두 가지 방법이 있었는데 파일을 하나씩 처음부터 읽는 것과 같은 역할을 하는 파일이 둘 이상 있으면 그것들을 먼저 diff로 대조하는 것이다. 뒤쪽을 골랐다. 이유는 빠진 것은 한 파일 안에 없어서다. 대신 짝이 없는 파일은 이 방식으로 못 보는 것을 감수했고 그것은 따로 읽었다. 차이가 나오면 그 차이가 의도적인지를 묻는 순서다.
환경이 달라서 생긴 차이면 그대로 두고 한쪽에만 빠진 것이면 고치는데, 이 구분을 묻는 것 자체가 점검이 된다. 차이를 발견하는 것보다 그 차이에 이유가 있는지를 확인하는 쪽이 실제로 시간이 드는 작업이었다.
정리
- 도움말에 적힌 기본값과 코드의 기본값이 다를 수 있다
- 도움말은 실행에 영향을 주지 않는 문자열이라 틀려도 아무것도 안 깨진다
- 테스트가 문자열 내용까지 보지 않으므로 이 종류는 조용히 낡는다
- 기본값이 없으면 시작 자체가 실패하고 오류 문구가 원인을 안 말한다
- 도움말이 말한 동작이 코드에 아예 없는 경우도 있다
- 배포 목록 누락은 그 환경에서만 터져서 환경 문제로 오인하기 쉽다
rsync --delete는 로컬에 파일이 없는 조건에서만 사고를 낸다- 빠진 것은 그 파일 안에 없으므로 한 파일만 봐서는 못 찾는다
- 같은 역할을 하는 파일을 대조하고 차이가 의도적인지 묻는다