rein's world

잡상: 서버 코드 테스트 하기

작년 여름까지 작성했던 서버를 테스트하는 코드들은 대부분 이런 형태였다

  • 클라이언트 API들을 래핑하는 부분을 만들고,
  • 래핑된 클라이언트 API들을 호출해서 서버의 특정 부분이 동작하게하고,
  • 클라이언트 단에서 서버의 반응을 관찰해서 제대로 동작하는지 확인하는 형태

이 방법의 문제는,

  • 실제로 가능한 서버의 상태(state) 수에 비해 클라이언트에서 목격? 할 수 있는 상태 수가 턱없이 작다
  • 서버의 특정 버그를 고립시키기 힘들다. 혹은 서버의 특정 버그가 어느 코드 부근에서 나타나는지 확정하기 힘들다.

등등의 문제가 있다. 대충 떠오른게 이정도니 좀 더 있겠지?

지난 주 + 이번 주 하면서 일단 서버를 직접 테스트하려고 몇 가지 작업을 했는데, 구체적으로는 다음과 같은 방향으로 진행 중이고 일부만 완성된 상태.

멀티 스레딩과 관련된 버그는 무시한다

혹은 대상으로 삼지 않는다. Intel TBB의 철학?적인 부분과도 연관된 것인데,

싱글 스레드에서 잡을 수 있는 버그를 모두 잡고 멀티스레드로 넘어가라

라는 것. 사실 이 둘 사이의 버그는 그 영역이 조금 다르고,  특히 멀티스레딩 쪽에서 발생하는 버그는 테스트 케이스보다는 무작위 테스트(더미 클라이언트 붙이기 등등)에서 찾기 쉬운 듯 하다. 그래서 원래의 로직을 싱글 스레드 기반의 테스트 코드들 위에서 돌 수 있게 한다.

네트웍 계층을 이상적인 것으로 본다

네트웍 만큼 성격이 불량한(?) 계층도 컴퓨터 공학에서 찾기가 좀 힘들 것이다. 다행히도 작업 중인 서버 개체들이 비슷한 프레임웍을 써서 그 부분을 래핑해서 이상적인 + 싱글스레드 기반의 무언가로 바꿔서 동작할 수 있게 만들었다.

전송을 하면,

메인 루프의 특정 시점에,

  1. Socket->Send()
  2. (테스트 프레임웍의) 전송 큐에 전달
  3. 메인 루프로 돌아옴

같은 형태로 전송이 이뤄지고, 이에 대해서 큐를 처리하는 프레임웍의 코드에서,

  1. GQCS 에서 반환된 것처럼 처리 로직 쪽으로 넘기고
  2. 처리 로직은 실제 개발 중인 코드가 실행

이런 형태로 동작하게 했다 — 지만 아직 이 부분은 구현만 대충 되었고 전체가 돌아가는 중은 아님 (불완전?)

동기화 객체들은 테스트 프레임웍이 제어한다 — 싱글 스레드로 동작해도 _옳은 결과_가 나올 수 있게

첫번째랑 비슷한 맥락인데, 싱글 스레드로 돌아가게 제어해준다. 근데 이 부분의 작업이 좀 귀찮다 -_-;; 그래도 Producer–Consumer 패러다임으로 도는 것은 싱글 스레드로 대체해도 잘 돌기 때문에 별 무리없이(?) 이전이 되어가는 듯 … 다만 작업이 작업이다보니 원래의 프레임웍에서 내가 테스트하면서 제어하고싶은 부분은 새로 구현하다시피…물론 싱글 스레드라 쉽긴하다.

이렇게 하면 서버 객체 간 연결은 몰라도 서버와 특정 연결(다른 서버든 클라이언트든…)을 테스트 용 블랙박스 개념으로 만들 수 있는 것 같다 (아직까지는 잘 진행되는 중)

뭐 올해 목표이기도 하니, 앞으로 잘 진행해봐야지.