Files
MoviePilot/tests/test_postgresql_driver_ab.py
DDSRem 2de976f6b3 Merge pull request #7050 from DDSRem-Dev/codex-comment-migration
docs: 统一全项目中文注释和结构化契约说明
2026-10-17 19:26:29 +08:00

136 lines
4.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
PostgreSQL 驱动 A/B harness 的无 Docker 合同测试。
"""
from __future__ import annotations
import argparse
import importlib.util
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[1]
SCRIPT = ROOT / "scripts" / "perf" / "postgresql_driver_ab.py"
def load_harness():
"""
从脚本路径加载 harness,避免把 scripts 变成运行时 package。
"""
spec = importlib.util.spec_from_file_location("postgresql_driver_ab_test", SCRIPT)
assert spec is not None and spec.loader is not None
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def sample(variant: str, value: float) -> dict:
"""
构造满足汇总合同的单个样本。
"""
return {
"variant": variant,
"postgresql_settings": {"server_version": "18.4"},
"sql_contract": {"fixture_sha256": "fixture", "sql_sha256": "sql"},
"serial_query": {"throughput_ops_s": value},
"concurrent_query": {"throughput_ops_s": value * 2},
"batch_write": {"seconds": 10 / value},
"long_transaction": {"parallel_short_query_seconds": 1 / value},
}
def test_campaign_and_image_arguments_are_strict() -> None:
"""
公开参数不得生成不安全名称或接受可变镜像标签。
"""
harness = load_harness()
assert harness.normalize_campaign("PG-AB.1") == "pg-ab.1"
with pytest.raises(argparse.ArgumentTypeError):
harness.normalize_campaign("../escape")
with pytest.raises(argparse.ArgumentTypeError):
harness.immutable_image("moviepilot-v3:latest")
assert harness.immutable_image(f"moviepilot-v3@sha256:{'a' * 64}")
def test_sample_order_covers_all_balanced_permutations() -> None:
"""
六轮中每个方案必须各占两次首、中、末位置。
"""
harness = load_harness()
orders = [harness.sample_order(index) for index in range(6)]
assert len(set(orders)) == 6
for variant in harness.VARIANTS:
assert [order[0] for order in orders].count(variant) == 2
assert [order[1] for order in orders].count(variant) == 2
assert [order[2] for order in orders].count(variant) == 2
def test_validate_sample_enforces_driver_and_gil_contracts() -> None:
"""
V3t 必须使用 psycopg C 且在基准结束后仍关闭 GIL。
"""
harness = load_harness()
valid = {
"runtime": {
"python_version": "3.14.7",
"implementation": "c",
"gil_before_import": False,
"gil_after_import": False,
"gil_after_benchmark": False,
},
"long_transaction": {
"parallel_short_query_value": "payload-00002",
"parallel_short_query_seconds": 0.01,
"contended_update_seconds": 0.2,
"requested_seconds": 0.25,
},
}
harness.validate_sample("v3t_psycopg3_c", valid)
valid["runtime"]["gil_after_benchmark"] = True
with pytest.raises(harness.HarnessInvalid, match="GIL"):
harness.validate_sample("v3t_psycopg3_c", valid)
def test_summary_keeps_three_variants_separate() -> None:
"""
汇总必须保留三方案,不能把两个标准 V3 驱动合并。
"""
harness = load_harness()
samples = []
for variant, _driver in harness.VARIANTS:
samples.extend((sample(variant, 10.0), sample(variant, 20.0), sample(variant, 30.0)))
summary = harness.summarize(samples)
assert set(summary["metrics"]) == {variant for variant, _ in harness.VARIANTS}
assert summary["metrics"]["v3_psycopg2"]["serial_query_throughput_ops_s"] == 20
assert (
summary["ratios"]["v3t_psycopg3_c"]
["serial_query_throughput_over_v3_psycopg2"]
== 1
)
def test_campaign_requires_complete_matching_results() -> None:
"""
三方案缺样本或业务结果不同都不能生成性能结论。
"""
harness = load_harness()
samples = []
for variant, _driver in harness.VARIANTS:
for _ in range(3):
item = sample(variant, 10.0)
item["serial_query"]["checksum"] = "same"
item["concurrent_query"]["checksums"] = ["same"]
samples.append(item)
harness.validate_campaign(samples, rounds=3)
samples[-1]["serial_query"]["checksum"] = "different"
with pytest.raises(harness.HarnessInvalid, match="校验和"):
harness.validate_campaign(samples, rounds=3)