Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions apps/user-service/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,33 @@ dependencies {
testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.5'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.testcontainers:junit-jupiter'
testImplementation 'org.testcontainers:mariadb'
testImplementation 'com.h2database:h2'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

tasks.named('test') {
useJUnitPlatform {
// 기본적으로는 e2e 태그 제외하고 실행
excludeTags 'e2e'
}
systemProperty 'spring.profiles.active', 'test-unit'
}

// E2E 테스트 전용 task 추가
tasks.register('e2eTest', Test) {
useJUnitPlatform {
includeTags 'e2e'
}

systemProperty 'spring.profiles.active', 'test-e2e'

// E2E 테스트는 더 긴 시간 허용
timeout = Duration.ofMinutes(10)
}

// 모든 테스트 실행 task
tasks.register('allTests', Test) {
useJUnitPlatform()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import lombok.extern.slf4j.Slf4j;

@Service
@Profile({"unit-test", "local", "develop"})
@Profile({"test-unit", "test-e2e", "local", "develop"})
@Slf4j
public class MockEmailService implements EmailService {

Expand Down
13 changes: 13 additions & 0 deletions apps/user-service/src/main/resources/application-test-e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
spring:
config:
activate:
on-profile: test-e2e

mybatis:
mapper-locations: classpath:mybatis/mapper/**/*.xml
type-aliases-package: com.gltkorea.icebang.dto
configuration:
map-underscore-to-camel-case: true

logging:
config: classpath:log4j2-production.yml
48 changes: 48 additions & 0 deletions apps/user-service/src/main/resources/application-test-unit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# src/test/resources/application-test-unit.yml
spring:
config:
activate:
on-profile: test-unit

# H2 인메모리 데이터베이스 설정 (Unit Test용)
datasource:
url: jdbc:h2:mem:testdb;MODE=MariaDB;DB_CLOSE_DELAY=-1;DATABASE_TO_LOWER=TRUE
username: sa
password:
driver-class-name: org.h2.Driver
hikari:
connection-init-sql: "SET MODE MariaDB"
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
maximum-pool-size: 10
minimum-idle: 5
pool-name: HikariCP-MyBatis

# H2 웹 콘솔 활성화 (디버깅용)
h2:
console:
enabled: true

# JPA 설정 (H2용)
jpa:
hibernate:
ddl-auto: create-drop
show-sql: true
properties:
hibernate:
dialect: org.hibernate.dialect.H2Dialect

# SQL 스크립트 초기화 설정
sql:
init:
mode: embedded

mybatis:
mapper-locations: classpath:mybatis/mapper/**/*.xml
type-aliases-package: com.gltkorea.icebang.dto
configuration:
map-underscore-to-camel-case: true

logging:
config: classpath:log4j2-test-unit.yml
34 changes: 0 additions & 34 deletions apps/user-service/src/main/resources/application-test.yml

This file was deleted.

126 changes: 126 additions & 0 deletions apps/user-service/src/main/resources/log4j2-production.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
Configuration:
name: develop

properties:
property:
- name: "log-path"
value: "./logs"
- name: "charset-UTF-8"
value: "UTF-8"
# 통일된 콘솔 패턴 - 모든 로그에 RequestId 포함
- name: "console-layout-pattern"
value: "%highlight{[%-5level]} [%X{traceId}] %d{MM-dd HH:mm:ss} [%t] %n %msg%n%n"
# 파일용 상세 패턴 - RequestId 포함
- name: "file-layout-pattern"
value: "[%X{traceId}] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"
# 로그 파일 경로들
- name: "info-log"
value: ${log-path}/user-service/info.log
- name: "error-log"
value: ${log-path}/user-service/error.log
- name: "auth-log"
value: ${log-path}/user-service/auth.log
- name: "json-log"
value: ${log-path}/user-service/json-info.log

# [Appenders] 로그 기록방식 정의
Appenders:
# 통일된 콘솔 출력
Console:
name: console-appender
target: SYSTEM_OUT
PatternLayout:
pattern: ${console-layout-pattern}

# 롤링 파일 로그
RollingFile:
name: rolling-file-appender
fileName: ${log-path}/rolling-file.log
filePattern: "logs/archive/rolling-file.log.%d{yyyy-MM-dd-hh-mm}_%i.gz"
PatternLayout:
charset: ${charset-UTF-8}
pattern: ${file-layout-pattern}
Policies:
SizeBasedTriggeringPolicy:
size: "200KB"
TimeBasedTriggeringPolicy:
interval: "1"
DefaultRollOverStrategy:
max: "30"
fileIndex: "max"

# 파일 로그들
File:
- name: file-info-appender
fileName: ${info-log}
PatternLayout:
pattern: ${file-layout-pattern}
- name: file-error-appender
fileName: ${error-log}
PatternLayout:
pattern: ${file-layout-pattern}
- name: file-auth-appender
fileName: ${auth-log}
PatternLayout:
pattern: ${file-layout-pattern}
- name: file-json-info-appender
fileName: ${json-log}
PatternLayout:
pattern: ${file-layout-pattern}

# [Loggers] 로그 출력 범위를 정의
Loggers:
# [Loggers - Root] 모든 로그를 기록하는 최상위 로그를 정의
Root:
level: OFF
AppenderRef:
- ref: console-appender
- ref: rolling-file-appender

# [Loggers - Loggers] 특정 패키지나 클래스에 대한 로그를 정의
Logger:
# 1. Spring Framework 로그
- name: org.springframework
additivity: "false"
level: DEBUG
AppenderRef:
- ref: console-appender
- ref: file-info-appender
- ref: file-error-appender

# 2. 애플리케이션 로그
- name: com.gltkorea.icebang
additivity: "false"
level: TRACE
AppenderRef:
- ref: console-appender
- ref: file-info-appender
- ref: file-error-appender

# 3. HikariCP 로그 비활성화
- name: com.zaxxer.hikari
level: OFF

# 4. Spring Security 로그 - 인증/인가 추적에 중요
- name: org.springframework.security
level: DEBUG
additivity: "false"
AppenderRef:
- ref: console-appender
- ref: file-auth-appender

# 5. 웹 요청 로그 - 요청 처리 과정 추적
- name: org.springframework.web
level: DEBUG
additivity: "false"
AppenderRef:
- ref: console-appender
- ref: file-info-appender

# 6. 트랜잭션 로그 - DB 작업 추적
- name: org.springframework.transaction
level: DEBUG
additivity: "false"
AppenderRef:
- ref: console-appender
- ref: file-info-appender
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
// @SpringBootTest
// @Import(TestcontainersConfiguration.class)
// @AutoConfigureTestDatabase(replace = Replace.NONE)
// @ActiveProfiles("test") // application-test.yml 설정을 활성화
// @ActiveProfiles("test") // application-test-unit.yml 설정을 활성화
// @Transactional // 테스트 후 데이터 롤백
// @Sql(
// scripts = {"classpath:sql/create-schema.sql", "classpath:sql/insert-user-data.sql"},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.gltkorea.icebang.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface E2eTest {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.gltkorea.icebang.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface UnitTest {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.gltkorea.icebang.config;

import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.MariaDBContainer;

@TestConfiguration(proxyBeanMethods = false)
public class E2eTestConfiguration {

@Bean
@ServiceConnection
MariaDBContainer<?> mariadbContainer() {
return new MariaDBContainer<>("mariadb:11.4")
.withDatabaseName("pre_process")
.withUsername("mariadb")
.withPassword("qwer1234");
}

@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry, MariaDBContainer<?> mariadb) {
// MariaDB 연결 설정
registry.add("spring.datasource.url", mariadb::getJdbcUrl);
registry.add("spring.datasource.username", mariadb::getUsername);
registry.add("spring.datasource.password", mariadb::getPassword);
registry.add("spring.datasource.driver-class-name", () -> "org.mariadb.jdbc.Driver");

// HikariCP 설정
registry.add("spring.hikari.connection-timeout", () -> "30000");
registry.add("spring.hikari.idle-timeout", () -> "600000");
registry.add("spring.hikari.max-lifetime", () -> "1800000");
registry.add("spring.hikari.maximum-pool-size", () -> "10");
registry.add("spring.hikari.minimum-idle", () -> "5");
registry.add("spring.hikari.pool-name", () -> "HikariCP-E2E");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.gltkorea.icebang.controller;

import org.springframework.boot.test.context.TestComponent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@TestComponent
@RestController
public class TestController {

@GetMapping("/api/health")
public String health() {
return "OK";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.gltkorea.icebang.support;

import org.junit.jupiter.api.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.ActiveProfiles;

import com.gltkorea.icebang.config.E2eTestConfiguration;

@Tag("e2e")
@Import(E2eTestConfiguration.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test-e2e")
public abstract class E2eTestSupport {

@LocalServerPort protected int port;

@Autowired protected TestRestTemplate restTemplate;

protected String getBaseUrl() {
return "http://localhost:" + port;
}

protected String getApiUrl(String path) {
return getBaseUrl() + "/api" + path;
}
}
Loading
Loading