holy fuking shit
This commit is contained in:
@@ -33,7 +33,10 @@ class StrictPlayback(PlaybackTransport):
|
||||
raise AssertionError("Replay attempted an extra action")
|
||||
expected = self.events[self.index]
|
||||
actual_request = json.loads(body)
|
||||
without_id = lambda value: {k: v for k, v in value.items() if k != "request_id"}
|
||||
|
||||
def without_id(value):
|
||||
return {k: v for k, v in value.items() if k != "request_id"}
|
||||
|
||||
if (urlsplit(url).path != expected["path"] or
|
||||
without_id(actual_request) != without_id(expected["request"])):
|
||||
raise AssertionError(f"Replay action differs at index {self.index}")
|
||||
@@ -66,6 +69,47 @@ def save_json(path, value):
|
||||
allow_nan=False) + "\n", encoding="utf-8")
|
||||
|
||||
|
||||
def timing_rows(events):
|
||||
"""按官方附件 2 第 4.1 节逐动作累计虚拟时间(微秒),返回明细与汇总。"""
|
||||
position, channel, virtual_us = (0.0, 0.0), 1, 0
|
||||
distance_total, switch_total, move_total_us = 0.0, 0, 0
|
||||
rows = []
|
||||
previous_recorded = 0.0
|
||||
max_local_gap = 0.0
|
||||
for i, event in enumerate(events):
|
||||
request, response = event["request"], event["response"]
|
||||
path = event["path"]
|
||||
distance, switches, action_s = 0.0, 0, 0
|
||||
if path in ("/measure", "/clear"):
|
||||
target = (request["position"]["x"], request["position"]["y"])
|
||||
distance = math.dist(position, target)
|
||||
position = target
|
||||
if path == "/measure":
|
||||
switches = int(channel != request["channel"])
|
||||
channel = request["channel"]
|
||||
action_s = 5
|
||||
else:
|
||||
action_s = 5 if response["clear_result"] == "success" else 3
|
||||
move_us = round(distance / 5 * 1_000_000)
|
||||
virtual_us += move_us + (switches + action_s) * 1_000_000
|
||||
distance_total += distance
|
||||
switch_total += switches
|
||||
move_total_us += move_us
|
||||
recorded = response["virtual_time_s"]
|
||||
gap_us = round(recorded * 1_000_000) - virtual_us
|
||||
max_local_gap = max(max_local_gap,
|
||||
abs(recorded - previous_recorded - distance/5 - switches - action_s))
|
||||
previous_recorded = recorded
|
||||
rows.append({"index": i, "path": path, "request_id": request["request_id"],
|
||||
"channel": request.get("channel", ""), "x": position[0], "y": position[1],
|
||||
"result": response.get("measure_result", response.get("clear_result", "")),
|
||||
"svd_deg": response.get("svd_deg", ""), "distance_m": distance,
|
||||
"move_us": move_us, "switch_s": switches, "action_s": action_s,
|
||||
"recomputed_us": virtual_us, "recorded_s": recorded, "gap_us": gap_us})
|
||||
return rows, virtual_us, distance_total, move_total_us, switch_total, previous_recorded, \
|
||||
max_local_gap
|
||||
|
||||
|
||||
def audit(folder: Path) -> dict:
|
||||
records = [json.loads(line) for line in
|
||||
(folder / "session.jsonl").read_text(encoding="utf-8").splitlines()]
|
||||
@@ -130,40 +174,8 @@ def audit(folder: Path) -> dict:
|
||||
|
||||
# Official attachment 2 section 4.1: accumulate virtual time in microseconds.
|
||||
# Round each move to the nearest microsecond, then add integer action costs.
|
||||
position, channel, virtual_us = (0.0, 0.0), 1, 0
|
||||
distance_total, switch_total, move_total_us = 0.0, 0, 0
|
||||
rows = []
|
||||
previous_recorded = 0.0
|
||||
max_local_gap = 0.0
|
||||
for i, event in enumerate(events):
|
||||
request, response, path = event["request"], event["response"], event["path"]
|
||||
distance, switches, action_s = 0.0, 0, 0
|
||||
if path in ("/measure", "/clear"):
|
||||
target = (request["position"]["x"], request["position"]["y"])
|
||||
distance = math.dist(position, target)
|
||||
position = target
|
||||
if path == "/measure":
|
||||
switches = int(channel != request["channel"])
|
||||
channel = request["channel"]
|
||||
action_s = 5
|
||||
else:
|
||||
action_s = 5 if response["clear_result"] == "success" else 3
|
||||
move_us = round(distance / 5 * 1_000_000)
|
||||
virtual_us += move_us + (switches + action_s) * 1_000_000
|
||||
distance_total += distance
|
||||
switch_total += switches
|
||||
move_total_us += move_us
|
||||
recorded = response["virtual_time_s"]
|
||||
gap_us = round(recorded * 1_000_000) - virtual_us
|
||||
max_local_gap = max(max_local_gap,
|
||||
abs(recorded - previous_recorded - distance/5 - switches - action_s))
|
||||
previous_recorded = recorded
|
||||
rows.append({"index": i, "path": path, "request_id": request["request_id"],
|
||||
"channel": request.get("channel", ""), "x": position[0], "y": position[1],
|
||||
"result": response.get("measure_result", response.get("clear_result", "")),
|
||||
"svd_deg": response.get("svd_deg", ""), "distance_m": distance,
|
||||
"move_us": move_us, "switch_s": switches, "action_s": action_s,
|
||||
"recomputed_us": virtual_us, "recorded_s": recorded, "gap_us": gap_us})
|
||||
rows, virtual_us, distance_total, move_total_us, switch_total, previous_recorded, \
|
||||
max_local_gap = timing_rows(events)
|
||||
checks["all_timestamps_match_microsecond_recomputation"] = all(r["gap_us"] == 0 for r in rows)
|
||||
real_s = (events[-1]["response"]["real_timestamp_ms"] -
|
||||
events[0]["response"]["real_timestamp_ms"]) / 1000
|
||||
@@ -206,7 +218,8 @@ def audit(folder: Path) -> dict:
|
||||
"clear_time_s": sum(r["action_s"] for r in rows if r["path"] == "/clear"),
|
||||
"timing_audit": {
|
||||
"original_unquantized_mismatch_count": len(raw_timing["mismatches"]),
|
||||
"original_unquantized_final_gap_s": previous_recorded - raw_timing["final_virtual_time_s"],
|
||||
"original_unquantized_final_gap_s":
|
||||
previous_recorded - raw_timing["final_virtual_time_s"],
|
||||
"max_single_action_unquantized_gap_s": max_local_gap,
|
||||
"microsecond_mismatch_count": sum(r["gap_us"] != 0 for r in rows),
|
||||
"explanation": "原复算累计未量化浮点耗时;按动作移动耗时取最近整数微秒后,所有官方时刻完全一致。",
|
||||
|
||||
Reference in New Issue
Block a user