LabHub
学习 学习路径 课程

테스트 도구 실전 · sleep 없이 시간 경계를 재현한다 · 实验

sleep 없이 시간 경계를 재현한다

在 LabHub 中继续学习

목표

가짜 시계로 제한 창·재시도 시각·사용자별 격리를 검증합니다.

왜 중요한가

요청 제한 테스트에 sleep을 넣었더니 개발 PC에서는 통과하고 CI에서는 실패했다. 느린 실행기가 시간 경계를 바꾸고 테스트 자체도 오래 걸렸다. 시간은 프로그램의 입력이므로 호출자가 제어할 수 있게 만들고 경계를 정확히 밟아야 한다.

단계

1. /root/work/test-clock-window-lab/test_service.py에서 제공된 service.py의 다음 공개 계약을 테스트하세요: validate_limit(limit, window)는 bool 제외 양의 int limit와 양의 유한 int/float window만 허용해 (limit, float(window))를 반환합니다. 나머지는 ValueError입니다. 정상 구현에서는 통과하고 이 계약을 어긴 구현에서는 실제 테스트 본문의 실패로 검출해야 합니다. 앞 단계 테스트를 유지하며 test_ 함수를 추가하세요.

처음 한 번 준비하세요. 기존 파일은 덮어쓰지 않습니다.

mkdir -p /root/work/test-clock-window-labtest -e /root/work/test-clock-window-lab/service.py || cp /opt/fixtures/ten_labs/test-clock-window-lab/service.py /root/work/test-clock-window-lab/service.pytest -e /root/work/test-clock-window-lab/test_service.py || cp /opt/fixtures/ten_labs/test-clock-window-lab/test_service.py /root/work/test-clock-window-lab/test_service.pycd /root/work/test-clock-window-lab

2. /root/work/test-clock-window-lab/test_service.py에서 제공된 service.py의 다음 공개 계약을 테스트하세요: active(history, now, window)는 now-window보다 큰 시각만 원래 순서의 새 리스트로 반환합니다. history는 정렬된 비감소 시각입니다. 정상 구현에서는 통과하고 이 계약을 어긴 구현에서는 실제 테스트 본문의 실패로 검출해야 합니다. 앞 단계 테스트를 유지하며 test_ 함수를 추가하세요.

3. /root/work/test-clock-window-lab/test_service.py에서 제공된 service.py의 다음 공개 계약을 테스트하세요: retry_after(history, now, window)는 이미 정리된 비어 있지 않은 history의 첫 시각+window-now를 ceil한 값과 0 중 큰 정수입니다. 빈 리스트는 0입니다. 정상 구현에서는 통과하고 이 계약을 어긴 구현에서는 실제 테스트 본문의 실패로 검출해야 합니다. 앞 단계 테스트를 유지하며 test_ 함수를 추가하세요.

4. /root/work/test-clock-window-lab/test_service.py에서 제공된 service.py의 다음 공개 계약을 테스트하세요: history_for(state, key)는 없는 키면 빈 리스트, 있으면 그 기록의 사본을 반환합니다. 조회만으로 state를 수정하지 않습니다. 정상 구현에서는 통과하고 이 계약을 어긴 구현에서는 실제 테스트 본문의 실패로 검출해야 합니다. 앞 단계 테스트를 유지하며 test_ 함수를 추가하세요.

5. /root/work/test-clock-window-lab/test_service.py에서 제공된 service.py의 다음 공개 계약을 테스트하세요: admit(state, key, now, limit, window)는 설정 검증 후 해당 키의 만료 기록을 정리합니다. 여유가 있으면 now를 추가하고 (True,0), 꽉 찼으면 추가하지 않고 (False,retry_after)를 반환합니다. 정상 구현에서는 통과하고 이 계약을 어긴 구현에서는 실제 테스트 본문의 실패로 검출해야 합니다. 앞 단계 테스트를 유지하며 test_ 함수를 추가하세요.

6. /root/work/test-clock-window-lab/test_service.py에서 제공된 service.py의 다음 공개 계약을 테스트하세요: client_key(value)는 1~40자 ASCII 영문·숫자·하이픈 문자열을 그대로 반환하고 나머지는 ValueError입니다. 정상 구현에서는 통과하고 이 계약을 어긴 구현에서는 실제 테스트 본문의 실패로 검출해야 합니다. 앞 단계 테스트를 유지하며 test_ 함수를 추가하세요.

7. /root/work/test-clock-window-lab/test_service.py에서 제공된 service.py의 다음 공개 계약을 테스트하세요: limited_response(wait)는 상태 429, 본문 {error:'rate_limited'}, Retry-After 헤더는 wait를 문자열로 만든 JSONResponse입니다. 정상 구현에서는 통과하고 이 계약을 어긴 구현에서는 실제 테스트 본문의 실패로 검출해야 합니다. 앞 단계 테스트를 유지하며 test_ 함수를 추가하세요.

8. /root/work/test-clock-window-lab/test_service.py에서 제공된 service.py의 다음 공개 계약을 테스트하세요: create_app(clock, limit=2, window=10)는 GET /work에서 X-Client-ID를 검사해 잘못된 키는 400 {error:'invalid_client'}, 허용은 200 {ok:True}, 초과는 limited_response입니다. state는 앱별로 분리합니다. 정상 구현에서는 통과하고 이 계약을 어긴 구현에서는 실제 테스트 본문의 실패로 검출해야 합니다. 앞 단계 테스트를 유지하며 test_ 함수를 추가하세요.

참고

8个步骤

  1. 설정을 검증한다 — 테스트
  2. 창의 왼쪽 경계를 제외한다 — 테스트
  3. 대기 시간을 올림한다 — 테스트
  4. 키마다 기록을 나눈다 — 테스트
  5. 허용 요청만 기록한다 — 테스트
  6. 클라이언트 키를 검증한다 — 테스트
  7. 거절 응답을 만든다 — 테스트
  8. 가상 시간으로 요청 흐름을 끝낸다 — 테스트