토이 프로젝트 스터디 #14

appti·2022년 6월 28일
0

토이 프로젝트 스터디 #14

  • 스터디 진행 날짜 : 6/28
  • 스터디 작업 날짜 : 6/25 ~ 6/28

토이 프로젝트 진행 사항

  • AWS S3 로컬 테스트를 위해 LocalStack 적용

내용

LocalStack

// build.gradle

testImplementation 'org.testcontainers:localstack:1.16.3'
  • build.gradleLocalStack 추가
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 {
        // given
        String content = "hello world";
        String key = "s3-key";

        // when
        amazonS3Client.putObject(bucket, key, content);
        List<String> result = IOUtils.readLines(amazonS3Client.getObject(bucket, key).getObjectContent(), "utf-8");

        // then
        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의 포트를 바인딩해야 할지 해결하지 못한 상태
profile
안녕하세요

0개의 댓글