토이 프로젝트 스터디 #14
- 스터디 진행 날짜 : 6/28
- 스터디 작업 날짜 : 6/25 ~ 6/28
토이 프로젝트 진행 사항
AWS S3
로컬 테스트를 위해 LocalStack
적용
내용
LocalStack
// build.gradle
testImplementation 'org.testcontainers:localstack:1.16.3'
build.gradle
에 LocalStack
추가
spring:
main:
allow-bean-definition-overriding: true
AWS
객체를 Mocking
하기 위해 스프링 빈 오버라이딩 옵션 true
로 설정
@Profile("test")
@Configuration
public class LocalStackS3Config {
DockerImageName localstackImage = DockerImageName.parse("localstack/localstack");
@Bean(initMethod = "start", destroyMethod = "stop")
public LocalStackContainer localStackContainer() {
return new LocalStackContainer(localstackImage)
.withServices(LocalStackContainer.Service.S3);
}
@Bean
public AmazonS3Client amazonS3Client(LocalStackContainer localStackContainer) {
return (AmazonS3Client) AmazonS3ClientBuilder.standard()
.withEndpointConfiguration(localStackContainer.getEndpointConfiguration(LocalStackContainer.Service.S3))
.withCredentials(localStackContainer.getDefaultCredentialsProvider())
.build();
}
@Bean
public ImageUtils ImageUtils(LocalStackContainer localStackContainer) {
return new S3ImageUtils(amazonS3Client(localStackContainer));
}
@Bean
ServletWebServerFactory servletWebServerFactory(){
return new TomcatServletWebServerFactory();
}
}
- 스프링 빈을 오버라이딩할 테스트용 설정 추가
@TestConfiguration
사용 시 기존 스프링 빈을 사용하는 문제로 인해 test profile
에서만 실행되도록 변경
docker-compose
로 실행 시 ServletWebServerFactory
를 찾지 못하는 오류로 인해 직접 스프링 빈으로 등록
@ActiveProfiles("test")
@DisplayName("LocalStackS3Test 테스트")
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = LocalStackS3Config.class)
class LocalStackS3Test {
@Value("${cloud.aws.s3.bucket}")
String bucket;
@Autowired
AmazonS3Client amazonS3Client;
@BeforeEach
void beforeEach() {
amazonS3Client.createBucket(bucket);
}
@Test
void s3_이미지_업로드_테스트() throws IOException {
String content = "hello world";
String key = "s3-key";
amazonS3Client.putObject(bucket, key, content);
List<String> result = IOUtils.readLines(amazonS3Client.getObject(bucket, key).getObjectContent(), "utf-8");
assertEquals(1, result.size());
assertEquals(content, result.get(0));
}
}
- 정상적으로 테스트가 통과하는 것을 확인할 수 있음
문제점
LocalStack
을 로컬 환경에서도 Mocking
해서 사용하고자 적용시키려고 함
[containers-ryuk] o.testcontainers.utility.ResourceReaper : Can not connect to Ryuk at 172.17.0.1:50701
- 로컬이 아닌
docker
환경에서 실행 시 위와 같은 문제 발생
- 정상적으로
Testcontainers
와 스프링 부트 애플리케이션이 실행되고 있음
- 문제는 포트로, 호스트에서
docker
로 접속할 때에는 50701
로 접속해야 하지만 docker
내부의 디폴트 네트워크로는 기존 포트인 8080
으로 접속해야 한다고 추측
version: "3.7"
services:
database:
container_name: postgres
image: postgres:latest
restart: always
ports:
- 5432:5432
environment:
POSTGRES_DB: board_db
POSTGRES_USER: board
POSTGRES_PASSWORD: board
volumes:
- /Users/labtop/intellij/docker-postgres/:/var/lib/postgresql/data
cache:
container_name: redis
image: redis:alpine
ports:
- 6379:6379
volumes:
- /Users/labtop/intellij/docker-redis/:/data
application:
container_name: board
build:
context: .
dockerfile: Dockerfile
ports:
- 8085:8085
environment:
SPRING_DATASOURCE_URL: jdbc:postgresql://database:5432/board_db
SPRING_DATASOURCE_USERNAME: board
SPRING_DATASOURCE_PASSWORD: board
depends_on:
- database
- cache
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- 현재
docker-compose.yml
의 상태는 위와 같음
LocalStack
에 대한 설정이 없기 때문에 어떤 식으로 올바른 testcontainers
의 포트를 바인딩해야 할지 해결하지 못한 상태