Skip to content

Commit a9e9eb0

Browse files
authored
Merge pull request #545 from projects200/fix/CICD
fix(CICD) : 특정 테스트코드가 CI/CD 과정에서 배포 안되는 오류 수정
2 parents d337231 + 64338e7 commit a9e9eb0

File tree

6 files changed

+125
-94
lines changed

6 files changed

+125
-94
lines changed

.github/workflows/dev-server-cicd.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77

88
jobs:
99
backend-CI:
10-
runs-on: ubuntu-22.04
10+
runs-on: ubuntu-latest
1111

1212
# Testcontainers가 CI 환경에서 Docker를 잘 찾도록 환경 변수 추가
1313
env:

src/test/java/com/project200/undabang/common/message/impl/SlackMessageSenderTest.java

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,35 @@
22

33
import com.github.tomakehurst.wiremock.client.WireMock;
44
import com.project200.undabang.common.message.MessageSender;
5+
import com.project200.undabang.common.support.IntegrationTestSupport;
56
import com.project200.undabang.exercise.repository.ExerciseRepository;
67
import com.project200.undabang.policy.service.PolicyService;
78
import com.project200.undabang.score.validation.ExercisePolicyValidator;
89
import org.junit.jupiter.api.BeforeEach;
910
import org.junit.jupiter.api.DisplayName;
1011
import org.junit.jupiter.api.Nested;
1112
import org.junit.jupiter.api.Test;
12-
import org.slf4j.LoggerFactory;
1313
import org.springframework.beans.factory.annotation.Autowired;
1414
import org.springframework.boot.test.context.SpringBootTest;
1515
import org.springframework.test.context.DynamicPropertyRegistry;
1616
import org.springframework.test.context.DynamicPropertySource;
1717
import org.springframework.test.context.bean.override.mockito.MockitoBean;
18-
import org.testcontainers.containers.GenericContainer;
19-
import org.testcontainers.containers.output.Slf4jLogConsumer;
20-
import org.testcontainers.containers.wait.strategy.Wait;
21-
import org.testcontainers.junit.jupiter.Container;
22-
import org.testcontainers.junit.jupiter.Testcontainers;
23-
import org.testcontainers.utility.DockerImageName;
2418

2519
import java.util.concurrent.TimeUnit;
2620

2721
import static com.github.tomakehurst.wiremock.client.WireMock.*;
2822
import static org.awaitility.Awaitility.await;
2923

30-
@Testcontainers
24+
//@Testcontainers
3125
@SpringBootTest
32-
class SlackMessageSenderTest {
26+
class SlackMessageSenderTest extends IntegrationTestSupport {
3327

34-
@Container
35-
static GenericContainer<?> wiremockContainer = new GenericContainer<>(DockerImageName.parse("wiremock/wiremock:3.5.2-1"))
36-
.withExposedPorts(8080)
37-
.waitingFor(Wait.forHttp("/__admin/mappings").forStatusCode(200))
38-
.withCommand("--verbose")
39-
.withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger(SlackMessageSenderTest.class)));
28+
// @Container
29+
// static GenericContainer<?> wiremockContainer = new GenericContainer<>(DockerImageName.parse("wiremock/wiremock:3.5.2-1"))
30+
// .withExposedPorts(8080)
31+
// .waitingFor(Wait.forHttp("/__admin/mappings").forStatusCode(200))
32+
// .withCommand("--verbose")
33+
// .withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger(SlackMessageSenderTest.class)));
4034

4135
@Nested
4236
@SpringBootTest
@@ -57,13 +51,18 @@ class SlackEnabledIntegrationTest {
5751
static void overrideProperties(DynamicPropertyRegistry registry) {
5852
String webhookPath = "/mock/slack-webhook";
5953
registry.add("slack.webhook.url",
60-
() -> String.format("http://%s:%d%s", wiremockContainer.getHost(), wiremockContainer.getFirstMappedPort(), webhookPath));
54+
() -> String.format("http://%s:%d%s",
55+
WIREMOCK_CONTAINER.getHost(),
56+
WIREMOCK_CONTAINER.getFirstMappedPort(),
57+
webhookPath));
58+
// registry.add("slack.webhook.url",
59+
// () -> String.format("http://%s:%d%s", wiremockContainer.getHost(), wiremockContainer.getFirstMappedPort(), webhookPath));
6160
registry.add("slack.webhook.enabled", () -> "true");
6261
}
6362

6463
@BeforeEach
6564
void setUp() {
66-
WireMock.configureFor(wiremockContainer.getHost(), wiremockContainer.getFirstMappedPort());
65+
WireMock.configureFor(WIREMOCK_CONTAINER.getHost(), WIREMOCK_CONTAINER.getFirstMappedPort());
6766
WireMock.reset();
6867
}
6968

@@ -175,14 +174,19 @@ class SlackDisabledIntegrationTest {
175174
@DynamicPropertySource
176175
static void overrideProperties(DynamicPropertyRegistry registry) {
177176
String webhookPath = "/mock/slack-webhook";
177+
// registry.add("slack.webhook.url",
178+
// () -> String.format("http://%s:%d%s", wiremockContainer.getHost(), wiremockContainer.getFirstMappedPort(), webhookPath));
178179
registry.add("slack.webhook.url",
179-
() -> String.format("http://%s:%d%s", wiremockContainer.getHost(), wiremockContainer.getFirstMappedPort(), webhookPath));
180+
() -> String.format("http://%s:%d%s",
181+
WIREMOCK_CONTAINER.getHost(),
182+
WIREMOCK_CONTAINER.getFirstMappedPort(),
183+
webhookPath));
180184
registry.add("slack.webhook.enabled", () -> "false");
181185
}
182186

183187
@BeforeEach
184188
void setUp() {
185-
WireMock.configureFor(wiremockContainer.getHost(), wiremockContainer.getFirstMappedPort());
189+
WireMock.configureFor(WIREMOCK_CONTAINER.getHost(), WIREMOCK_CONTAINER.getFirstMappedPort());
186190
WireMock.reset();
187191
}
188192

src/test/java/com/project200/undabang/common/service/PictureServiceIntegrationTest.java

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.project200.undabang.common.entity.Picture;
55
import com.project200.undabang.common.entity.dto.PictureUploadParameters;
66
import com.project200.undabang.common.repository.PictureRepository;
7+
import com.project200.undabang.common.support.IntegrationTestSupport;
78
import com.project200.undabang.common.web.exception.CustomException;
89
import com.project200.undabang.common.web.exception.ErrorCode;
910
import com.project200.undabang.common.web.exception.S3UploadFailedException;
@@ -17,14 +18,9 @@
1718
import org.springframework.beans.factory.annotation.Value;
1819
import org.springframework.boot.test.context.SpringBootTest;
1920
import org.springframework.mock.web.MockMultipartFile;
20-
import org.springframework.test.context.DynamicPropertyRegistry;
21-
import org.springframework.test.context.DynamicPropertySource;
2221
import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
2322
import org.springframework.web.multipart.MultipartFile;
2423
import org.testcontainers.containers.localstack.LocalStackContainer;
25-
import org.testcontainers.junit.jupiter.Container;
26-
import org.testcontainers.junit.jupiter.Testcontainers;
27-
import org.testcontainers.utility.DockerImageName;
2824
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
2925
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
3026
import software.amazon.awssdk.regions.Region;
@@ -41,15 +37,15 @@
4137
import static org.assertj.core.api.Assertions.assertThatThrownBy;
4238
import static org.mockito.Mockito.*;
4339

44-
@Testcontainers
40+
//@Testcontainers
4541
@SpringBootTest
46-
public class PictureServiceIntegrationTest {
42+
public class PictureServiceIntegrationTest extends IntegrationTestSupport {
4743

48-
@Container
49-
static LocalStackContainer localStack = new LocalStackContainer(
50-
DockerImageName.parse("localstack/localstack:latest"))
51-
.withServices(LocalStackContainer.Service.S3)
52-
.withEnv("DEFAULT_REGION", "ap-northeast-2");
44+
// @Container
45+
// static LocalStackContainer localStack = new LocalStackContainer(
46+
// DockerImageName.parse("localstack/localstack:latest"))
47+
// .withServices(LocalStackContainer.Service.S3)
48+
// .withEnv("DEFAULT_REGION", "ap-northeast-2");
5349
@Autowired
5450
private PictureService pictureService;
5551
@Autowired
@@ -67,13 +63,13 @@ public class PictureServiceIntegrationTest {
6763
@MockitoSpyBean
6864
private PictureRepository pictureRepositorySpy;
6965

70-
@DynamicPropertySource
71-
static void overrideProperties(DynamicPropertyRegistry registry) {
72-
registry.add("spring.cloud.aws.s3.endpoint", () -> localStack.getEndpointOverride(LocalStackContainer.Service.S3).toString());
73-
registry.add("spring.cloud.aws.credentials.access-key", localStack::getAccessKey);
74-
registry.add("spring.cloud.aws.credentials.secret-key", localStack::getSecretKey);
75-
registry.add("spring.cloud.aws.region.static", localStack::getRegion);
76-
}
66+
// @DynamicPropertySource
67+
// static void overrideProperties(DynamicPropertyRegistry registry) {
68+
// registry.add("spring.cloud.aws.s3.endpoint", () -> localStack.getEndpointOverride(LocalStackContainer.Service.S3).toString());
69+
// registry.add("spring.cloud.aws.credentials.access-key", localStack::getAccessKey);
70+
// registry.add("spring.cloud.aws.credentials.secret-key", localStack::getSecretKey);
71+
// registry.add("spring.cloud.aws.region.static", localStack::getRegion);
72+
// }
7773

7874
@BeforeEach
7975
void setUp() {
@@ -82,9 +78,9 @@ void setUp() {
8278
pictureRepository.deleteAllInBatch();
8379

8480
S3Client s3 = S3Client.builder()
85-
.endpointOverride(localStack.getEndpointOverride(LocalStackContainer.Service.S3))
86-
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(localStack.getAccessKey(), localStack.getSecretKey())))
87-
.region(Region.of(localStack.getRegion()))
81+
.endpointOverride(LOCAL_STACK.getEndpointOverride(LocalStackContainer.Service.S3))
82+
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(LOCAL_STACK.getAccessKey(), LOCAL_STACK.getSecretKey())))
83+
.region(Region.of(LOCAL_STACK.getRegion()))
8884
.build();
8985
try {
9086
s3.createBucket(CreateBucketRequest.builder().bucket(BUCKET_NAME).build());

src/test/java/com/project200/undabang/common/service/S3ServiceTest.java

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.project200.undabang.common.service;
22

33
import com.project200.undabang.common.context.UserContextHolder;
4+
import com.project200.undabang.common.support.IntegrationTestSupport;
45
import org.junit.jupiter.api.BeforeAll;
56
import org.junit.jupiter.api.DisplayName;
67
import org.junit.jupiter.api.Test;
@@ -9,12 +10,7 @@
910
import org.springframework.beans.factory.annotation.Value;
1011
import org.springframework.boot.test.context.SpringBootTest;
1112
import org.springframework.mock.web.MockMultipartFile;
12-
import org.springframework.test.context.DynamicPropertyRegistry;
13-
import org.springframework.test.context.DynamicPropertySource;
1413
import org.testcontainers.containers.localstack.LocalStackContainer;
15-
import org.testcontainers.junit.jupiter.Container;
16-
import org.testcontainers.junit.jupiter.Testcontainers;
17-
import org.testcontainers.utility.DockerImageName;
1814
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
1915
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
2016
import software.amazon.awssdk.core.ResponseBytes;
@@ -31,36 +27,36 @@
3127
import static org.mockito.BDDMockito.given;
3228
import static org.mockito.Mockito.mockStatic;
3329

34-
@Testcontainers
30+
//@Testcontainers
3531
@SpringBootTest
36-
class S3ServiceTest {
32+
class S3ServiceTest extends IntegrationTestSupport {
3733

38-
@Container
39-
static LocalStackContainer localStack = new LocalStackContainer(
40-
DockerImageName.parse("localstack/localstack:latest"))
41-
.withServices(LocalStackContainer.Service.S3)
42-
.withEnv("DEFAULT_REGION", "ap-northeast-2");
34+
// @Container
35+
// static LocalStackContainer localStack = new LocalStackContainer(
36+
// DockerImageName.parse("localstack/localstack:latest"))
37+
// .withServices(LocalStackContainer.Service.S3)
38+
// .withEnv("DEFAULT_REGION", "ap-northeast-2");
4339
@Autowired
4440
private S3Service s3Service;
4541
@Autowired
4642
private S3Client s3Client;
4743
@Value("${app.s3.bucket-name}")
4844
private String BUCKET_NAME;
4945

50-
@DynamicPropertySource
51-
static void overrideProperties(DynamicPropertyRegistry registry) {
52-
registry.add("spring.cloud.aws.s3.endpoint", () -> localStack.getEndpointOverride(LocalStackContainer.Service.S3).toString());
53-
registry.add("spring.cloud.aws.credentials.access-key", localStack::getAccessKey);
54-
registry.add("spring.cloud.aws.credentials.secret-key", localStack::getSecretKey);
55-
registry.add("spring.cloud.aws.region.static", localStack::getRegion);
56-
}
46+
// @DynamicPropertySource
47+
// static void overrideProperties(DynamicPropertyRegistry registry) {
48+
// registry.add("spring.cloud.aws.s3.endpoint", () -> localStack.getEndpointOverride(LocalStackContainer.Service.S3).toString());
49+
// registry.add("spring.cloud.aws.credentials.access-key", localStack::getAccessKey);
50+
// registry.add("spring.cloud.aws.credentials.secret-key", localStack::getSecretKey);
51+
// registry.add("spring.cloud.aws.region.static", localStack::getRegion);
52+
// }
5753

5854
@BeforeAll
5955
static void beforeAll() {
6056
S3Client s3ClientForSetup = S3Client.builder()
61-
.endpointOverride(localStack.getEndpointOverride(LocalStackContainer.Service.S3))
62-
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(localStack.getAccessKey(), localStack.getSecretKey())))
63-
.region(Region.of(localStack.getRegion()))
57+
.endpointOverride(LOCAL_STACK.getEndpointOverride(LocalStackContainer.Service.S3))
58+
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(LOCAL_STACK.getAccessKey(), LOCAL_STACK.getSecretKey())))
59+
.region(Region.of(LOCAL_STACK.getRegion()))
6460
.build();
6561
try {
6662
s3ClientForSetup.createBucket(CreateBucketRequest.builder().bucket("my-test-image-bucket").build());
@@ -132,7 +128,7 @@ void uploadImageAndGetPublicUrlWithMetadata() {
132128

133129
// Then: 결과 검증
134130
assertThat(publicUrl).isNotNull();
135-
String expectedUrlPrefix = localStack.getEndpointOverride(LocalStackContainer.Service.S3).toString() + "/" + BUCKET_NAME + "/";
131+
String expectedUrlPrefix = LOCAL_STACK.getEndpointOverride(LocalStackContainer.Service.S3).toString() + "/" + BUCKET_NAME + "/";
136132
assertThat(publicUrl)
137133
.startsWith(expectedUrlPrefix)
138134
.endsWith(objectKey);
@@ -179,7 +175,7 @@ void uploadImageAndGetPublicUrlWithoutMetadata() {
179175

180176
// Then: 결과 검증
181177
assertThat(publicUrl).isNotNull();
182-
String expectedUrlPrefix = localStack.getEndpointOverride(LocalStackContainer.Service.S3).toString() + "/" + BUCKET_NAME + "/";
178+
String expectedUrlPrefix = LOCAL_STACK.getEndpointOverride(LocalStackContainer.Service.S3).toString() + "/" + BUCKET_NAME + "/";
183179
assertThat(publicUrl)
184180
.startsWith(expectedUrlPrefix)
185181
.endsWith(objectKey);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.project200.undabang.common.support;
2+
3+
import org.springframework.test.context.DynamicPropertyRegistry;
4+
import org.springframework.test.context.DynamicPropertySource;
5+
import org.testcontainers.containers.GenericContainer;
6+
import org.testcontainers.containers.localstack.LocalStackContainer;
7+
import org.testcontainers.containers.wait.strategy.Wait;
8+
import org.testcontainers.utility.DockerImageName;
9+
10+
public abstract class IntegrationTestSupport {
11+
12+
// 1. AWS용 LocalStack
13+
protected static final LocalStackContainer LOCAL_STACK;
14+
15+
// 2. [추가] Slack API용 WireMock
16+
protected static final GenericContainer<?> WIREMOCK_CONTAINER;
17+
18+
static {
19+
// --- LocalStack 초기화 ---
20+
LOCAL_STACK = new LocalStackContainer(DockerImageName.parse("localstack/localstack:latest"))
21+
.withServices(LocalStackContainer.Service.S3)
22+
.withEnv("DEFAULT_REGION", "ap-northeast-2");
23+
LOCAL_STACK.start();
24+
25+
// --- [추가] WireMock 초기화 ---
26+
WIREMOCK_CONTAINER = new GenericContainer<>(DockerImageName.parse("wiremock/wiremock:3.5.2-1"))
27+
.withExposedPorts(8080)
28+
.waitingFor(Wait.forHttp("/__admin/mappings").forStatusCode(200))
29+
.withCommand("--verbose");
30+
31+
WIREMOCK_CONTAINER.start();
32+
}
33+
34+
@DynamicPropertySource
35+
static void overrideProperties(DynamicPropertyRegistry registry) {
36+
// LocalStack 설정
37+
registry.add("spring.cloud.aws.s3.endpoint", () -> LOCAL_STACK.getEndpointOverride(LocalStackContainer.Service.S3).toString());
38+
registry.add("spring.cloud.aws.credentials.access-key", LOCAL_STACK::getAccessKey);
39+
registry.add("spring.cloud.aws.credentials.secret-key", LOCAL_STACK::getSecretKey);
40+
registry.add("spring.cloud.aws.region.static", LOCAL_STACK::getRegion);
41+
}
42+
}

0 commit comments

Comments
 (0)