Github action에서 Backend 폴더에 코드 변화가 일어는 PR이 생성될 때 마다, Java 코드의 Junit5 Test를 실행시키기로 했다. 또한 이 테스트를 운영되는 MySQL DB에서 처리하기로 하였다.
로컬에서는 H2 Database를 사용하였고, 전혀 문제 없이 테스트 코드가 처리되었다. 하지만 PR을 날릴 때마다, 아래와 같은 문제가 발생하였다.
테스트 시 발생하는 Too many connections Error
먼저 문제를 파악하기 위해, CI에서 사용하는 yml 파일을 로컬로 옮겨 실행하였고 아래와 같은 결과를 얻었다.
이를 확인하기 위해, MySQL의 connection을 테스트환경을 돌리면서 감시해보았다.
여기서 문제가 발생하는 것이 맞았다. Threads_connected의 갯수가 테스트 도중 70개까지 폭증하게 되었다. 70개 이후로는 RDS 프리티어의 성능이 버티지 못하고, 오류를 뱉는 것으로 보였다.
그런데, 내가 알기로는 HikariCP의 default는 10개로 알고 있었다. 하지만 70개까지 폭증한 것을 보고 뭔가 문제 상황이 생긴 것을 파악했다.
먼저 문제는 테스트 코드였다.
위의 클래스에서 Mockmvc와 다른 ApplicationContext를 활용하기 위해 @SpringBootTest
어노테이션을 붙여 놓았는데, 이것이 문제 상황을 발생시켰다. 먼저 저 어노테이션은 ApplicationContext를 올려 Bean을 등록해주는 역할을 하는데, 각 Test 객체마다 달아놨으므로, HikariCP가 계속해서 생성되어 테스트 환경을 망치게 된 것이였다.
먼저 2번의 문제는 확실하게 해결해야했다. 이 오류가 생성된 근본적인 문제이였기 때문이다. 따라서 2번을 해결하려고 하였다. 하지만 문제가 발생하였는데, end-to-end Test나 여러가지의 경우는 실제로 ApplicationContext에 값을 올려야 하기 때문이었다. 그나마 end-to-end Test의 경우는 .http 정적 파일로 떨궈 Test를 실험해보는 방식으로 처리할 수 있으나, security configuration과 관련되어 테스트하는 경우는 저 어노테이션이 필요하였다. 따라서 지울 수 없는 부분이 생기기도 하고, 2번 만으로는 문제해결이 불가능할 것으로 보였다.
따라서 1, 3번의 해결책 중 하나를 채용해야했다.
하지만 2, 3번의 방법을 채택하기로 하였다. 잘 만든 테스트는 테스트 서버에서 잘 동작하면 실서버에서도 잘돌아가야하니 2, 3번을 채택하여 테스트용 서버를 따로 두는 느낌으로 가기로 하였다.