39 lines
1.4 KiB
Python
39 lines
1.4 KiB
Python
"""回放传输:把既有演练日志作为服务器响应原样回放给客户端。
|
||
|
||
用于 P1 验收"本地状态机与官方响应一致":官方演练记录
|
||
(output/q1/practice/*_actions.json)逐条喂给客户端,客户端重建的
|
||
状态必须与当时服务器返回的虚拟时刻逐步吻合。
|
||
|
||
按录制顺序匹配(客户端的 request_id 生成规则与采集器不同,
|
||
故不参与匹配;故障重试场景请用 ScriptedFaultTransport)。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import json
|
||
from urllib.parse import urlsplit
|
||
|
||
from ..protocol.transport import Transport, TransportResponse
|
||
|
||
|
||
class PlaybackTransport(Transport):
|
||
"""events: 演练日志 [{path, request, response, ...}, ...]。"""
|
||
|
||
def __init__(self, events: list[dict]):
|
||
self.events = list(events)
|
||
self.index = 0
|
||
self.served: list[dict] = []
|
||
|
||
def post(self, url, body, headers, timeout):
|
||
if self.index >= len(self.events):
|
||
raise AssertionError("回放日志已耗尽仍有请求")
|
||
event = self.events[self.index]
|
||
path = urlsplit(url).path
|
||
if path != event["path"]:
|
||
raise AssertionError(
|
||
f"回放顺序不一致: 客户端请求 {path}, 录制预期 {event['path']}")
|
||
self.index += 1
|
||
self.served.append(event)
|
||
return TransportResponse(
|
||
200, json.dumps(event["response"], ensure_ascii=False).encode("utf-8"))
|