배포 스크립트가 만든 심볼릭 링크가 제대로 걸렸는지 확인하는 검사를 만들었고 전부 통과했다. 그런데 애플리케이션은 그 파일을 못 읽고 있었다.
Table of contents
Open Table of contents
원인 — 있는 것과 해소되는 것
링크 자체는 걸려 있는데 가리키는 대상이 없었다. 내가 쓴 test -L 은 그것이 링크인지만 보고 가리키는 것이 존재하는지는 보지 않는 검사였다.
test(1) 매뉴얼대로 -L 은 링크 존재만 보고 -e 는 링크를 따라간 대상의 존재를 보므로 조건을 test -e 로 바꿨다. 검사가 무엇을 보는지를 확인하지 않은 채로 통과를 받아들인 것이 문제였다.
검증 — 대조군으로 한 확인
바꾼 검사가 제대로 잡는지를 대조군으로 확인했다. 일부러 ln -s /nonexistent broken 으로 깨진 링크를 만들어 -e 로 돌리니 실패가 나왔고 -L 로 돌리니 통과가 나왔다.
무엇이 다른지가 그 자리에서 드러났다. 통과가 나오면 실패해야 하는 입력으로 한 번 더 돌리는 절차가 이 확인의 핵심이었다.
같은 문제를 가진 다른 검사들
같은 눈으로 다른 검사도 봤다. curl -s 상태 확인이 %{http_code} 를 안 보고 있어서 오류 페이지가 와도 통과였다.
데이터베이스 검사도 붙는 것만 보고 우리 데이터베이스인지는 안 봤다. 상태 코드와 응답 내용을 둘 다 보게 하고 접속 후 SELECT DATABASE() 까지 확인하게 고쳤다.
주의 — 빈 출력과 0건의 함정
빈 출력을 통과로 보는 검사도 있었는데 명령 자체가 실패해도 빈 출력이 나온다. 명령 실패와 결과 없음을 나누도록 $? 를 먼저 확인하게 했다.
로그의 오류 건수를 세는 검사는 로그 파일이 없으면 세기가 실패하면서 값이 비어 비교가 이상해졌다. 파일이 있는지부터 확인하게 해서 0건이 정상인지 아무것도 안 본 것인지를 갈랐다.
조치 — 검사 목록과 실행 여부
두 가지 방법이 있었는데 검사를 하나씩 고치고 넘어가는 것과 검사마다 무엇을 보는지와 실패해야 하는 입력을 CHECKS.md 표로 적는 것이다. 뒤쪽을 골랐다. 이유는 고친 검사도 다음 사람이 무엇을 보는지 모르면 같은 통과를 또 믿어서다. 대신 새 검사를 만들 때마다 표 한 줄을 채워야 하는 것을 감수했다.
검사가 실제로 도는지도 확인했는데 배포에 붙여 둔 검사가 chmod +x 가 안 돼 실패하고도 배포가 안 멈추고 있었다. 명시적으로 bash -e 로 실행해 오류 시 중단되게 고친 뒤 검사가 돌았다는 사실 자체를 로그에 남겼다. 검사가 통과했다는 것과 검사가 돌았다는 것은 다르고 로그에 없으면 안 돈 것이다.
정리
- 검사가 무엇을 보는지 확인하지 않으면 통과가 의미 없다
- 링크는
test -L로 있는 것과test -e로 해소되는 것이 다르다 - 실패해야 하는 입력으로 한 번 더 돌려 검사가 잡는지 본다
- 응답은 상태 코드와 내용을 둘 다 본다
- 빈 출력을 통과로 보지 않고 명령 실패와 결과 없음을 나눈다
- 0건이 정상인지 아무것도 안 본 것인지 가른다
- 검사마다 무엇을 보는지와 대조군을 적어 둔다
- 검사가 통과했다는 것과 돌았다는 것은 다르다