정리: tls_crosstest 코드리뷰 완료 후 중복 .md 파일 제거한다

code_review_1.log, plan_1.log, complete.log 아카이브 완료 확인 후 삭제.
This commit is contained in:
toki 2026-04-26 19:37:25 +09:00
parent 1419895ed6
commit c055387ace
2 changed files with 0 additions and 811 deletions

View file

@ -1,135 +0,0 @@
<!-- task=tls_crosstest plan=1 tag=TLS_CROSSTEST -->
# Code Review Reference - TLS_CROSSTEST
## 개요
date=2026-04-26
task=tls_crosstest, plan=1, tag=TLS_CROSSTEST
## 이 파일을 읽는 리뷰 에이전트에게
각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
리뷰 완료 후 반드시 아래 순서로 아카이브하세요.
1. `CODE_REVIEW.md``code_review_1.log` (N = 기존 code_review_*.log 수)
2. `PLAN.md``plan_1.log` (M = 기존 plan_*.log 수)
3. PASS인 경우 `complete.log` 작성 후 종료. WARN/FAIL인 경우 새 `PLAN.md` + `CODE_REVIEW.md` 스텁 작성.
---
## 구현 항목별 완료 여부
| 항목 | 완료 여부 |
|------|---------|
| [TLS_CROSSTEST-1] Dart 클라이언트 파일 — TLS 모드 추가 | [x] |
| [TLS_CROSSTEST-2] Go 클라이언트 파일 — TLS 모드 추가 | [x] |
| [TLS_CROSSTEST-3] Kotlin 클라이언트 파일 — TLS 모드 추가 | [x] |
| [TLS_CROSSTEST-4] Python 클라이언트 파일 — TLS 모드 추가 | [x] |
| [TLS_CROSSTEST-5] TypeScript 클라이언트 파일 — TLS 모드 추가 | [x] |
| [TLS_CROSSTEST-6] Dart orchestrator 3개 — TLS phase 추가 | [x] |
| [TLS_CROSSTEST-7] Go orchestrator 3개 — TLS phase 추가 | [x] |
| [TLS_CROSSTEST-8] Kotlin orchestrator 4개 — TLS TCP phase 추가 | [x] |
| [TLS_CROSSTEST-9] Python orchestrator 4개 — TLS phase 추가 | [x] |
| [TLS_CROSSTEST-10] TypeScript orchestrator 4개 — TLS phase 추가 | [x] |
## 계획 대비 변경 사항
- Python crosstest client 4개에 secure close timeout과 짧은 server-ready delay를 추가했다. TLS close 또는 Kotlin server listener 등록 레이스로 테스트 프로세스가 불필요하게 타임아웃되는 것을 막기 위한 안정화다.
- Kotlin server row 3개(`kotlin_dart`, `kotlin_go`, `kotlin_python`)는 기존 WS 서버를 phase마다 재시작하던 구조를 `kotlin_typescript`와 같은 단일 WS 서버 재사용 구조로 맞췄다. 같은 포트 재바인딩 타이밍으로 인한 연결 거부를 방지한다.
- Kotlin server row는 계획대로 WSS phase를 추가하지 않고 TLS TCP 2 phase만 추가했다.
## 주요 설계 결정
- 각 server orchestrator는 자기 언어의 test cert fixture를 사용한다. 단 Go server orchestrator는 Go 패키지에 cert fixture가 없어 `dart/test/certs`를 사용한다.
- Kotlin server row는 WSS를 추가하지 않고 TLS TCP만 검증한다.
- 클라이언트 helper는 기존 TCP/WS 구조를 유지하고 `--cert`가 필요한 secure mode에서만 trust context/CA를 구성한다.
## 리뷰어를 위한 체크포인트
- **포트 충돌 없음**: 포트 배정표의 신규 TLS TCP / WSS 포트(볼드체)가 각 파일의 기존 TCP/WS 포트와 겹치지 않는지 확인.
- **인증서 경로 일관성**: 각 언어 orchestrator가 자신의 `test/certs/server.crt` + `server.key`를 사용하고, `--cert` 인수로 클라이언트에 전달하는지 확인.
- **클라이언트 `--mode` 확장**: 1-5번 클라이언트 파일 전체에서 `"tls"` / `"wss"` case가 기존 `"tcp"` / `"ws"` 구조와 동일한 패턴으로 추가됐는지 확인.
- **`buildClientTLS` / `buildClientSslContext` 헬퍼 복사 정확성**: Go 3개 클라이언트 파일과 Kotlin 4개 클라이언트 파일에 복사된 헬퍼가 기준 파일 (`dart_go_client/main.go`, `tls_support` TestHelpers.kt)과 일치하는지 확인.
- **TypeScript `typescript_kotlin` orchestrator**: WSS 없는 TLS TCP 2 phase만 포함됐는지 확인 (`typescript_kotlin_client.ts` 에 `wss` 케이스는 있어도 orchestrator에서 WSS phase를 호출하지 않음).
- **Push 메시지 검증 문자열**: 각 클라이언트 파일이 올바른 서버 언어명을 포함한 push 문자열을 검증하는지 확인 (예: `python_dart_client.dart``'push from python server'`).
- **의존 관계 순서**: 1단계(클라이언트 1-5) 완료 후 2단계(orchestrator 6-10)가 구현됐는지 확인.
## 검증 결과
정적/중간 검증:
```text
$ cd dart && dart analyze crosstest/kotlin_dart_client.dart crosstest/python_dart_client.dart crosstest/typescript_dart_client.dart crosstest/dart_kotlin.dart crosstest/dart_python.dart crosstest/dart_typescript.dart
No issues found!
$ cd go && env PATH=/config/go-sdk/go/bin:$PATH GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod go build ./crosstest/kotlin_go_client ./crosstest/python_go_client ./crosstest/typescript_go_client
(exit 0)
$ python3 -m py_compile python/crosstest/dart_python_client.py python/crosstest/go_python_client.py python/crosstest/kotlin_python_client.py python/crosstest/typescript_python_client.py python/crosstest/python_dart.py python/crosstest/python_go.py python/crosstest/python_kotlin.py python/crosstest/python_typescript.py
(exit 0)
$ cd typescript && npx tsc --noEmit
(exit 0)
$ cd kotlin && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle ./gradlew compileCrosstestKotlin
BUILD SUCCESSFUL
```
최종 crosstest:
```text
$ cd dart && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 dart run crosstest/dart_kotlin.dart
PASS all dart-server/kotlin-client crosstests passed
$ cd dart && dart run crosstest/dart_python.dart
PASS all dart-server/python-client crosstests passed
$ cd dart && dart run crosstest/dart_typescript.dart
PASS all dart-server/typescript-client crosstests passed
$ cd go && env PATH=/config/go-sdk/go/bin:$PATH GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 go run ./crosstest/go_kotlin.go
PASS all go-server/kotlin-client crosstests passed
$ cd go && env PATH=/config/go-sdk/go/bin:$PATH GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod go run ./crosstest/go_python.go
PASS all go-server/python-client crosstests passed
$ cd go && env PATH=/config/go-sdk/go/bin:$PATH GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod go run ./crosstest/go_typescript.go
PASS all go-server/typescript-client crosstests passed
$ cd kotlin && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle ./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinDartKt
PASS all kotlin-server/dart-client crosstests passed
$ cd kotlin && env PATH=/config/go-sdk/go/bin:$PATH JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod ./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinGoKt
PASS all kotlin-server/go-client crosstests passed
$ cd kotlin && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle ./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinPythonKt
PASS all kotlin-server/python-client crosstests passed
$ cd kotlin && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle ./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinTypescriptKt
PASS all kotlin-server/typescript-client crosstests passed
$ cd python && python3 -m crosstest.python_dart
PASS all python-server/dart-client crosstests passed
$ cd python && env PATH=/config/go-sdk/go/bin:$PATH GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod python3 -m crosstest.python_go
PASS all python-server/go-client crosstests passed
$ cd python && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 python3 -m crosstest.python_kotlin
PASS all python-server/kotlin-client crosstests passed
$ cd python && python3 -m crosstest.python_typescript
PASS all python-server/typescript-client crosstests passed
$ cd typescript && node --import tsx crosstest/typescript_dart.ts
PASS all typescript-server/dart-client crosstests passed
$ cd typescript && env PATH=/config/go-sdk/go/bin:$PATH GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod node --import tsx crosstest/typescript_go.ts
PASS all typescript-server/go-client crosstests passed
$ cd typescript && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 node --import tsx crosstest/typescript_kotlin.ts
PASS all typescript-server/kotlin-client crosstests passed
$ cd typescript && node --import tsx crosstest/typescript_python.ts
PASS all typescript-server/python-client crosstests passed
```

View file

@ -1,676 +0,0 @@
<!-- task=tls_crosstest plan=1 tag=TLS_CROSSTEST -->
# TLS 크로스테스트 전 언어 확장
## 이 파일을 읽는 구현 에이전트에게
각 항목의 체크리스트를 완료 표시하고, 중간 검증 명령을 실행한 뒤 출력을 CODE_REVIEW.md `검증 결과` 섹션에 붙여 넣는다. 최종 검증까지 완료 후 CODE_REVIEW.md 각 항목을 `[x]`로 체크한다. **의존 관계 및 구현 순서** 섹션을 반드시 지킨다.
## 배경
`dart_go`·`go_dart` 두 조합에만 TLS TCP + WSS 크로스테스트가 존재한다. Python·TypeScript·Kotlin에 TLS 구현이 추가됨에 따라 나머지 18개 쌍에도 TLS 검증이 가능해졌다. 이번 작업으로 서버·클라이언트 양쪽 모두 TLS를 지원하는 모든 조합에 TLS 크로스테스트 phase를 추가한다.
**기준 파일:** `dart/crosstest/dart_go.dart` (orchestrator), `go/crosstest/dart_go_client/main.go` (client)
**인증서 경로 규칙:** 각 언어의 `test/certs/server.crt` + `server.key` 를 사용한다 (모두 `dart/test/certs/` 원본의 사본). orchestrator는 자신의 언어 경로로 서버 cert를 로드하고 `--cert=<path>` 로 클라이언트에 전달한다.
---
## 포트 배정표
| orchestrator | TCP | WS | TLS TCP (신규) | WSS (신규) |
|---|---|---|---|---|
| dart_kotlin | 29590 | 29592 | **29594** | **29596** |
| dart_python | 29694 | 29696 | **29698** | **29700** |
| dart_typescript | 29790 | 29792 | **29794** | **29796** |
| go_kotlin | 29290 | 29292 | **29294** | **29296** |
| go_python | 29390 | 29392 | **29394** | **29396** |
| go_typescript | 29490 | 29492 | **29494** | **29496** |
| kotlin_dart | 29490 | 29492 | **29494** | — |
| kotlin_go | 29390 | 29392 | **29394** | — |
| kotlin_python | 29394 | 29396 | **29398** | — |
| kotlin_typescript | 29794 | 29796 | **29798** | — |
| python_dart | 29494 | 29496 | **29498** | **29500** |
| python_go | 29490 | 29492 | **29494** | **29496** |
| python_kotlin | 29498 | 29500 | **29502** | **29504** |
| python_typescript | 29798 | 29800 | **29802** | **29804** |
| typescript_dart | 29802 | 29804 | **29806** | **29808** |
| typescript_go | 29806 | 29808 | **29810** | **29812** |
| typescript_kotlin | 29810 | 29812 | **29814** | — |
| typescript_python | 29814 | 29816 | **29818** | **29820** |
---
## [TLS_CROSSTEST-1] Dart 클라이언트 파일 — TLS 모드 추가
### 문제
`dart/crosstest/kotlin_dart_client.dart`, `dart/crosstest/python_dart_client.dart`, `dart/crosstest/typescript_dart_client.dart` 3개 파일이 `--mode=tls/wss`, `--cert` 인수를 처리하지 않는다.
### 해결 방법
`dart/crosstest/go_dart_client.dart` 패턴을 참조한다. 각 파일에서:
1. `args`에서 `--cert` 인수 파싱 추가
2. `_connectWithRetry` 또는 동등 함수의 `switch (mode)` 블록에 `'tls'`·`'wss'` 케이스 추가:
```dart
case 'tls':
final ctx = SecurityContext()..setTrustedCertificates(certPath!);
final socket = await ProtobufClient.connectSecure(_host, port, context: ctx);
return _ClientHandle(/* TCP client */, () async => /* close */);
case 'wss':
final ctx = SecurityContext()..setTrustedCertificates(certPath!);
final ws = await WsProtobufClient.connectSecure(_host, port, context: ctx);
return _ClientHandle(/* WS client */, () async => /* close */);
```
3. 각 파일에서 push 메시지 검증 문자열이 맞는지 확인:
- `kotlin_dart_client`: `'push from kotlin server'`
- `python_dart_client`: `'push from python server'`
- `typescript_dart_client`: `'push from typescript server'`
### 수정 파일 및 체크리스트
- `dart/crosstest/kotlin_dart_client.dart`
- [x] `--cert` 파라미터 파싱 추가
- [x] `'tls'`·`'wss'` 모드 케이스 추가
- `dart/crosstest/python_dart_client.dart`
- [x] `--cert` 파라미터 파싱 추가
- [x] `'tls'`·`'wss'` 모드 케이스 추가
- `dart/crosstest/typescript_dart_client.dart`
- [x] `--cert` 파라미터 파싱 추가
- [x] `'tls'`·`'wss'` 모드 케이스 추가
### 테스트 작성
단독 실행 테스트 없음. TLS_CROSSTEST-8~10의 orchestrator 검증으로 확인.
### 중간 검증
```
$ cd dart && dart analyze crosstest/kotlin_dart_client.dart crosstest/python_dart_client.dart crosstest/typescript_dart_client.dart
No issues found!
```
---
## [TLS_CROSSTEST-2] Go 클라이언트 파일 — TLS 모드 추가
### 문제
`go/crosstest/kotlin_go_client/main.go`, `go/crosstest/python_go_client/main.go`, `go/crosstest/typescript_go_client/main.go` 3개 파일이 `--mode=tls/wss`, `--cert` 를 처리하지 않는다.
### 해결 방법
`go/crosstest/dart_go_client/main.go` 패턴을 참조한다. 각 파일에서:
1. `flag.String("cert", "", ...)` 플래그 추가
2. `dial()` 함수의 `switch mode` 블록에 `"tls"`·`"wss"` 케이스 추가:
```go
case "tls":
tlsCfg, err := buildClientTLS(*cert)
client, err = toki.DialTcpTLS(ctx, host, port, tlsCfg, 0, 0, parserMap())
case "wss":
tlsCfg, err := buildClientTLS(*cert)
client, err = toki.DialWssWithHeartbeat(ctx, host, port, wsPath, tlsCfg, 0, 0, parserMap())
```
3. `buildClientTLS(certFile string)` 헬퍼를 `dart_go_client/main.go`에서 복사 추가
4. 각 파일 push 메시지 검증 문자열 확인:
- `kotlin_go_client`: `"push from kotlin server"`
- `python_go_client`: `"push from python server"`
- `typescript_go_client`: `"push from typescript server"`
### 수정 파일 및 체크리스트
- `go/crosstest/kotlin_go_client/main.go`
- [x] `--cert` 플래그 추가
- [x] `"tls"`·`"wss"` 케이스 및 `buildClientTLS` 헬퍼 추가
- `go/crosstest/python_go_client/main.go`
- [x] 동일
- `go/crosstest/typescript_go_client/main.go`
- [x] 동일
### 테스트 작성
없음. TLS_CROSSTEST-7~9의 orchestrator 검증으로 확인.
### 중간 검증
```
$ cd go && env PATH=/config/go-sdk/go/bin:$PATH GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod \
go build ./crosstest/kotlin_go_client ./crosstest/python_go_client ./crosstest/typescript_go_client
(exit 0)
```
---
## [TLS_CROSSTEST-3] Kotlin 클라이언트 파일 — TLS 모드 추가
### 문제
`kotlin/crosstest/dart_kotlin_client.kt`, `go_kotlin_client/Main.kt`, `python_kotlin_client.kt`, `typescript_kotlin_client.kt` 4개 파일이 `--mode=tls/wss`, `--cert` 를 처리하지 않는다.
### 해결 방법
각 파일에서:
1. `argValue(args, "cert")` 파싱 추가
2. `connectWithRetry(mode, port, cert)` 시그니처에 `cert: String?` 추가
3. `when (mode)` 블록에 `"tls"`·`"wss"` 케이스 추가:
```kotlin
"tls" -> {
val sslCtx = buildClientSslContext(cert ?: error("--cert required for tls"))
DialTcpTls(HOST, port, sslCtx, 0, 0, parserMap)
}
"wss" -> {
val sslCtx = buildClientSslContext(cert ?: error("--cert required for wss"))
dialWss(HOST, port, WS_PATH, sslCtx, 0, 0, parserMap)
}
```
4. `buildClientSslContext(certPath: String): SSLContext` 헬퍼 추가:
```kotlin
fun buildClientSslContext(certPath: String): SSLContext {
val certFactory = java.security.cert.CertificateFactory.getInstance("X.509")
val cert = java.io.File(certPath).inputStream().use {
certFactory.generateCertificate(it) as java.security.cert.X509Certificate
}
val ts = java.security.KeyStore.getInstance("PKCS12")
ts.load(null, null)
ts.setCertificateEntry("toki", cert)
val tmf = javax.net.ssl.TrustManagerFactory.getInstance(
javax.net.ssl.TrustManagerFactory.getDefaultAlgorithm()
)
tmf.init(ts)
val ctx = javax.net.ssl.SSLContext.getInstance("TLS")
ctx.init(null, tmf.trustManagers, null)
return ctx
}
```
5. 각 파일 push 메시지 검증 문자열 확인 (`'push from dart/go/python/typescript server'`).
**참고:** `go_kotlin_client`는 Gradle 서브프로젝트 (`kotlin/crosstest/go_kotlin_client/`). 나머지 세 파일은 독립 `.kt` 파일.
### 수정 파일 및 체크리스트
- `kotlin/crosstest/dart_kotlin_client.kt`
- [x] `--cert` 파싱, `"tls"`·`"wss"` 케이스, `buildClientSslContext` 추가
- `kotlin/crosstest/go_kotlin_client/src/main/kotlin/com/tokilabs/toki_socket/crosstest/Main.kt`
- [x] 동일
- `kotlin/crosstest/python_kotlin_client.kt`
- [x] 동일
- `kotlin/crosstest/typescript_kotlin_client.kt`
- [x] 동일
### 테스트 작성
없음. TLS_CROSSTEST-6~10의 orchestrator 검증으로 확인.
### 중간 검증
```
$ cd kotlin && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle \
./gradlew compileCrosstestKotlin
BUILD SUCCESSFUL
```
---
## [TLS_CROSSTEST-4] Python 클라이언트 파일 — TLS 모드 추가
### 문제
`python/crosstest/dart_python_client.py`, `go_python_client.py`, `kotlin_python_client.py`, `typescript_python_client.py` 4개 파일이 TLS 모드를 처리하지 않는다.
### 해결 방법
각 파일에서:
1. `argparse``--cert` 인수 추가 (`default=None`)
2. `choices=["tcp", "ws"]``["tcp", "ws", "tls", "wss"]` 변경
3. `dial()` 함수에 `"tls"`·`"wss"` 케이스 추가:
```python
elif mode == "tls":
ssl_ctx = ssl.create_default_context(cafile=cert)
ssl_ctx.check_hostname = False
return await connect_tcp_tls(HOST, port, ssl_ctx, 0, 0, parser_map())
elif mode == "wss":
ssl_ctx = ssl.create_default_context(cafile=cert)
ssl_ctx.check_hostname = False
return await connect_wss(HOST, port, WS_PATH, ssl_ctx, 0, 0, parser_map())
```
4. `import ssl`, `connect_tcp_tls`, `connect_wss` import 추가
### 수정 파일 및 체크리스트
- `python/crosstest/dart_python_client.py`
- [x] `import ssl`, `connect_tcp_tls`, `connect_wss` 추가
- [x] `--cert` argparse 인수 추가, choices 확장
- [x] `"tls"`·`"wss"` 분기 추가
- `python/crosstest/go_python_client.py`
- [x] 동일
- `python/crosstest/kotlin_python_client.py`
- [x] 동일
- `python/crosstest/typescript_python_client.py`
- [x] 동일
### 중간 검증
```
$ python3 -m py_compile python/crosstest/dart_python_client.py \
python/crosstest/go_python_client.py \
python/crosstest/kotlin_python_client.py \
python/crosstest/typescript_python_client.py
(exit 0)
```
---
## [TLS_CROSSTEST-5] TypeScript 클라이언트 파일 — TLS 모드 추가
### 문제
`typescript/crosstest/dart_typescript_client.ts`, `go_typescript_client.ts`, `kotlin_typescript_client.ts`, `python_typescript_client.ts` 4개 파일이 TLS 모드를 처리하지 않는다.
### 해결 방법
각 파일에서:
1. `parseArgs()``mode` 타입을 `"tcp" | "ws" | "tls" | "wss"` 로 확장
2. `--cert` 인수 파싱 추가
3. `dialWithRetry` / `dial()``cert?: string` 파라미터 추가
4. `dial()` switch 에 `"tls"`·`"wss"` 케이스 추가:
```typescript
case "tls": {
const ca = fs.readFileSync(cert!);
return connectTcpTls(HOST, port, { ca }, 0, 0, parserMap());
}
case "wss": {
const ca = fs.readFileSync(cert!);
return connectWss(HOST, port, WS_PATH, { ca }, 0, 0, parserMap());
}
```
5. `import * as fs from "node:fs"`, `connectTcpTls`, `connectWss` import 추가
### 수정 파일 및 체크리스트
- `typescript/crosstest/dart_typescript_client.ts`
- [x] `fs`, `connectTcpTls`, `connectWss` import 추가
- [x] `--cert` 파싱, mode 타입 확장, `dial()` 케이스 추가
- `typescript/crosstest/go_typescript_client.ts`
- [x] 동일
- `typescript/crosstest/kotlin_typescript_client.ts`
- [x] 동일
- `typescript/crosstest/python_typescript_client.ts`
- [x] 동일
### 중간 검증
```
$ cd typescript && npx tsc --noEmit
(exit 0)
```
---
## [TLS_CROSSTEST-6] Dart orchestrator 3개 — TLS phase 추가
### 문제
`dart/crosstest/dart_kotlin.dart`, `dart/crosstest/dart_python.dart`, `dart/crosstest/dart_typescript.dart` 에 TLS phase가 없다.
### 해결 방법
`dart/crosstest/dart_go.dart` 패턴을 참조한다. 각 파일에서:
1. TLS/WSS 포트 상수 추가:
- `dart_kotlin`: `_tlsTcpPort = 29594`, `_wssPort = 29596`
- `dart_python`: `_tlsTcpPort = 29698`, `_wssPort = 29700`
- `dart_typescript`: `_tlsTcpPort = 29794`, `_wssPort = 29796`
2. `_DartTlsTcpServer`, `_DartWssServer` 클래스 추가 (dart_go.dart 와 동일 구조)
3. `_runTls()` 메서드 추가 — TLS TCP send-push, TLS TCP requests, WSS send-push, WSS requests 4개 phase
4. `main()`에서 `await _runTls()` 호출 추가
5. 각 파일의 클라이언트 실행 헬퍼에서 `--cert=<path>` 전달
6. 인증서 경로: `dart/test/certs/server.crt`, `dart/test/certs/server.key`
### 수정 파일 및 체크리스트
- `dart/crosstest/dart_kotlin.dart`
- [x] TLS/WSS 포트 상수 추가 (29594, 29596)
- [x] `_DartTlsTcpServer`, `_DartWssServer` 클래스 추가
- [x] `_runTls()` 메서드 추가 (4 phase)
- [x] `main()`에서 `_runTls()` 호출 추가
- [x] Kotlin 클라이언트 호출에 TLS 인수 전달
- `dart/crosstest/dart_python.dart`
- [x] 동일 (포트 29698, 29700)
- `dart/crosstest/dart_typescript.dart`
- [x] 동일 (포트 29794, 29796)
### 중간 검증
```
$ cd dart && dart analyze crosstest/dart_kotlin.dart crosstest/dart_python.dart crosstest/dart_typescript.dart
No issues found!
$ cd dart && dart run crosstest/dart_python.dart
PASS all dart-server/python-client crosstests passed
$ cd dart && dart run crosstest/dart_typescript.dart
PASS all dart-server/typescript-client crosstests passed
$ cd dart && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 dart run crosstest/dart_kotlin.dart
PASS all dart-server/kotlin-client crosstests passed
```
---
## [TLS_CROSSTEST-7] Go orchestrator 3개 — TLS phase 추가
### 문제
`go/crosstest/go_kotlin.go`, `go/crosstest/go_python.go`, `go/crosstest/go_typescript.go` 에 TLS phase가 없다.
### 해결 방법
`go/crosstest/go_dart.go` 패턴 참조. 각 파일에서:
1. TLS/WSS 포트 상수 추가:
- `go_kotlin`: `goKotlinTLSPort = 29294`, `goKotlinWSSPort = 29296`
- `go_python`: `goPythonTLSPort = 29394`, `goPythonWSSPort = 29396`
- `go_typescript`: `goTypescriptTLSPort = 29494`, `goTypescriptWSSPort = 29496`
2. `crypto/tls` import 추가 (미존재 시)
3. `loadServerTLS(certFile, keyFile)` 헬퍼 추가 (go_dart.go 에서 복사)
4. `runTLSTCPSendPush`, `runTLSTCPRequests`, `runWSSendPushSecure`, `runWSSRequestsSecure` 추가
5. `run()` 에서 TLS phase 호출 추가
6. 인증서: `go_dart.go`와 동일하게 `dartDir``test/certs/` 에서 로드
### 수정 파일 및 체크리스트
- `go/crosstest/go_kotlin.go`
- [x] TLS 포트 상수 (29294, 29296), `loadServerTLS`, TLS phase 함수 4개 추가
- [x] `run()`에서 호출 추가
- `go/crosstest/go_python.go`
- [x] 동일 (포트 29394, 29396)
- `go/crosstest/go_typescript.go`
- [x] 동일 (포트 29494, 29496)
### 중간 검증
```
$ cd go && env PATH=/config/go-sdk/go/bin:$PATH GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod \
go run ./crosstest/go_python.go
PASS all go-server/python-client crosstests passed
$ cd go && env PATH=/config/go-sdk/go/bin:$PATH GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod \
go run ./crosstest/go_typescript.go
PASS all go-server/typescript-client crosstests passed
$ cd go && env PATH=/config/go-sdk/go/bin:$PATH JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod \
go run ./crosstest/go_kotlin.go
PASS all go-server/kotlin-client crosstests passed
```
---
## [TLS_CROSSTEST-8] Kotlin orchestrator 4개 — TLS TCP phase 추가
### 문제
`kotlin_dart.kt`, `kotlin_go.kt`, `kotlin_python.kt`, `kotlin_typescript.kt` 에 TLS phase가 없다. Kotlin `WsServer` TLS는 이번 TLS_CROSSTEST 범위에서 사용하지 않으므로 TLS TCP 2개 phase만 추가한다.
### 해결 방법
각 파일에서:
1. TLS TCP 포트 상수 추가:
- `kotlin_dart`: TLS TCP `29494`
- `kotlin_go`: TLS TCP `29394`
- `kotlin_python`: TLS TCP `29398`
- `kotlin_typescript`: TLS TCP `29798`
2. 인증서 로딩: `kotlin/src/test/resources/server.crt` + `server.key` 경로를 repo root 기준으로 계산
3. `runTlsTcp(sslContext, certPath)` 함수 추가 — send-push, requests 2 phase
4. Kotlin `WsServer`는 TLS를 지원하지 않으므로 WSS phase는 추가하지 않는다.
5. TLS TCP 서버는 `TcpServer(..., sslContext = serverCtx)` 생성자 사용
6. main 또는 run 함수에서 `runTlsTcp()` 호출 추가
### 수정 파일 및 체크리스트
- `kotlin/crosstest/kotlin_dart.kt`
- [x] TLS TCP 포트 상수 (29494)
- [x] 인증서 경로 계산 로직 추가
- [x] `runTlsTcp()` 함수 추가 (send-push, requests)
- [x] main에서 `runTlsTcp()` 호출 추가
- [x] WSS phase 제외 (Kotlin `WsServer` TLS 미지원)
- `kotlin/crosstest/kotlin_go.kt`
- [x] 동일 (TLS TCP 포트 29394)
- `kotlin/crosstest/kotlin_python.kt`
- [x] 동일 (TLS TCP 포트 29398)
- `kotlin/crosstest/kotlin_typescript.kt`
- [x] 동일 (TLS TCP 포트 29798)
### 중간 검증
```
$ cd kotlin && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle \
./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinDartKt
PASS all kotlin-server/dart-client crosstests passed
$ cd kotlin && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle \
./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinGoKt
PASS all kotlin-server/go-client crosstests passed
$ cd kotlin && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle \
./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinPythonKt
PASS all kotlin-server/python-client crosstests passed
$ cd kotlin && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle \
./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinTypescriptKt
PASS all kotlin-server/typescript-client crosstests passed
```
---
## [TLS_CROSSTEST-9] Python orchestrator 4개 — TLS phase 추가
### 문제
`python/crosstest/python_dart.py`, `python_go.py`, `python_kotlin.py`, `python_typescript.py` 에 TLS phase가 없다.
### 해결 방법
각 파일에서:
1. TLS/WSS 포트 상수 추가:
- `python_dart`: `TLS_TCP_PORT = 29498`, `WSS_PORT = 29500`
- `python_go`: `TLS_TCP_PORT = 29494`, `WSS_PORT = 29496`
- `python_kotlin`: `TLS_TCP_PORT = 29502`, `WSS_PORT = 29504`
- `python_typescript`: `TLS_TCP_PORT = 29802`, `WSS_PORT = 29804`
2. `import ssl` 추가
3. `_make_server_ssl_context()` 헬퍼 추가:
```python
def _make_server_ssl_context() -> ssl.SSLContext:
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.load_cert_chain(CERT_PATH, KEY_PATH)
return ctx
```
4. `CERT_PATH`, `KEY_PATH` 상수: 각 파일 기준 repo root에서 계산
5. `run_tls()` 코루틴 추가 — TLS TCP send-push, TLS TCP requests, WSS send-push, WSS requests
6. `main()` 또는 `run()` 에서 `await run_tls()` 호출 추가
7. `--cert` 로 클라이언트 subprocess에 인증서 경로 전달
### 수정 파일 및 체크리스트
- `python/crosstest/python_dart.py`
- [x] TLS/WSS 포트 상수 (29498, 29500), cert 경로, `run_tls()` 추가
- `python/crosstest/python_go.py`
- [x] 동일 (29494, 29496)
- `python/crosstest/python_kotlin.py`
- [x] 동일 (29502, 29504)
- `python/crosstest/python_typescript.py`
- [x] 동일 (29802, 29804)
### 중간 검증
```
$ python3 -m py_compile python/crosstest/python_dart.py python/crosstest/python_go.py \
python/crosstest/python_kotlin.py python/crosstest/python_typescript.py
(exit 0)
$ cd python && env PATH=/config/go-sdk/go/bin:$PATH GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod python3 -m crosstest.python_go
PASS all python-server/go-client crosstests passed
$ cd python && python3 -m crosstest.python_typescript
PASS all python-server/typescript-client crosstests passed
$ cd python && python3 -m crosstest.python_dart
PASS all python-server/dart-client crosstests passed
$ cd python && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 python3 -m crosstest.python_kotlin
PASS all python-server/kotlin-client crosstests passed
```
---
## [TLS_CROSSTEST-10] TypeScript orchestrator 4개 — TLS phase 추가
### 문제
`typescript/crosstest/typescript_dart.ts`, `typescript_go.ts`, `typescript_kotlin.ts`, `typescript_python.ts` 에 TLS phase가 없다.
### 해결 방법
각 파일에서:
1. TLS/WSS 포트 상수 추가:
- `typescript_dart`: `TLS_TCP_PORT = 29806`, `WSS_PORT = 29808`
- `typescript_go`: `TLS_TCP_PORT = 29810`, `WSS_PORT = 29812`
- `typescript_kotlin`: `TLS_TCP_PORT = 29814` (WSS 없음)
- `typescript_python`: `TLS_TCP_PORT = 29818`, `WSS_PORT = 29820`
2. `import * as fs from "node:fs"` 추가
3. `CERT_PATH`, `KEY_PATH`: repo root 기준 계산
4. `runTls()` 함수 추가:
- `typescript_kotlin`: TLS TCP 2 phase만 (Kotlin WsServer TLS 미지원)
- 나머지: TLS TCP send-push, TLS TCP requests, WSS send-push, WSS requests
5. main 에서 `await runTls()` 호출 추가
6. `TcpServer` 생성 시 `tlsOptions: { cert, key }` 전달
7. `WsServer` 생성 시 `tlsOptions: { cert, key }` 전달 (`typescript_kotlin` 제외)
8. 클라이언트 subprocess에 `--mode=tls`, `--cert=CERT_PATH` 전달
### 수정 파일 및 체크리스트
- `typescript/crosstest/typescript_dart.ts`
- [x] TLS/WSS 포트 상수 (29806, 29808), cert 경로, `runTls()` 추가
- `typescript/crosstest/typescript_go.ts`
- [x] 동일 (29810, 29812)
- `typescript/crosstest/typescript_kotlin.ts`
- [x] TLS 포트 상수 (29814), `runTls()` — TLS TCP 2 phase만
- `typescript/crosstest/typescript_python.ts`
- [x] 동일 (29818, 29820)
### 중간 검증
```
$ cd typescript && npx tsc --noEmit
(exit 0)
$ cd typescript && env PATH=/config/go-sdk/go/bin:$PATH GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod node --import tsx crosstest/typescript_go.ts
PASS all typescript-server/go-client crosstests passed
$ cd typescript && node --import tsx crosstest/typescript_python.ts
PASS all typescript-server/python-client crosstests passed
$ cd typescript && node --import tsx crosstest/typescript_dart.ts
PASS all typescript-server/dart-client crosstests passed
$ cd typescript && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 node --import tsx crosstest/typescript_kotlin.ts
PASS all typescript-server/kotlin-client crosstests passed
```
---
## 수정 파일 요약
| 파일 | 항목 |
|------|------|
| `dart/crosstest/kotlin_dart_client.dart` | TLS_CROSSTEST-1 |
| `dart/crosstest/python_dart_client.dart` | TLS_CROSSTEST-1 |
| `dart/crosstest/typescript_dart_client.dart` | TLS_CROSSTEST-1 |
| `go/crosstest/kotlin_go_client/main.go` | TLS_CROSSTEST-2 |
| `go/crosstest/python_go_client/main.go` | TLS_CROSSTEST-2 |
| `go/crosstest/typescript_go_client/main.go` | TLS_CROSSTEST-2 |
| `kotlin/crosstest/dart_kotlin_client.kt` | TLS_CROSSTEST-3 |
| `kotlin/crosstest/go_kotlin_client/src/main/kotlin/com/tokilabs/toki_socket/crosstest/Main.kt` | TLS_CROSSTEST-3 |
| `kotlin/crosstest/python_kotlin_client.kt` | TLS_CROSSTEST-3 |
| `kotlin/crosstest/typescript_kotlin_client.kt` | TLS_CROSSTEST-3 |
| `python/crosstest/dart_python_client.py` | TLS_CROSSTEST-4 |
| `python/crosstest/go_python_client.py` | TLS_CROSSTEST-4 |
| `python/crosstest/kotlin_python_client.py` | TLS_CROSSTEST-4 |
| `python/crosstest/typescript_python_client.py` | TLS_CROSSTEST-4 |
| `typescript/crosstest/dart_typescript_client.ts` | TLS_CROSSTEST-5 |
| `typescript/crosstest/go_typescript_client.ts` | TLS_CROSSTEST-5 |
| `typescript/crosstest/kotlin_typescript_client.ts` | TLS_CROSSTEST-5 |
| `typescript/crosstest/python_typescript_client.ts` | TLS_CROSSTEST-5 |
| `dart/crosstest/dart_kotlin.dart` | TLS_CROSSTEST-6 |
| `dart/crosstest/dart_python.dart` | TLS_CROSSTEST-6 |
| `dart/crosstest/dart_typescript.dart` | TLS_CROSSTEST-6 |
| `go/crosstest/go_kotlin.go` | TLS_CROSSTEST-7 |
| `go/crosstest/go_python.go` | TLS_CROSSTEST-7 |
| `go/crosstest/go_typescript.go` | TLS_CROSSTEST-7 |
| `kotlin/crosstest/kotlin_dart.kt` | TLS_CROSSTEST-8 |
| `kotlin/crosstest/kotlin_go.kt` | TLS_CROSSTEST-8 |
| `kotlin/crosstest/kotlin_python.kt` | TLS_CROSSTEST-8 |
| `kotlin/crosstest/kotlin_typescript.kt` | TLS_CROSSTEST-8 |
| `python/crosstest/python_dart.py` | TLS_CROSSTEST-9 |
| `python/crosstest/python_go.py` | TLS_CROSSTEST-9 |
| `python/crosstest/python_kotlin.py` | TLS_CROSSTEST-9 |
| `python/crosstest/python_typescript.py` | TLS_CROSSTEST-9 |
| `typescript/crosstest/typescript_dart.ts` | TLS_CROSSTEST-10 |
| `typescript/crosstest/typescript_go.ts` | TLS_CROSSTEST-10 |
| `typescript/crosstest/typescript_kotlin.ts` | TLS_CROSSTEST-10 |
| `typescript/crosstest/typescript_python.ts` | TLS_CROSSTEST-10 |
## 의존 관계 및 구현 순서
**1단계 (클라이언트 파일 — 병렬 가능):**
TLS_CROSSTEST-1, TLS_CROSSTEST-2, TLS_CROSSTEST-3, TLS_CROSSTEST-4, TLS_CROSSTEST-5
**2단계 (orchestrator 파일 — 각 클라이언트 완료 후):**
- TLS_CROSSTEST-6 → TLS_CROSSTEST-1(Dart client), TLS_CROSSTEST-3(Kotlin), TLS_CROSSTEST-4(Python), TLS_CROSSTEST-5(TypeScript) 완료 후
- TLS_CROSSTEST-7 → TLS_CROSSTEST-2(Go), TLS_CROSSTEST-3(Kotlin), TLS_CROSSTEST-4(Python), TLS_CROSSTEST-5(TypeScript) 완료 후
- TLS_CROSSTEST-8 → TLS_CROSSTEST-1(Dart), TLS_CROSSTEST-2(Go), TLS_CROSSTEST-4(Python), TLS_CROSSTEST-5(TypeScript) 완료 후
- TLS_CROSSTEST-9 → TLS_CROSSTEST-1(Dart), TLS_CROSSTEST-2(Go), TLS_CROSSTEST-3(Kotlin), TLS_CROSSTEST-5(TypeScript) 완료 후
- TLS_CROSSTEST-10 → TLS_CROSSTEST-1(Dart), TLS_CROSSTEST-2(Go), TLS_CROSSTEST-3(Kotlin), TLS_CROSSTEST-4(Python) 완료 후
## 최종 검증
```
$ cd dart && dart run crosstest/dart_kotlin.dart
PASS all dart-server/kotlin-client crosstests passed
$ cd dart && dart run crosstest/dart_python.dart
PASS all dart-server/python-client crosstests passed
$ cd dart && dart run crosstest/dart_typescript.dart
PASS all dart-server/typescript-client crosstests passed
$ cd go && env PATH=/config/go-sdk/go/bin:$PATH GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod \
go run ./crosstest/go_kotlin.go && go run ./crosstest/go_python.go && go run ./crosstest/go_typescript.go
PASS all go-server/kotlin-client crosstests passed
PASS all go-server/python-client crosstests passed
PASS all go-server/typescript-client crosstests passed
$ cd kotlin && env JAVA_HOME=/config/opt/jdk/jdk-17.0.10+7 GRADLE_USER_HOME=/tmp/gradle \
./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinDartKt && \
./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinGoKt && \
./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinPythonKt && \
./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinTypescriptKt
(모두 PASS)
$ cd python && python3 -m crosstest.python_dart && python3 -m crosstest.python_go && \
python3 -m crosstest.python_kotlin && python3 -m crosstest.python_typescript
(모두 PASS)
$ cd typescript && node --import tsx crosstest/typescript_dart.ts && \
node --import tsx crosstest/typescript_go.ts && \
node --import tsx crosstest/typescript_kotlin.ts && \
node --import tsx crosstest/typescript_python.ts
(모두 PASS)
```