필드 번호를 바꿨더니 옛 클라이언트가 조용히 틀린 값을 읽었다 · 계약 검사는 리뷰어가 아니라 스크립트가 한다 · 퀴즈
퀴즈: 검사는 스크립트가 한다
문항 6개. 정답과 해설은 풀어 본 뒤에 보여 드립니다.
호환성 검사기가 두 .proto 를 비교할 때 키로 삼아야 하는 것은?
- 필드 이름 — 사람이 읽는 계약이므로
- 메시지별 필드 번호 — 와이어에는 번호만 실리므로
- 선언 순서 — 직렬화 순서가 곧 번호이므로
- 타입 — 와이어 타입이 번호를 결정하므로
이름만 바뀐 필드(`note` → `memo`, 번호·타입 동일)를 오류가 아니라 경고로 두는 근거는?
- protoc 이 이름 변경을 자동으로 별칭 처리하기 때문에
- 이름 변경은 ProtoJSON 에서도 아무 영향이 없기 때문에
- 바이너리 와이어에는 이름이 없어 바이트가 한 비트도 바뀌지 않기 때문에
- 경고를 오류로 바꾸면 검사 시간이 두 배로 늘기 때문에
`id` 가 1 번에서 2 번으로 옮겨 갔다. 검사기가 `REMOVED_NOT_RESERVED 1` 과 `RENAMED #2` 를 함께 내는 대신 `RENUMBERED` 하나만 내야 하는 이유는?
- 원인이 하나이므로 한 줄로 알려야 사람이 고칠 곳을 바로 찾는다
- REMOVED 와 RENAMED 는 exit 코드에 영향을 주지 않아 무의미하다
- 번호 변경은 조건부 호환이라 낮은 심각도 하나로 합쳐야 한다
- 출력 줄 수가 많으면 CI 로그 크기 제한에 걸린다
옛 파일에 `reserved 10 to 12;` 가 있고 새 파일이 `string memo = 11;` 을 더했다. 검사기가 이것을 잡으려면?
- 새 파일의 reserved 목록에 11 이 있는지만 보면 된다
- 범위 예약은 protoc 만 이해하므로 검사기는 건너뛰어도 된다
- 11 은 옛 파일에 필드로 없었으니 안전한 추가로 통과시킨다
- 범위를 10, 11, 12 로 펴서 옛 파일의 예약 집합에 넣고 새 필드 번호를 대조한다
검사기의 출력 계약으로 옳은 것은?
- 위반이 있으면 exit 0 으로 끝내고 사람이 출력을 읽어 판단한다
- 위반은 한 줄에 하나, 있으면 exit 1, 없으면 마지막 줄 OK 와 exit 0, 경고는 exit 코드에 영향 없음
- 경고가 하나라도 있으면 exit 1 로 끝내 리뷰어의 주의를 끈다
- 결과를 JSON 파일로만 남기고 종료 코드는 항상 0 이다
어떤 검사기도 잡지 못하는 스키마 변경으로 문서가 따로 경고하는 것은?
- 중첩 메시지 안의 타입 변경
- reserved 없이 필드를 삭제하는 것
- 필드 기본값의 의미를 바꾸는 것 — 바이트도 스키마 텍스트도 그대로다
- 필드 번호를 19,000 번대에 두는 것