본문으로 건너뛰기

스트레스 테스트

스트레스 제품군. 사용자가 돈을 잃을 수 있는 앱 부분을 적대적, 난수화, 폴트 주입된 워크로드로 때립니다 — 주로 복사 트레이딩. 올바른 상태를 주장합니다. tests/StressTests에 있으며 일반 dotnet test 초록 게이트에서 실행됩니다.

접근 — 결정론적 시뮬레이션 테스트 (DST)​

분산 금융 시스템을 스트레스 테스트하는 가장 좋은 방법은 결정론적 시뮬레이션 테스트, TigerBeetle, FoundationDB, Antithesis: 실제 논리를 시뮬레이션된 세계에 대해 실행하고 시드된 난수화 워크로드 + 주입된 폴트로駆動하며 quiescence에서 불변량을 주장합니다. 모든 것이 시드 + 결정론적 → 실패는 정확한 시드에서 재현됩니다. 결합:

  • 카오스 엔지니어링 폴트 주입 (Netflix Chaos Monkey 스타일) — 연결 끊김, 주문 거부, 토큰 회전, 노드 죽음.
  • 속성 기반 불변량 — 정확한 호출 시퀀스가 아닙니다; 이벤트 간 개입 방식에 관계없이 유지되어야 하는 속성을 주장합니다 (수렴, 고아 없음, 최대 하나의 임대 보유자).

앱은 이미 완벽한 DST 세계 모델과 함께 제공됩니다: FakeTradingSession, cTrader 충실한 인메모리 Open API 세션. 스트레스 제품군은 모의가 아니라 이를 재사용합니다 (연결됨, 단일 단일 진실 공급원), 시뮬레이션된 브로커가 실제 브로커처럼 행동합니다.

무엇을 커버하는가​

복사 트레이딩 (주요 초점)​

CopyDstWorld (tests/StressTests/CopyTrading/)를 통해 구동되며 라이브 CopyEngineHost를 가짜 세션에 대해 실행하고 membership-일관된 소스 워크로드를 발급:

시나리오스트레스
Mass_fan_out…1 소스 → 80 대상, 150 열기 then 닫기; 전체 팬아웃 + 드레인
High_frequency_open_close…300 rapid interleaved 열기/닫기; 유출된 포지션 없음
Partial_close_and_scale_in_storm…부분-닫기 + 스케일-인 혼란; 라벨-세트 안정성
Connection_flap_storm…반복 소켓 끊김/재연결 + 비행 중 동기화 해제; 재동기화 수렴
Order_rejection_cascade…하위 집합이 모든 주문을 거부; 건강한 대상은 영향받지 않고 재동기화를 통해 자체 복구
Token_rotation_storm…주문 폭풍 중 Rapid 제자리 토큰 스왑
Randomized_chaos_workload… (10 시드)DST 핵심 — 모든 이벤트 유형 + 모든 폴트가 예측 불가능하게 interleaved
CopyLeaseReclaimStressTests노드 죽음 + 임대를 클러스터规模的로 회수 (순수 도메인, FakeTimeProvider)

수렴 불변량. 휴지에서 모든 건강한 대상은 여전히 열린 소스 포지션 세트를 정확히 미러합니다 — 고아 없음, 누락 없음. 라벨 세트에서 주장됩니다 (스케일-인이 동일한 소스 라벨 아래에 두 번째 대상 포지션을 정당하게 열므로 중복 라벨이 예상됨). 현재 주문을 거부하는 대상은 지연 허용되며 복구 후 조정됩니다.

임대 불변량. 노드가 죽고 시드된 일정에 따라 부활하는 클러스터에서 최대 하나의 노드가 프로필에 대한 유효한 임인을 항상 보유합니다; 죽은 노드의 임인은 만료 시 정확히 만료되며 건강 클러스터는 모든 프로필이 정확히 하나의 노드에 의해 보유된 것으로 정착됩니다. CopyEngineSupervisor'의 클레임 술어를 CopyProfile 도메인 임대 메서드에 대해 미러링합니다.

하네스의 스레드 안전성​

FakeTradingSession은 단일 스레드입니다; 스트레스 워크로드가 호스트가 읽기/쓰기하는 동안 테스트 스레드에서 변형합니다. SyncTradingSession이 각 세션 작업을 하나의 게이트에서 원자적으로 만들지만 (재연결 콜백에서 게이트를 보유하여 호스트의 _stateGate와 잠금 순서를 반전시키고 데드락을 발생시키지 않음) 재연결 콜백에서 게이트를 들고 있지 않습니다 — 시뮬레이터 자체는 변경되지 않고 그대로 둡니다.

발견된 버그​

  • CopyEngineHost의 시작 재동기화 경주. OnReconnected가 초기 참조-로드 + 첫 번째 재동기화 전에 연결되어 있어서 소켓 플랩이 시작 중일 때 두 번째 재동기화를 동시에 실행하고 호스트의 비동시 상태 사전(_symbolDetails, _sourceVolumes)을 손상시킬 수 있었습니다. 수정됨: 시작 로드 + 첫 번째 재동기화를 게이트 아래에서 실행. 프로덕션 경주, 테스트 아티팩트가 아닙니다 — DST 카오스 워크로드가 그것을 표면화했습니다.

실행​

dotnet test tests/StressTests/StressTests.csproj

제품군 직렬화됩니다 ([assembly: CollectionBehavior(DisableTestParallelization = true)]): 각 테스트가 라이브 호스트 백그라운드 루프를 회전하고 벽 시계 아래 quiescence까지驱动器, 그래서 병렬 실행이 호스트 작업을 굶주리게 하고 수렴 시간 초과를 flaky하게 만듭니다. 워크로드는 제품군이 기본 초록 게이트에 유지되도록 몇 초 내에 완료되도록 크기 조정됩니다. 실패는 해당 시드를 인쇄합니다; 해당 시드를 다시 실행하여 정확한 인터리빙을 재현합니다.

확장​

  • 새로운 복사 동작 → CopyDstWorld에 소스 op 추가 (이벤트 스트림과 소스 북 멤버십 일관성 유지) + 가加权重ケース in CopyChaosDstTests. 대상 포지션을 생성하거나 은퇴시킬 수 있다면 수렴 불변량이 여전히 유지되는지 확인합니다.
  • 새로운 폴트 → CopyDstWorld에 인젝터 추가 (SyncTradingSession을 통해 FakeTradingSession'의 제어 표면에 위임) + 명명된 시나리오 plus 카오스 혼합에서 연습합니다.
  • 시뮬레이터를 cTrader-충실하게 유지합니다 (루트 CLAUDE.md 의무 참조); 스트레스 테스트를 통과하도록 약화하지 마세요.