코드를 읽다가 밖으로 빼기로 했던 설정값이 하드코딩된 채 남아 있는 것을 발견했다. 보고하려다 한 번 더 확인했는데, 그 체크아웃은 작업 브랜치였고 외부화 작업이 머지되기 전 시점이었다. 운영에는 이미 반영돼 있었다.
Table of contents
Open Table of contents
읽은 것이 도는 것이 아닐 때
같은 성격의 상황을 몇 가지 만났다. 로컬에 체크아웃된 브랜치가 몇 주 전 것이라 그 뒤에 들어간 변경이 안 보이는 경우가 가장 흔했고, 작업하는 저장소와 배포가 당겨 가는 저장소가 갈라져 있어서 아무리 머지하고 배포해도 반영되지 않는 경우도 있었다.
머신마다 같은 원격 별칭이 다른 서버를 가리키고 있던 적도 있다. 인자 없이 푸시하면 어디로 나가는지 알 수 없는 상태였다. 로컬 사본이 낡아서 원격에는 수십 커밋이 있는데 로컬에는 몇 개뿐인 경우에는 이력을 조사하고 그 작업이 없다고 결론지을 뻔했다.
읽은 함수가 분기 매핑에서 주석 처리돼 실제로는 절대 호출되지 않던 경우도 있었다. 전부 읽은 것과 도는 것이 다른 경우인데, 읽는 동안에는 그 차이가 드러나지 않는다는 점이 공통이다.
확인 항목
코드에서 무언가를 발견하면 단정하기 전에 몇 가지를 본다. 현재 브랜치가 무엇인지 확인하고, 알려진 머지 커밋이 지금 이력의 조상인지 확인한다.
git merge-base --is-ancestor <머지커밋> HEAD && echo "포함됨"
배포가 어디서 당겨 가는지도 본다. 원격 목록을 확인하고 주소 재작성 규칙이 걸려 있는지까지 보는데, 주소를 바꿨는데도 다른 경로로 나가고 있던 적이 있었기 때문이다. 로컬 이력만 보지 않고 원격 이력을 직접 조회하는 것도 여기 들어간다. 마지막으로 그 코드가 실제로 호출되는지 호출 지점을 역추적한다.
배포 후의 확인 순서
배포한 뒤에도 같은 문제가 있었다. 수정을 배포했는데 같은 오류가 계속 나서 배포가 안 됐거나 캐시 때문이라고 생각했는데, 확인해 보니 서버 파일에는 수정이 정확히 반영돼 있었다. 진짜 원인은 그 함수에 도달하기 전에 앞선 호출에서 같은 오류가 나는 것이었다.
그래서 배포 후 증상이 그대로면 순서를 정해 뒀다. 서버 파일에 수정이 반영됐는지를 먼저 직접 확인하고, 반영돼 있으면 그 지점보다 앞서 호출되는 것들을 훑는다. 같은 오류 메시지가 여러 곳에서 날 수 있다는 것을 전제로 두는 것이 요점이다. 메시지가 같다고 해서 발생 위치가 같지는 않다.
선언과 실제의 괴리
파일에 적힌 것과 실제 동작이 다른 경우도 몇 번 있었다. 의존성 선언에 적힌 런타임 버전으로 실행 환경을 판단했는데 실제로는 다른 버전이 돌고 있었고, 오류 메시지 형식이 그 버전에만 있는 것이라 뒤늦게 드러났다.
예시 설정 파일을 보고 운영 값을 단정한 적도 있다. 운영 설정은 저장소 밖에 있고 빌드할 때 당겨 오는 구조였는데 예시 파일의 값을 근거로 계획까지 세웠다. 공식 문서에 지원한다고 적힌 기능이 실제로는 동작하지 않아 한참 디버깅한 경우도 있었다.
선언과 예시와 문서는 전부 누군가가 그렇게 되기를 의도해 적어 둔 것이지 지금 그렇다는 관측이 아니다. 관측으로 쓰려면 실체를 한 번 더 확인해야 한다.
정리
- 코드에서 발견한 것을 운영 상태로 단정하기 전에 브랜치와 이력 포함 여부를 본다
- 작업하는 저장소와 배포가 당기는 저장소가 다를 수 있다
- 로컬 이력만 보면 원격 작업이 안 보이므로 원격을 직접 조회한다
- 읽은 코드가 실제로 호출되는지 호출 지점을 역추적한다
- 배포 후 증상이 그대로면 서버 파일을 직접 확인한다
- 반영돼 있으면 그 지점보다 앞선 호출을 훑는다
- 메시지가 같다고 발생 위치가 같지는 않다
- 선언과 예시와 문서는 의도이지 관측이 아니다