Skip to content

test: supertest 대상 앱을 127.0.0.1에 열어 다른 프로세스의 포트 가로채기 차단 - #490

Merged
chanwoo7 merged 2 commits into
developfrom
test/supertest-loopback
Oct 4, 2026
Merged

chanwoo7 merged 2 commits into
developfrom
test/supertest-loopback

Conversation

@chanwoo7

@chanwoo7 chanwoo7 commented Oct 4, 2026

Copy link
Copy Markdown
Member

배경

  • 이슈 #485입니다. role-routes.spec의 worker GET /rest-docs가 가끔 기대한 404 대신 401을 받았습니다.
  • 기존 추정(api 전용 문서 미들웨어가 붙음)은 맞지 않았습니다.
    • worker 앱은 이 경로를 항상 404로 끝내고, 테스트 env에는 문서 토큰이 없어 문서 미들웨어가 붙어도 401을 낼 수 없습니다.
    • 따라서 그 401은 테스트 앱이 아닌 다른 서버의 응답입니다.

원인 (유력, 사고 순간 재현은 못 함)

  • supertest는 닫힌 서버를 와일드카드(::)로 열고, 요청은 127.0.0.1로 보냅니다.
  • macOS는 다른 프로세스가 같은 포트를 127.0.0.1로 따로 바인드하는 것을 허용하고, 그러면 127.0.0.1 요청이 그쪽으로 갑니다. 스크립트와 새 spec으로 실측했습니다(리눅스는 그 바인드를 거부합니다).
  • 이 맥미니에서는 VS Code 헬퍼 프로세스가 127.0.0.1 임시 포트(49208, 50004)를 열고 있고, 둘 다 /rest-docs에 401을 돌려줍니다.
  • 사고 순간 실제로 그 프로세스가 포트를 가져갔는지는 증명하지 못했습니다. 메커니즘과 401 응답자만 확인한 상태입니다.

변경

  • listenOnLoopback(src/test/http-app.ts)을 추가했습니다. 앱을 127.0.0.1에 먼저 열고, supertest는 열린 주소를 그대로 씁니다.
    • 같은 주소·포트는 다른 프로세스가 잡지 못하고(EADDRINUSE), 와일드카드로 열어도 127.0.0.1 요청을 가져가지 못합니다.
  • getHttpServer()를 쓰는 spec 7개의 app.init()을 이 헬퍼로 바꿨습니다.
  • 가이드 §9(운영 호스트 보호)에 한 줄을 추가했습니다.

테스트

  • src/test/http-app.spec.ts를 추가했습니다.
    • 반증: 와일드카드로 연 앱은 같은 포트를 127.0.0.1로 잡은 서버에 요청을 빼앗깁니다(macOS에서만 실행, 리눅스 CI는 skip).
    • 헬퍼로 열면 다른 서버가 같은 포트를 잡지 못하고 요청은 앱이 받습니다.
    • supertest를 쓰는 spec 전부가 헬퍼를 쓰는지 점검합니다(현재 8개). role-routes의 교체를 되돌리면 그 파일을 위반으로 잡는 것을 확인했습니다.
  • 바꾼 spec 7개와 새 spec을 함께 실행해 78건이 통과했습니다.

플랜 대조

플랜 5번 불릿 상태
재현율 측정(반복 실행) 안 한 것: 원래 재현율이 낮아 반복 실행이 운영 호스트에 부담인 데 비해 증거가 약해, 사용자 확인을 거쳐 메커니즘 실증으로 대신했습니다
원인 확정 시 수정 + 회귀 유력 원인으로 수정 + 회귀(사용자 확인을 거침, 사고 순간 재현은 못 함)

@coderabbitai

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: CaQuick/caquick-be/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 60b13ba0-b5cd-4cdd-9203-6534a23f8af7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown

🧹 knip — dead-code 리포트

Unused exported types (1)
전체 리포트
Unused exported types (1)
RateLimitPolicy  type  src/global/rate-limit/index.ts:4:8

청소 후보(오탐 가능) · 기준 docs/guide/architecture-conventions.md

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

🩺 NestJS Doctor — 90/100 (Excellent)

진단 469건 (error 12).

Category error warning info
architecture 1 1 42
correctness 0 260 0
performance 0 30 28
schema 0 0 75
security 11 21 0
architecture / security 상위 항목
  • error architecture/architecture/no-manual-instantiation: Manual instantiation of 'OutboxRepository' detected. Use dependency injection instead.
  • info architecture/architecture/no-barrel-export-internals: Barrel file re-exports internal type 'IAuditLogRepository'.
  • warning security/security/no-exposed-env-vars: Direct 'process.env.NODE_ENV' access in 'AuthController'. Use ConfigService instead.
  • warning security/security/require-guards-on-endpoints: Endpoint 'start' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'callback' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'refresh' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'logout' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'sellerLogin' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'sellerRefresh' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'sellerLogout' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'devIssueToken' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'adminLogin' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'adminRefresh' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'adminLogout' has no @UseGuards() at class or method level.
  • warning security/security/require-guards-on-endpoints: Endpoint 'getJwks' has no @UseGuards() at class or method level.

오탐 포함 가능 · 기준 docs/guide/architecture-conventions.md

@codecov

codecov Bot commented Oct 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Coverage report

St.❔
Category Percentage Covered / Total
🟢 Statements 97.92% 10059/10273
🟢 Branches 92.41% 3787/4098
🟢 Functions 97.45% 2027/2080
🟢 Lines 98.51% 9150/9288

Test suite run success

3746 tests passing in 356 suites.

Report generated by 🧪jest coverage report action from b55c414

- role-routes worker의 GET /rest-docs가 간헐 401(기대 404). worker 앱은 이 경로를 항상 404로 끝내고 테스트 env에는 문서 토큰이 없어, 앱 안에서는 401이 나올 수 없음 → 다른 서버의 응답
- supertest는 닫힌 서버를 와일드카드(::)로 열고 127.0.0.1로 요청. macOS는 다른 프로세스가 같은 포트를 127.0.0.1로 따로 바인드하게 두고 요청을 그쪽으로 보냄(실측). 맥미니의 VS Code 헬퍼가 127.0.0.1 임시 포트에서 /rest-docs에 401을 돌려줌
  - 사고 순간의 포트 점유는 재현하지 못함, 메커니즘과 401 응답자만 확인
- listenOnLoopback(src/test/http-app.ts): 앱을 127.0.0.1에 먼저 열어 같은 주소·포트를 다른 프로세스가 잡지 못하게(EADDRINUSE), supertest는 열린 주소를 그대로 씀
  - getHttpServer()를 쓰는 spec 7개의 app.init()을 교체
- http-app.spec: 와일드카드로 열면 가로채진다(macOS만, 리눅스는 바인드 자체 거부), 헬퍼로 열면 못 가로챈다, 사용처 전수 점검(role-routes를 되돌리면 그 파일을 위반으로 잡음 확인)
- 가이드 §9 운영 호스트 보호에 한 줄
- 단언이 서버를 모으기 전에 실패하면 열린 서버가 남아 jest가 끝나지 않고 공용 락을 계속 잡음(첫 버전 실행에서 약 35분)
- 서버는 열리는 즉시 모으고 afterEach가 연결까지 닫음
- 반증: 단언을 일부러 실패시켜도 13초 안에 종료(1 failed), 정상 3 passed
@chanwoo7
chanwoo7 force-pushed the test/supertest-loopback branch from bd96e84 to b55c414 Compare October 4, 2026 16:02
@chanwoo7
chanwoo7 merged commit a820ae2 into develop Oct 4, 2026
12 checks passed
@chanwoo7
chanwoo7 deleted the test/supertest-loopback branch October 4, 2026 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant