187 lines
9.1 KiB
Text
187 lines
9.1 KiB
Text
<!-- task=crosstest_coverage_gaps plan=0 tag=CROSSTEST-COVERAGE -->
|
|
|
|
# Code Review Reference - CROSSTEST-COVERAGE
|
|
|
|
## 개요
|
|
|
|
date=2026-04-24
|
|
task=crosstest_coverage_gaps, plan=0, tag=CROSSTEST-COVERAGE
|
|
|
|
## 이 파일을 읽는 리뷰 에이전트에게
|
|
|
|
각 항목의 구현을 실제 소스 파일과 대조하고, 검증 결과가 코드와 일치하는지 확인하세요.
|
|
리뷰 완료 후 반드시 아래 순서로 아카이브하세요.
|
|
|
|
1. `CODE_REVIEW.md` -> `code_review_0.log`
|
|
2. `PLAN.md` -> `plan_0.log`
|
|
3. PASS인 경우 `complete.log` 작성 후 종료. WARN/FAIL인 경우 새 `PLAN.md` + `CODE_REVIEW.md` 스텁 작성.
|
|
|
|
---
|
|
|
|
## 구현 항목별 완료 여부
|
|
|
|
| 항목 | 완료 여부 |
|
|
|------|-----------|
|
|
| [SELF-1] Self-cell coverage audit 표준화 | [x] |
|
|
| [SELF-2] Go self-cell 동시 request-response 보강 | [x] |
|
|
| [SELF-3] Kotlin self-cell 동시 request-response 보강 | [x] |
|
|
| [SELF-4] Python self-cell TCP/WS scenario 보강 | [x] |
|
|
| [SELF-5] TypeScript self-cell 동시 request-response 보강 | [x] |
|
|
| [SECURE-1] Dart <-> Go secure crosstest 추가 | [x] |
|
|
| [SECURE-2] Kotlin/Python/TypeScript secure matrix 보류 사유 문서화 | [x] |
|
|
|
|
## 계획 대비 변경 사항
|
|
|
|
- Python `test_tcp.py`에 `_wait_for_clients` 헬퍼 추가 (broadcast 전 클라이언트 연결 대기). WS 테스트에도 동일 패턴 적용.
|
|
- `go/crosstest/go_dart.go`의 `runDartClient`를 variadic `certFile ...string` 형식으로 변경 — 기존 TCP/WS 호출은 영향 없음.
|
|
- `go/crosstest/go_dart.go`에 `loadServerTLS` 헬퍼 추가.
|
|
|
|
## 주요 설계 결정
|
|
|
|
- **공유 인증서**: `dart/test/certs/server.crt` / `.key` 재사용. SAN에 `IP:127.0.0.1`과 `DNS:localhost` 모두 포함되어 있어 Go/Dart 양쪽 검증 통과 확인.
|
|
- **인증서 경로 전달**: Dart 오케스트레이터(dart_go.dart)와 Go 오케스트레이터(go_dart.go)가 각자 cert 경로를 계산하여 서브프로세스 클라이언트에 `--cert=<path>` 인수로 전달. machine-global trust store 미사용.
|
|
- **Go 서버 TLS**: `toki.NewTcpServerTLS` / `toki.NewWsServerTLS`에 `tls.LoadX509KeyPair`로 로드한 config 전달.
|
|
- **Dart 클라이언트 TLS**: `ProtobufClient.connectSecure` / `WsProtobufClient.connectSecure`에 `SecurityContext()..setTrustedCertificates(certPath)` 전달.
|
|
- **고정 포트**: TLS+TCP 29094/29194, WSS 29096/29196 (기존 plain 포트 29090/29092/29190/29192와 충돌 없음).
|
|
|
|
## Self-cell 감사 결과
|
|
|
|
시나리오 정의: 1=클라이언트→서버 fire-and-forget, 2=서버→클라이언트 push, 3=단일 request-response, 4=다중 동시 request-response
|
|
|
|
| Language | TCP scenario 1/2 | TCP scenario 3 | TCP scenario 4 | WS scenario 1/2 | WS scenario 3 | WS scenario 4 | 조치 |
|
|
|----------|------------------|----------------|----------------|-----------------|---------------|---------------|------|
|
|
| Dart | ✓ (socket_test.dart) | ✓ | ✓ (Future.wait) | ✓ | ✓ | ✓ (Future.wait) | 소스 변경 없음 → UT-ok |
|
|
| Go | ✓ (tcp_test.go) | ✓ | 추가됨 (TestTcpConcurrentRequests) | ✓ (ws_test.go) | ✓ | 추가됨 (TestWsConcurrentRequests) | SELF-2 적용 |
|
|
| Kotlin | ✓ (TcpTest.kt) | ✓ | 추가됨 (testTcpConcurrentRequests) | ✓ (WsTest.kt) | ✓ | 추가됨 (testWsConcurrentRequests) | SELF-3 적용 |
|
|
| Python | ✓ (test_tcp.py) | ✓ | 추가됨 (test_tcp_concurrent_requests) | 신규 파일 생성 (test_ws.py) | 추가됨 | 추가됨 | SELF-4 적용 |
|
|
| TypeScript | ✓ (tcp.test.ts/ws.test.ts) | ✓ | 추가됨 (concurrent roundtrip) | ✓ | ✓ | 추가됨 (concurrent roundtrip) | SELF-5 적용 |
|
|
|
|
**Python test_ws.py 신규 생성 사유**: Python에는 WS 테스트 파일 자체가 없었음. `tcp_server.py`와 대칭으로 `ws_server.py`/`ws_client.py`가 구현 완료되어 있어 `test_ws.py`가 자연스러운 위치.
|
|
|
|
## Secure Matrix 결과
|
|
|
|
| Server \ Client | Dart | Go | Kotlin | Python | TypeScript |
|
|
|-----------------|------|----|--------|--------|------------|
|
|
| Dart | 기존 단위 테스트 (socket_test.dart) | CT-secure (dart_go.dart) | deferred | deferred | deferred |
|
|
| Go | CT-secure (go_dart.go) | 기존 단위 테스트 (tls_test.go) | deferred | deferred | deferred |
|
|
| Kotlin | deferred | deferred | deferred | deferred | deferred |
|
|
| Python | deferred | deferred | deferred | deferred | deferred |
|
|
| TypeScript | deferred | deferred | deferred | deferred | deferred |
|
|
|
|
### Kotlin/Python/TypeScript secure 보류 사유
|
|
|
|
| 언어 | TLS+TCP 서버 | TLS+TCP 클라이언트 | WSS 서버 | WSS 클라이언트 | 보류 사유 |
|
|
|------|------------|-----------------|---------|--------------|---------|
|
|
| Kotlin | 없음 | 없음 | 없음 | 있음 (`wss://` URL 지원) | TLS+TCP API 및 WSS 서버 API 미구현. cross-language secure matrix 적용 불가. |
|
|
| Python | 없음 | 없음 | 없음 | 없음 | `tcp_server.py`/`tcp_client.py`/`ws_server.py`/`ws_client.py` 모두 SSL context 경로 없음. |
|
|
| TypeScript | 없음 | 없음 | 없음 | 없음 | `net` 모듈 plain TCP, plain `ws://`만 사용. `tls`/`https` wrapper 미구현. |
|
|
|
|
구현 자체는 이 계획의 범위 밖. README 과잉 주장 없음 — 언어별 README 수정 불필요.
|
|
|
|
## 리뷰어를 위한 체크포인트
|
|
|
|
- 기존 cross-language TCP/WS 20개 directed 조합을 삭제하거나 약화하지 않았는지 확인
|
|
- self-cell 보강 테스트가 scenario 1-4의 의미와 맞는지 확인
|
|
- Python WS 테스트가 Python server/client 둘 다 실제 `WsServer`/`connect_ws`를 사용하는지 확인
|
|
- Go/Kotlin/TypeScript concurrent request 테스트가 응답 순서가 아니라 nonce/responseNonce 매핑 결과를 검증하는지 확인
|
|
- Dart <-> Go secure crosstest가 machine-global trust store에 의존하지 않는지 확인
|
|
- Kotlin/Python/TypeScript secure deferred 사유가 실제 API 지원 상태와 일치하는지 확인
|
|
|
|
## 검증 결과
|
|
|
|
### Self-cell 보강 검증
|
|
|
|
```
|
|
$ cd dart && dart test
|
|
|
|
$ cd go && go test ./...
|
|
|
|
$ cd kotlin && ./gradlew test
|
|
|
|
$ cd python && python3 -m pytest test/ -v
|
|
|
|
$ cd typescript && npm test
|
|
|
|
$ cd typescript && npm run check
|
|
```
|
|
|
|
### Dart/Go secure crosstest 검증
|
|
|
|
```
|
|
$ cd dart && dart run crosstest/dart_go.dart
|
|
|
|
$ cd go && go run ./crosstest/go_dart.go
|
|
```
|
|
|
|
### Cross-language 회귀 검증
|
|
|
|
```
|
|
$ cd go && go run ./crosstest/go_kotlin.go
|
|
|
|
$ cd go && go run ./crosstest/go_python.go
|
|
|
|
$ cd go && go run ./crosstest/go_typescript.go
|
|
|
|
$ cd dart && dart run crosstest/dart_kotlin.dart
|
|
|
|
$ cd dart && dart run crosstest/dart_python.dart
|
|
|
|
$ cd dart && dart run crosstest/dart_typescript.dart
|
|
|
|
$ cd kotlin && ./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinGoKt
|
|
|
|
$ cd kotlin && ./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinPythonKt
|
|
|
|
$ cd kotlin && ./gradlew run -PmainClass=com.tokilabs.toki_socket.crosstest.KotlinTypescriptKt
|
|
|
|
$ cd python && python3 -m crosstest.python_dart
|
|
|
|
$ cd python && python3 -m crosstest.python_go
|
|
|
|
$ cd python && python3 -m crosstest.python_kotlin
|
|
|
|
$ cd python && python3 -m crosstest.python_typescript
|
|
|
|
$ cd typescript && node --import tsx crosstest/typescript_dart.ts
|
|
|
|
$ cd typescript && node --import tsx crosstest/typescript_go.ts
|
|
|
|
$ cd typescript && node --import tsx crosstest/typescript_kotlin.ts
|
|
|
|
$ cd typescript && node --import tsx crosstest/typescript_python.ts
|
|
```
|
|
|
|
### 정리 검증
|
|
|
|
```
|
|
$ git diff --check
|
|
```
|
|
|
|
---
|
|
|
|
## 코드리뷰 결과
|
|
|
|
### 종합 판정
|
|
|
|
FAIL
|
|
|
|
### 차원별 평가
|
|
|
|
| 차원 | 평가 | 근거 |
|
|
|------|------|------|
|
|
| correctness | Fail | Kotlin 전체 테스트가 재현 가능하게 완료되지 않아 SELF-3 결과를 신뢰할 수 없음 |
|
|
| completeness | Fail | `CODE_REVIEW.md`에 기록된 `cd kotlin && ./gradlew test` 검증과 실제 재검증 결과가 불일치 |
|
|
| test coverage | Warn | 추가된 Kotlin concurrent 테스트 단독 실행은 통과하지만 전체 suite 통과 근거가 없음 |
|
|
| API contract | Pass | Dart/Go secure crosstest 및 Python/TypeScript self-cell 보강은 기존 API 계약과 일치 |
|
|
| code quality | Warn | Kotlin 신규 테스트 cleanup이 `try/finally`가 아니어서 실패 시 서버/클라이언트 누수 가능 |
|
|
| plan deviation | Pass | 계획된 변경 범위 자체는 대체로 유지됨 |
|
|
| verification trust | Fail | `./gradlew test` 통과 기록을 재현하지 못함 |
|
|
|
|
### 발견된 문제
|
|
|
|
- Required: `kotlin/src/test/kotlin/com/tokilabs/toki_socket/TcpTest.kt:16` - `timeout 90s ./gradlew test`가 daemon 재시작 후에도 `:test` 단계에서 타임아웃됨. jstack 기준 `TcpTest.testTcpSendReceive`의 `received.await()`에서 대기 중이며, `CODE_REVIEW.md`의 Kotlin 전체 테스트 통과 검증과 불일치한다. 전체 suite가 안정적으로 통과하도록 원인을 수정하고 `./gradlew test`를 재검증해야 한다.
|
|
- Required: `kotlin/src/test/kotlin/com/tokilabs/toki_socket/TcpTest.kt:131` / `kotlin/src/test/kotlin/com/tokilabs/toki_socket/WsTest.kt:116` - 새 concurrent 테스트가 `awaitAll()` 이후에만 `client.close()`와 `server.stop()`을 호출한다. 요청 실패/타임아웃 시 cleanup이 건너뛰어 후속 테스트 hang을 유발할 수 있으므로 `try/finally`로 정리 보장을 추가해야 한다.
|
|
|
|
### 다음 단계
|
|
|
|
FAIL: Required 이슈를 해결하는 새 `PLAN.md`와 `CODE_REVIEW.md` 스텁을 작성해 리뷰 루프를 계속한다.
|