generated from ttipo/project-base
52c6ebecb6
첫 CI(같은 PC 의 러너)에서 백엔드 단위 테스트의 CPU 시간 단언 두 곳이 넘쳤다 — CI 와 같은 Linux 컨테이너에서 메모리가 모자라고 테스트가 함께 돌 때 평소의 4~7배로 재졌다 (이미지 많은 정화 1.6초 → 5.75초 · 한도 5초, 한도 가까운 본문의 DTO 검사 0.08초 → 0.59초 · 한도 0.5초). 한도를 평소의 10배쯤으로 다시 잡는다 — 막으려는 옛 경로(제곱)는 여전히 확실히 넘는다. 여유가 6.7배뿐이던 HTML 비용 사전 검사도 함께 늘린다(0.3초 · 옛 경로 172초). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
36 lines
2.4 KiB
TypeScript
36 lines
2.4 KiB
TypeScript
/**
|
|
* CPU 시간 스톱워치 — 단위 테스트 전용 도우미 (앱 코드에서 import 하지 않는다).
|
|
*
|
|
* 왜 벽시계(performance.now)가 아닌가: 다른 프로세스가 CPU 를 나눠 쓰면 벽시계 시간은 그만큼 늘어난다.
|
|
* 2026-10-27 바쁜 PC(병렬 테스트·개발 서버와 함께)에서 혼자 0.7~0.8초인 정화가 5.9초·9.1초로 재져
|
|
* 전체 테스트 4번 중 2번이 실패했다. CPU 시간은 이 프로세스가 실제로 계산한 시간만 세므로 다른 작업이 많아도 거의 늘지 않는다 —
|
|
* "계산량이 입력 길이에 비례하는가(예전의 제곱 경로가 돌아오지 않았는가)"를 보는 단언에 쓴다.
|
|
*
|
|
* - 프로세스 전체(GC·JIT 스레드 포함)의 user + system 시간이다 — 한도는 지금 값의 10배쯤 넉넉하게, 예전의 제곱 경로는 확실히 넘는 값으로 둔다.
|
|
* CPU 시간도 늘지 않는 것은 아니다 — 2026-10-28 CI 와 같은 Linux 컨테이너(Docker Desktop)에서 메모리가 모자라고 테스트가 함께 돌 때
|
|
* 평소의 4~7배로 재져, 여유가 3~6배뿐이던 한도 두 곳이 CI 를 실패시켰다(이미지 많은 정화 1.6초 → 5.75초, DTO 검사 0.08초 → 0.59초).
|
|
* - 기다리는 시간(I/O·타이머)은 CPU 시간에 들어가지 않는다 — 그런 단언(예: 파일이 지워질 때까지 기다리기)에는 쓰지 않는다.
|
|
* - Windows 에서는 CPU 시간이 스케줄러 틱(약 15.6ms) 단위로 는다 — 수십 ms 아래를 비교하는 데 쓰지 않는다.
|
|
*
|
|
* 위치: src 밖(test/)이라 빌드(nest build 는 sourceRoot 인 src 만 컴파일한다)와 단위 테스트 커버리지(rootDir 이 src)에 들어가지 않고,
|
|
* 이름이 `*.spec.ts` 가 아니라 테스트로 돌지도 않는다. 단위 테스트는 `@/../test/cpu-time` 으로 부른다 —
|
|
* `@/` 기준이라 부르는 파일의 깊이와 상관없다 (tsconfig paths 와 jest moduleNameMapper 가 그대로 푼다).
|
|
*/
|
|
|
|
const MICROSECONDS_PER_MS = 1_000;
|
|
|
|
/**
|
|
* 지금부터 재기 시작한다. 돌려준 함수를 부르면 그때까지 이 프로세스가 쓴 CPU 시간(ms)을 준다.
|
|
*
|
|
* const cpuMs = startCpuTimer();
|
|
* sanitizeMailHtml(html);
|
|
* expect(cpuMs()).toBeLessThan(5_000);
|
|
*/
|
|
export function startCpuTimer(): () => number {
|
|
const started = process.cpuUsage();
|
|
return () => {
|
|
const { user, system } = process.cpuUsage(started);
|
|
return (user + system) / MICROSECONDS_PER_MS;
|
|
};
|
|
}
|