본문 바로가기
IT/소프트웨어

🔍 테스트 통과했다고 끝? 진짜 전쟁은 배포 후에 시작된다

by DrKo83 2026. 1. 24.
300x250
반응형

테스트는 기본, 실전은 따로 있다

소프트웨어 개발에서 테스트는 필수죠. 단위 테스트, 통합 테스트, 성능 테스트까지 꼼꼼하게 작성하면 안심이 될 것 같지만, 실제로는 그렇지 않아요. 프로덕션 환경은 테스트 환경과 완전히 다르거든요.

사용자들의 예측 불가능한 행동, 갑작스러운 네트워크 장애, 하드웨어 리부팅까지. 이런 혼돈 속에서만 발견되는 버그들이 있어요. 아무리 테스트 커버리지가 높아도, 실제 운영 환경에서만 터지는 문제들은 따로 있더라고요.

제인 스트리트에서 개발하는 'Aria'라는 분산 시스템도 마찬가지였어요. 저지연 메시지 버스로, 강력한 순서 보장과 안정성을 자랑하는 시스템인데요. 점점 더 많은 팀이 사용하면서 장애 없이 운영해야 한다는 부담이 커졌죠.

온갖 테스트를 다 해봤지만

Aria 팀은 정말 다양한 테스트 기법을 활용했어요. 단위 테스트부터 시작해서, 네트워크를 시뮬레이션하는 통합 테스트, 랜덤 이벤트를 생성하는 Quickcheck 테스트, 버전 호환성 테스트, AFL을 활용한 퍼즈 테스트, 성능 회귀를 체크하는 야간 실험실 테스트, 그리고 스테이징 환경에서 서비스를 무작위로 재시작하는 카오스 테스트까지요.

특히 시뮬레이션된 네트워킹 테스트가 핵심이었어요. 모킹 없이도 빠르고 결정론적인 테스트를 작성할 수 있어서, 더 많은 엣지 케이스를 적은 노력으로 표현할 수 있었거든요. 덕분에 프로덕션 장애는 정말 드물었고, 매주 새로운 변경사항을 배포해도 안정적이었죠.

그런데도 버그가 발생하면 항상 "아, 이건 정말 까다로운 케이스네. 테스트할 생각을 못 했던 게 당연해" 하는 반응이 나왔어요. Quickcheck나 퍼즈 테스트도 결국 우리가 만든 인위적인 환경 안에서만 작동하고, 카오스 테스트는 겉핥기에 불과했거든요.

생각하지 못한 모든 것을 테스트하는 방법

그러던 중 Antithesis라는 플랫폼을 알게 됐어요. 이 서비스의 놀라운 점은 완전히 결정론적인 하이퍼바이저로 제어되는 가상 머신에서 시스템 전체를 실행한다는 거예요. 스케줄링과 네트워킹에 개입해서 약간의 혼돈을 만들고, 그 과정에서 시스템이 실패할 수 있는 상황을 찾아내죠.

더 좋은 건, 시스템을 변경할 필요가 없다는 점이에요. 네트워크, 파일 시스템, 공유 메모리까지 모두 현실적인 환경에서 실행되고, 실제 클라이언트 코드로 시스템과 상호작용할 수 있어요. 만약 프로세스가 크래시하거나 단언문이 실패하면, 그 상태로 되돌아가서 무엇이 잘못됐는지 자세히 분석할 수 있죠.

가트너에 따르면 2024년 글로벌 소프트웨어 테스팅 시장 규모는 약 600억 달러(약 78조 원)에 달하며, 2028년까지 연평균 7%씩 성장할 것으로 전망된다고 해요. 그만큼 테스트의 중요성이 커지고 있지만, 기존 방식의 한계도 명확해지고 있는 거죠.

첫 실행에서 바로 버그 발견

처음엔 반신반의했어요. 그런데 첫 실행에서 바로 두 개의 버그가 발견됐죠. 특히 한 버그는 불과 한 달 전에 추가된 코드에서 발생한 거였는데, 프로덕션에서 터질 가능성이 꽤 높았고 영향도 심각했어요.

설계할 때 이런 실패 가능성을 고려하긴 했지만, 코드에 간단한 버그가 숨어있었고 명시적인 테스트를 작성하는 걸 깜빡했던 거죠. 이런 게 바로 현실이에요. 아무리 경험 많은 개발자라도 모든 엣지 케이스를 미리 생각하긴 어렵거든요.

Antithesis의 API는 정말 우아해요. Docker 이미지와 컴포즈 파일만 제공하면, VM 안에서 docker compose up을 실행해줘요. 그런 다음 컨테이너에 실행 파일들을 담은 디렉토리를 만들면, Antithesis가 알아서 언제 어떻게 실행할지 결정하죠. 사용자나 관리자가 프로덕션에서 취할 만한 액션들을 정의해두면 되는 거예요.

실제로 발견된 치명적인 버그

어느 날 아침, 야간 테스트 결과를 확인하니 예상치 못한 컨테이너 종료가 발생했어요. 로그를 보니 "replicator" 서비스가 서버에 연결한 직후 예외를 발생시키고 크래시했더라고요. 손상된 데이터를 받은 것처럼 보였는데, 이건 절대 일어나선 안 되는 일이었죠.

Antithesis는 특정 실패 사례를 조사할 수 있는 도구도 제공해요. 시간을 조금 되돌려서 다른 입력으로 실행해보고, 다시 실패하는지 확인하는 거죠. 그 결과 크래시 약 6초 전에 뭔가 발생해서 재현 가능성이 매우 높은 상태가 됐다는 걸 알아냈어요.

로그를 추적해보니, Antithesis가 무작위로 다른 서비스를 죽였더라고요. 서버가 재시작되고, 클라이언트가 연결했고, 그다음 클라이언트가 손상된 데이터를 받았어요. 여기서 Antithesis의 디버거 환경이 빛을 발했어요. 노트북 스타일 스니펫을 작성해서 VM 안에서 실행할 수 있거든요. 크래시 1초 전으로 되돌아가서 tcpdump를 실행해 클라이언트와 서버 간 주고받은 정확한 트래픽을 캡처했죠.

버그의 정체

문제는 "tip-retransmitter" 서비스의 새 기능과 관련이 있었어요. 이 서비스는 메모리 내 링 버퍼에서 클라이언트에게 데이터를 제공하는데, 최근 데이터만 사용 가능해요. 오랫동안 잘 작동했지만, 최근 로컬 클라이언트뿐 아니라 다른 지역의 클라이언트도 서비스할 수 있도록 확장했거든요. 뭔가 새로운 동작에서 버그가 생긴 거였죠.

자세히 살펴보니, 클라이언트 요청이 유효한지 확인할 때 링 버퍼 상태에 대해 잘못된 가정을 하고 있었어요. 이 문제는 아주 특정한 조건에서만 나타났어요. 서버가 재시작되고 스냅샷을 로드한 후, 링 버퍼가 채워지기 전에, 클라이언트가 스냅샷 이전 데이터를 요청할 때요.

Antithesis가 정확히 이 상황을 재현했고, 서버는 에러 대신 링 버퍼의 빈 영역에서 NUL 바이트를 잘못 보냈던 거예요. 원래 코드가 작성될 때는 스냅샷이 존재하지 않아서 이 버그가 발생할 수 없었어요. 나중에 추가되면서 생긴 문제였죠.

까다로운 버그가 가진 모든 요소

이 버그는 정말 까다로운 버그의 모든 요소를 갖추고 있었어요. 서버가 재시작되고, 광고를 시작한 후 링 버퍼가 채워지기 전에 클라이언트가 연결해서 스냅샷 이전 데이터를 요청하는 특수한 상황이 필요했죠.

이미 프로덕션에서 오래 실행됐던 코드였지만, 서비스 디스커버리 메커니즘 때문에 버그가 숨겨져 있었어요. 기존 코드를 활용하다 보니 이 상황에 대한 새 테스트를 작성할 생각도 못 했고요. 게다가 손상된 데이터를 제공하는 거라 잠재적 영향이 정말 심각했어요.

다행히 Antithesis가 실제 문제가 되기 전에 버그를 잡아냈죠. 기능 완성 후 Antithesis 설정에 새 서비스를 추가한 직후 버그가 발견됐어요. 시간 차이가 짧아서 최근 변경사항이 원인이란 걸 알 수 있었죠.

만약 프로덕션에서 발생했다면 예외는 받았겠지만, 상황을 좁히기 위한 충분한 데이터가 없었을 거고, 작성한 수정이 실제 버그를 고치는지 검증할 방법도 없었을 거예요.

테스트 문화의 변화

Antithesis가 기존 테스트를 모두 대체하는 건 아니에요. 각 테스트 유형은 고유한 목적이 있거든요. 하지만 Antithesis가 우리가 생각하지 못했던 전체 시스템 시나리오를 테스트하는 방식은 그 자체로 마법 같아요.

덕분에 팀 문화에도 작은 변화가 생겼어요. Antithesis가 그 사이의 빈틈을 메워줄 거라 믿으며 더 야심찬 프로젝트를 추진할 수 있게 된 거죠. 맥킨지의 2024년 보고서에 따르면, 효과적인 테스팅 자동화를 도입한 기업들은 소프트웨어 배포 빈도가 평균 208% 증가하고, 변경 실패율은 50% 감소했다고 해요. 이런 수치는 Antithesis 같은 혁신적인 테스팅 도구의 가치를 잘 보여주는 거죠.

다음 단계는?

Antithesis는 Aria에 정말 유용했고, 이제 제인 스트리트 내 다른 애플리케이션에도 적용하기 시작했어요. 유사한 고신뢰성 분산 시스템들, 예를 들어 개발 중인 새 분산 객체 저장소 같은 곳에서요.

하지만 기회는 훨씬 많아요. Aria보다 테스팅 스토리가 덜 발전된 시스템에 사용하는 것도 기대돼요. 제인 스트리트의 모든 시스템이 목 네트워크와 타이밍 서비스를 사용해 멋진 결정론적 시뮬레이션 테스트를 구축한 건 아니거든요. 때로는 외부 소프트웨어에 의존하는 부분 때문에 그런 테스팅이 불가능하기도 해요. 하지만 그런 소프트웨어도 Antithesis에서는 쉽게 실행할 수 있죠.

에이전틱 코딩 툴 맥락에서도 큰 가능성이 있어요. 코딩 에이전트의 핵심 문제는 제대로 작동했다는 확신을 얻기 어렵다는 건데, Antithesis가 피드백 소스로서 그리고 그런 모델을 훈련하는 데 있어 큰 가능성을 보여주거든요.

투자로 이어진 파트너십

마지막으로 한 가지 더 말씀드릴게요. 제인 스트리트는 제품과 팀에 너무 감명받아서 투자하기로 했고, 결국 다음 펀딩 라운드를 리딩하게 됐어요. 이런 파트너십을 좋아하는 이유는 독특하고 우리 기술 문화와 잘 맞는 기술이기도 하지만, Antithesis가 피드백에 정말 개방적이고 자신들이 만드는 것에 열정적이기 때문이에요.

이건 제인 스트리트의 사모투자 접근법과도 일치해요. 기술을 깊이 이해하고 잠재력을 볼 수 있는 회사, 좋아하고 믿는 사람들이 일하는 곳, 그리고 우리 스스로 고객으로서 사용하고 싶은 제품을 만드는 곳에 장기 자본을 제공하는 거죠. Antithesis는 이 모든 조건을 충족해요.

개인적으로도 정말 기대돼요. Antithesis 팀과 함께 일하는 건 정말 즐거운 경험이거든요. 버그나 특정 동작에 대해 엔지니어들과 직접 이야기하고, UX에 대해 디자이너들과 논의할 수 있는 SaaS 제품을 써본 적이 없어요. 수많은 동료들이 제가 얼마나 멋지다고 칭찬하는지 들어야 했죠. 다음에 무엇을 발견할지 항상 이상하게도 기대돼요.

정리하자면

테스트는 소프트웨어 개발의 기본이지만, 프로덕션 환경의 혼돈 속에서만 발견되는 문제들이 있어요. 아무리 다양한 테스트 기법을 사용해도, 생각하지 못한 엣지 케이스는 항상 존재하죠. Antithesis는 결정론적 하이퍼바이저와 탐색 엔진을 통해 시스템 전체를 실제와 유사한 환경에서 테스트하고, 우리가 미처 생각지 못한 버그를 찾아내요. 제인 스트리트의 Aria 프로젝트에서 이미 입증됐고, 앞으로 더 많은 시스템과 에이전틱 코딩 툴에도 적용될 거예요. 단순히 테스트 도구를 넘어, 소프트웨어 개발 문화 자체를 바꾸는 혁신이라고 할 수 있죠.

300x250
반응형