init: 클린 기반 auth 서버 설계

This commit is contained in:
DongHyeonka
2026-07-24 14:30:18 +09:00
parent 471db0203d
commit 8a1ac1e769
3642 changed files with 275893 additions and 1 deletions
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.project.auth.AuthApplicationTests" tests="1" skipped="0" failures="0" errors="0" timestamp="2026-05-12T06:59:36.447Z" hostname="donghyeon-960XGK" time="0.011">
<properties/>
<testcase name="contextLoads()" classname="com.project.auth.AuthApplicationTests" time="0.004"/>
<system-out><![CDATA[2026-05-12T15:59:36.448+09:00 DEBUG 3742337 --- [ Test worker] [traceId=] .b.t.c.SpringBootTestContextBootstrapper : Neither @ContextConfiguration nor @ContextHierarchy found for test class [AuthApplicationTests]: using SpringBootContextLoader
2026-05-12T15:59:36.449+09:00 INFO 3742337 --- [ Test worker] [traceId=] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.project.auth.AuthApplicationTests]: AuthApplicationTests does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
2026-05-12T15:59:36.449+09:00 DEBUG 3742337 --- [ Test worker] [traceId=] .b.t.c.SpringBootTestContextBootstrapper : Using ContextCustomizerFactory implementations for test class [AuthApplicationTests]: [SpringBootTestRandomPortContextCustomizerFactory, OnFailureConditionReportContextCustomizerFactory, OverrideAutoConfigurationContextCustomizerFactory, ImportsContextCustomizerFactory, PropertyMappingContextCustomizerFactory, ExcludeFilterContextCustomizerFactory, TypeExcludeFiltersContextCustomizerFactory, DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactory, DuplicateJsonObjectContextCustomizerFactory, BeanOverrideContextCustomizerFactory, MockServerContainerContextCustomizerFactory, DynamicPropertiesContextCustomizerFactory]
2026-05-12T15:59:36.450+09:00 DEBUG 3742337 --- [ Test worker] [traceId=] .b.t.c.SpringBootTestContextBootstrapper : Using ContextCustomizers for test class [AuthApplicationTests]: [SpringBootTestRandomPortContextCustomizer, OnFailureConditionReportContextCustomizer, PropertyMappingContextCustomizer, ExcludeFilterContextCustomizer, DuplicateJsonObjectContextCustomizer, DynamicPropertiesContextCustomizer]
2026-05-12T15:59:36.451+09:00 INFO 3742337 --- [ Test worker] [traceId=] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.project.auth.AuthApplication for test class com.project.auth.AuthApplicationTests
2026-05-12T15:59:36.452+09:00 DEBUG 3742337 --- [ Test worker] [traceId=] .b.t.c.SpringBootTestContextBootstrapper : Using TestExecutionListeners for test class [AuthApplicationTests]: [ServletTestExecutionListener, DirtiesContextBeforeModesTestExecutionListener, ApplicationEventsTestExecutionListener, BeanOverrideTestExecutionListener, DependencyInjectionTestExecutionListener, DirtiesContextTestExecutionListener, CommonCachesTestExecutionListener, TransactionalTestExecutionListener, SqlScriptsTestExecutionListener, WithSecurityContextTestExecutionListener, EventPublishingTestExecutionListener, ReactorContextTestExecutionListener, MockitoResetTestExecutionListener]
]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" tests="25" skipped="0" failures="0" errors="0" timestamp="2026-05-12T06:59:46.185Z" hostname="donghyeon-960XGK" time="3.738">
<properties/>
<testcase name="all_client_facing_error_codes_have_unique_string_codes()" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.014"/>
<testcase name="unmapped_client_facing_error_code_implementation_falls_back_to_500()" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.002"/>
<testcase name="exact_mapping_table_must_cover_every_client_facing_error_code_enum_value()" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.002"/>
<testcase name="INTERNAL_SERVER_ERROR -&gt; 500 INTERNAL_SERVER_ERROR" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.007"/>
<testcase name="AUTHENTICATION_REQUIRED -&gt; 401 UNAUTHORIZED" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.001"/>
<testcase name="ACCESS_DENIED -&gt; 403 FORBIDDEN" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.0"/>
<testcase name="KEYCLOAK_CLAIMS_INVALID -&gt; 400 BAD_REQUEST" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.0"/>
<testcase name="KEYCLOAK_USER_NOT_FOUND -&gt; 404 NOT_FOUND" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.001"/>
<testcase name="KEYCLOAK_ACCOUNT_CONFLICT -&gt; 409 CONFLICT" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.0"/>
<testcase name="INVALID_INPUT -&gt; 400 BAD_REQUEST" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.0"/>
<testcase name="INVALID_REQUEST_BODY -&gt; 400 BAD_REQUEST" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.0"/>
<testcase name="MISSING_PARAMETER -&gt; 400 BAD_REQUEST" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.001"/>
<testcase name="CONSTRAINT_VIOLATION -&gt; 400 BAD_REQUEST" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.001"/>
<testcase name="MISSING_HEADER -&gt; 400 BAD_REQUEST" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.001"/>
<testcase name="REQUEST_BINDING_FAILED -&gt; 400 BAD_REQUEST" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.001"/>
<testcase name="METHOD_NOT_ALLOWED -&gt; 405 METHOD_NOT_ALLOWED" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.001"/>
<testcase name="RESOURCE_NOT_FOUND -&gt; 404 NOT_FOUND" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.001"/>
<testcase name="UNSUPPORTED_MEDIA_TYPE -&gt; 415 UNSUPPORTED_MEDIA_TYPE" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.001"/>
<testcase name="NOT_ACCEPTABLE -&gt; 406 NOT_ACCEPTABLE" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.001"/>
<testcase name="PAYLOAD_TOO_LARGE -&gt; 413 CONTENT_TOO_LARGE" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.001"/>
<testcase name="MESSAGE_NOT_WRITABLE -&gt; 500 INTERNAL_SERVER_ERROR" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.001"/>
<testcase name="UNHANDLED_CLIENT_ERROR -&gt; 400 BAD_REQUEST" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.008"/>
<testcase name="TYPE_MISMATCH -&gt; 400 BAD_REQUEST" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.001"/>
<testcase name="INVALID_PARAMETER -&gt; 400 BAD_REQUEST" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="0.0"/>
<testcase name="every_client_facing_error_code_implementation_on_classpath_is_covered_by_the_table()" classname="com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest" time="3.617"/>
<system-out><![CDATA[2026-05-12T15:59:46.202+09:00 WARN 3742337 --- [ Test worker] [traceId=] c.p.a.p.s.e.ApiErrorHttpStatusMapper : Unmapped ClientFacingErrorCode reached default branch. type=com.project.auth.architecture.ApiErrorHttpStatusMapperClientFacingCoverageTest$1 code=UNKNOWN-001 -> falling back to 500
2026-05-12T15:59:46.344+09:00 INFO 3742337 --- [ Test worker] [traceId=] com.tngtech.archunit.core.PluginLoader : Detected Java version 21.0.10
]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.project.auth.config.auth.security.KeycloakJwtAuthenticationConverterTest" tests="1" skipped="0" failures="0" errors="0" timestamp="2026-05-12T06:59:49.923Z" hostname="donghyeon-960XGK" time="0.012">
<properties/>
<testcase name="convertMapsKeycloakClaimsAndRealmRolesToProjectPrincipal()" classname="com.project.auth.config.auth.security.KeycloakJwtAuthenticationConverterTest" time="0.011"/>
<system-out><![CDATA[]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.project.auth.config.logging.AuthAuditLoggingConfigurationTest" tests="1" skipped="0" failures="0" errors="0" timestamp="2026-05-12T06:59:49.936Z" hostname="donghyeon-960XGK" time="0.015">
<properties/>
<testcase name="writesAuditEventFieldsAsStructuredKeyValuesInsteadOfFlattenedMessage()" classname="com.project.auth.config.logging.AuthAuditLoggingConfigurationTest" time="0.014"/>
<system-out><![CDATA[2026-05-12T15:59:49.939+09:00 WARN 3742337 --- [ Test worker] [traceId=0123456789abcdef0123456789abcdef] audit.auth : LOGIN_FAILURE eventType="LOGIN_FAILURE" emailMasked="al***@example.com" provider="LOCAL" reason="invalid_password"
]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.project.auth.config.logging.LoggingConfigurationSmokeTest" tests="3" skipped="0" failures="0" errors="0" timestamp="2026-05-12T06:59:49.952Z" hostname="donghyeon-960XGK" time="0.083">
<properties/>
<testcase name="prodStructuredLogstashEncoderWritesMdcAndEventFieldsAsTopLevelJsonMembers()" classname="com.project.auth.config.logging.LoggingConfigurationSmokeTest" time="0.06"/>
<testcase name="logbackRoutesStructuredConsoleForProdAndMakesAuditFileOptIn()" classname="com.project.auth.config.logging.LoggingConfigurationSmokeTest" time="0.002"/>
<testcase name="profileYamlLocksStructuredLoggingProxyTrustAndDevActuatorContract()" classname="com.project.auth.config.logging.LoggingConfigurationSmokeTest" time="0.019"/>
<system-out><![CDATA[2026-05-12T15:59:50.019+09:00 DEBUG 3742337 --- [ Test worker] [traceId=] o.s.boot.env.OriginTrackedYamlLoader : Loading from YAML: file [/home/donghyeon/dev/Project-Auth-Server/bootstrap/src/main/resources/application.yml]
2026-05-12T15:59:50.029+09:00 DEBUG 3742337 --- [ Test worker] [traceId=] o.s.boot.env.OriginTrackedYamlLoader : Merging document (no matchers set): {spring={application={name=project-auth-server}, profiles={default=local}, flyway={enabled=false}, jpa={open-in-view=false, properties={hibernate={format_sql=true, default_schema=auth, jdbc={time_zone=UTC}}}}}, server={forward-headers-strategy=native, tomcat={remoteip={internal-proxies=${SERVER_TOMCAT_REMOTEIP_INTERNAL_PROXIES:10\.[0-9]+\.[0-9]+\.[0-9]+|192\.168\.[0-9]+\.[0-9]+|172\.(1[6-9]|2[0-9]|3[0-1])\.[0-9]+\.[0-9]+|127\.[0-9]+\.[0-9]+\.[0-9]+}}}}, app={docs={title=${APP_DOCS_TITLE:Project Auth Server API}, description=${APP_DOCS_DESCRIPTION:인증 서버의 OpenAPI 문서입니다.}, version=${APP_DOCS_VERSION:v1}}, logging={audit={file=${APP_LOGGING_AUDIT_FILE:./logs/audit/auth.log}, max-history=${APP_LOGGING_AUDIT_MAX_HISTORY:30}, max-file-size=${APP_LOGGING_AUDIT_MAX_FILE_SIZE:50MB}, total-size-cap=${APP_LOGGING_AUDIT_TOTAL_SIZE_CAP:2GB}}, access={excluded-path-prefixes=[/actuator, /livez, /readyz, /swagger-ui, /v3/api-docs, /favicon.ico]}}, persistence={migration={location=${APP_PERSISTENCE_MIGRATION_LOCATION:classpath:db/migration}, schema=${APP_PERSISTENCE_MIGRATION_SCHEMA:auth}}}}, springdoc={swagger-ui={path=/swagger-ui.html}}, management={endpoints={web={exposure={include=health}}}, endpoint={health={show-details=never, probes={enabled=true, add-additional-paths=true}}}}}
2026-05-12T15:59:50.030+09:00 DEBUG 3742337 --- [ Test worker] [traceId=] o.s.boot.env.OriginTrackedYamlLoader : Loaded 1 document from YAML resource: file [/home/donghyeon/dev/Project-Auth-Server/bootstrap/src/main/resources/application.yml]
2026-05-12T15:59:50.031+09:00 DEBUG 3742337 --- [ Test worker] [traceId=] o.s.boot.env.OriginTrackedYamlLoader : Loading from YAML: file [/home/donghyeon/dev/Project-Auth-Server/bootstrap/src/main/resources/application-prod.yml]
2026-05-12T15:59:50.032+09:00 DEBUG 3742337 --- [ Test worker] [traceId=] o.s.boot.env.OriginTrackedYamlLoader : Merging document (no matchers set): {spring={config={activate={on-profile=prod}}, datasource={url=${APP_DATASOURCE_URL}, username=${APP_DATASOURCE_USERNAME}, password=${APP_DATASOURCE_PASSWORD}, driver-class-name=org.postgresql.Driver}, jpa={hibernate={ddl-auto=validate}}, security={oauth2={resourceserver={jwt={issuer-uri=${APP_SECURITY_KEYCLOAK_ISSUER_URI}}}}}}, logging={structured={format={console=logstash}}}}
2026-05-12T15:59:50.032+09:00 DEBUG 3742337 --- [ Test worker] [traceId=] o.s.boot.env.OriginTrackedYamlLoader : Loaded 1 document from YAML resource: file [/home/donghyeon/dev/Project-Auth-Server/bootstrap/src/main/resources/application-prod.yml]
2026-05-12T15:59:50.033+09:00 DEBUG 3742337 --- [ Test worker] [traceId=] o.s.boot.env.OriginTrackedYamlLoader : Loading from YAML: file [/home/donghyeon/dev/Project-Auth-Server/bootstrap/src/main/resources/application-dev.yml]
2026-05-12T15:59:50.035+09:00 DEBUG 3742337 --- [ Test worker] [traceId=] o.s.boot.env.OriginTrackedYamlLoader : Merging document (no matchers set): {spring={config={activate={on-profile=dev}}, datasource={url=${APP_DATASOURCE_URL}, username=${APP_DATASOURCE_USERNAME}, password=${APP_DATASOURCE_PASSWORD}, driver-class-name=org.postgresql.Driver}, jpa={hibernate={ddl-auto=validate}}, security={oauth2={resourceserver={jwt={issuer-uri=${APP_SECURITY_KEYCLOAK_ISSUER_URI}}}}}}, management={endpoints={web={exposure={include=health,info,loggers,httpexchanges}}}, endpoint={health={show-details=when-authorized}}, server={address=127.0.0.1, port=${MANAGEMENT_SERVER_PORT:9090}}}}
2026-05-12T15:59:50.035+09:00 DEBUG 3742337 --- [ Test worker] [traceId=] o.s.boot.env.OriginTrackedYamlLoader : Loaded 1 document from YAML resource: file [/home/donghyeon/dev/Project-Auth-Server/bootstrap/src/main/resources/application-dev.yml]
]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.project.auth.config.web.RequestAccessLogFilterTest" tests="2" skipped="0" failures="0" errors="0" timestamp="2026-05-12T06:59:50.035Z" hostname="donghyeon-960XGK" time="0.008">
<properties/>
<testcase name="skipsExcludedPaths()" classname="com.project.auth.config.web.RequestAccessLogFilterTest" time="0.001"/>
<testcase name="logsRequestUsingNormalizedRemoteAddrInsteadOfForwardedHeader()" classname="com.project.auth.config.web.RequestAccessLogFilterTest" time="0.006"/>
<system-out><![CDATA[2026-05-12T15:59:50.041+09:00 INFO 3742337 --- [ Test worker] [traceId=trace-1234] http.access : ACCESS eventType="HTTP_ACCESS" method="GET" requestPath="/api/v1/auth/me" status="204" durationMs="0" remoteIp="10.0.0.0" actorId="al***@example.com" result="success"
]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>
@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.project.auth.config.web.RequestBoundApiResultFactoryPropertyTest" tests="6" skipped="0" failures="0" errors="0" timestamp="2026-05-12T06:59:50.091Z" hostname="donghyeon-960XGK" time="1.132">
<properties/>
<testcase name="timestamp is always iso instant form" classname="com.project.auth.config.web.RequestBoundApiResultFactoryPropertyTest" time="0.476"/>
<testcase name="traceId falls back to dash for blank mdc value" classname="com.project.auth.config.web.RequestBoundApiResultFactoryPropertyTest" time="0.13"/>
<testcase name="traceId uses mdc value when present" classname="com.project.auth.config.web.RequestBoundApiResultFactoryPropertyTest" time="0.137"/>
<testcase name="traceId falls back to dash when mdc is empty" classname="com.project.auth.config.web.RequestBoundApiResultFactoryPropertyTest" time="0.049"/>
<testcase name="success with data carries data and no errors" classname="com.project.auth.config.web.RequestBoundApiResultFactoryPropertyTest" time="0.206"/>
<testcase name="failure without data carries no data and no errors" classname="com.project.auth.config.web.RequestBoundApiResultFactoryPropertyTest" time="0.112"/>
<system-out><![CDATA[timestamp = 2026-05-12T15:59:50.582927163, RequestBoundApiResultFactoryPropertyTest:timestamp is always iso instant form =
|-----------------------jqwik-----------------------
tries = 1000 | # of calls to property
checks = 1000 | # of not rejected calls
generation = RANDOMIZED | parameters are randomly generated
after-failure = SAMPLE_FIRST | try previously failed sample, then previous seed
when-fixed-seed = ALLOW | fixing the random seed is allowed
edge-cases#mode = MIXIN | edge cases are mixed in
edge-cases#total = 4 | # of all combined edge cases
edge-cases#tried = 4 | # of edge cases tried in current run
seed = 2228257119070284704 | random seed to reproduce generated values
timestamp = 2026-05-12T15:59:50.716348965, RequestBoundApiResultFactoryPropertyTest:traceId falls back to dash for blank mdc value =
|-----------------------jqwik-----------------------
tries = 1000 | # of calls to property
checks = 1000 | # of not rejected calls
generation = RANDOMIZED | parameters are randomly generated
after-failure = SAMPLE_FIRST | try previously failed sample, then previous seed
when-fixed-seed = ALLOW | fixing the random seed is allowed
edge-cases#mode = MIXIN | edge cases are mixed in
edge-cases#total = 8 | # of all combined edge cases
edge-cases#tried = 8 | # of edge cases tried in current run
seed = -3509992690197299427 | random seed to reproduce generated values
timestamp = 2026-05-12T15:59:50.853664217, RequestBoundApiResultFactoryPropertyTest:traceId uses mdc value when present =
|-----------------------jqwik-----------------------
tries = 1000 | # of calls to property
checks = 1000 | # of not rejected calls
generation = RANDOMIZED | parameters are randomly generated
after-failure = SAMPLE_FIRST | try previously failed sample, then previous seed
when-fixed-seed = ALLOW | fixing the random seed is allowed
edge-cases#mode = MIXIN | edge cases are mixed in
edge-cases#total = 16 | # of all combined edge cases
edge-cases#tried = 16 | # of edge cases tried in current run
seed = 3962357578450179575 | random seed to reproduce generated values
timestamp = 2026-05-12T15:59:50.904645516, RequestBoundApiResultFactoryPropertyTest:traceId falls back to dash when mdc is empty =
|-----------------------jqwik-----------------------
tries = 1000 | # of calls to property
checks = 1000 | # of not rejected calls
generation = RANDOMIZED | parameters are randomly generated
after-failure = SAMPLE_FIRST | try previously failed sample, then previous seed
when-fixed-seed = ALLOW | fixing the random seed is allowed
edge-cases#mode = MIXIN | edge cases are mixed in
edge-cases#total = 4 | # of all combined edge cases
edge-cases#tried = 4 | # of edge cases tried in current run
seed = 2839976709901769851 | random seed to reproduce generated values
timestamp = 2026-05-12T15:59:51.111386188, RequestBoundApiResultFactoryPropertyTest:success with data carries data and no errors =
|-----------------------jqwik-----------------------
tries = 1000 | # of calls to property
checks = 1000 | # of not rejected calls
generation = RANDOMIZED | parameters are randomly generated
after-failure = SAMPLE_FIRST | try previously failed sample, then previous seed
when-fixed-seed = ALLOW | fixing the random seed is allowed
edge-cases#mode = MIXIN | edge cases are mixed in
edge-cases#total = 100 | # of all combined edge cases
edge-cases#tried = 90 | # of edge cases tried in current run
seed = -6101865511542054141 | random seed to reproduce generated values
timestamp = 2026-05-12T15:59:51.224180365, RequestBoundApiResultFactoryPropertyTest:failure without data carries no data and no errors =
|-----------------------jqwik-----------------------
tries = 1000 | # of calls to property
checks = 1000 | # of not rejected calls
generation = RANDOMIZED | parameters are randomly generated
after-failure = SAMPLE_FIRST | try previously failed sample, then previous seed
when-fixed-seed = ALLOW | fixing the random seed is allowed
edge-cases#mode = MIXIN | edge cases are mixed in
edge-cases#total = 20 | # of all combined edge cases
edge-cases#tried = 20 | # of edge cases tried in current run
seed = -9058850209440203024 | random seed to reproduce generated values
]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.project.auth.config.web.TraceIdFilterTest" tests="2" skipped="0" failures="0" errors="0" timestamp="2026-05-12T06:59:50.044Z" hostname="donghyeon-960XGK" time="0.003">
<properties/>
<testcase name="populatesTraceIdClientIpAndUserAgentIntoMdc()" classname="com.project.auth.config.web.TraceIdFilterTest" time="0.002"/>
<testcase name="normalizesExternalHeaderBeforePuttingItIntoMdc()" classname="com.project.auth.config.web.TraceIdFilterTest" time="0.001"/>
<system-out><![CDATA[]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>