잡상: 서버 코드 테스트 하기
작년 여름까지 작성했던 서버를 테스트하는 코드들은 대부분 이런 형태였다
- 클라이언트 API들을 래핑하는 부분을 만들고,
- 래핑된 클라이언트 API들을 호출해서 서버의 특정 부분이 동작하게하고,
- 클라이언트 단에서 서버의 반응을 관찰해서 제대로 동작하는지 확인하는 형태
이 방법의 문제는,
- 실제로 가능한 서버의 상태(state) 수에 비해 클라이언트에서 목격? 할 수 있는 상태 수가 턱없이 작다
- 서버의 특정 버그를 고립시키기 힘들다. 혹은 서버의 특정 버그가 어느 코드 부근에서 나타나는지 확정하기 힘들다.
등등의 문제가 있다. 대충 떠오른게 이정도니 좀 더 있겠지?
지난 주 + 이번 주 하면서 일단 서버를 직접 테스트하려고 몇 가지 작업을 했는데, 구체적으로는 다음과 같은 방향으로 진행 중이고 일부만 완성된 상태.
멀티 스레딩과 관련된 버그는 무시한다
혹은 대상으로 삼지 않는다. Intel TBB의 철학?적인 부분과도 연관된 것인데,
싱글 스레드에서 잡을 수 있는 버그를 모두 잡고 멀티스레드로 넘어가라
라는 것. 사실 이 둘 사이의 버그는 그 영역이 조금 다르고, 특히 멀티스레딩 쪽에서 발생하는 버그는 테스트 케이스보다는 무작위 테스트(더미 클라이언트 붙이기 등등)에서 찾기 쉬운 듯 하다. 그래서 원래의 로직을 싱글 스레드 기반의 테스트 코드들 위에서 돌 수 있게 한다.
네트웍 계층을 이상적인 것으로 본다
네트웍 만큼 성격이 불량한(?) 계층도 컴퓨터 공학에서 찾기가 좀 힘들 것이다. 다행히도 작업 중인 서버 개체들이 비슷한 프레임웍을 써서 그 부분을 래핑해서 이상적인 + 싱글스레드 기반의 무언가로 바꿔서 동작할 수 있게 만들었다.
전송을 하면,
메인 루프의 특정 시점에,
Socket->Send()
- (테스트 프레임웍의) 전송 큐에 전달
- 메인 루프로 돌아옴
같은 형태로 전송이 이뤄지고, 이에 대해서 큐를 처리하는 프레임웍의 코드에서,
- GQCS 에서 반환된 것처럼 처리 로직 쪽으로 넘기고
- 처리 로직은 실제 개발 중인 코드가 실행
이런 형태로 동작하게 했다 — 지만 아직 이 부분은 구현만 대충 되었고 전체가 돌아가는 중은 아님 (불완전?)
동기화 객체들은 테스트 프레임웍이 제어한다 — 싱글 스레드로 동작해도 _옳은 결과_가 나올 수 있게
첫번째랑 비슷한 맥락인데, 싱글 스레드로 돌아가게 제어해준다. 근데 이 부분의 작업이 좀 귀찮다 -_-;; 그래도 Producer–Consumer 패러다임으로 도는 것은 싱글 스레드로 대체해도 잘 돌기 때문에 별 무리없이(?) 이전이 되어가는 듯 … 다만 작업이 작업이다보니 원래의 프레임웍에서 내가 테스트하면서 제어하고싶은 부분은 새로 구현하다시피…물론 싱글 스레드라 쉽긴하다.
이렇게 하면 서버 객체 간 연결은 몰라도 서버와 특정 연결(다른 서버든 클라이언트든…)을 테스트 용 블랙박스 개념으로 만들 수 있는 것 같다 (아직까지는 잘 진행되는 중)
뭐 올해 목표이기도 하니, 앞으로 잘 진행해봐야지.