mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-09-14 08:00:10 +00:00
480 lines
15 KiB
Python
480 lines
15 KiB
Python
from __future__ import annotations
|
|
|
|
import importlib.util
|
|
import json
|
|
import os
|
|
import sys
|
|
from contextlib import asynccontextmanager
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
import pytest
|
|
|
|
|
|
def _load_module():
|
|
path = Path(__file__).resolve().parents[1] / "scripts/benchmark/checkpoint/bench_channels.py"
|
|
spec = importlib.util.spec_from_file_location("bench_checkpoint_channels", path)
|
|
assert spec is not None
|
|
module = importlib.util.module_from_spec(spec)
|
|
assert spec.loader is not None
|
|
sys.modules[spec.name] = module
|
|
spec.loader.exec_module(module)
|
|
return module
|
|
|
|
|
|
bench = _load_module()
|
|
|
|
|
|
def test_parse_positive_int_csv_deduplicates_in_input_order(capsys: pytest.CaptureFixture[str]) -> None:
|
|
assert bench._parse_positive_int_csv("100,10,100,500", option="--updates") == [100, 10, 500]
|
|
assert "ignored duplicate value(s): 100" in capsys.readouterr().err
|
|
|
|
|
|
def test_parse_choice_csv_reports_duplicate_values(capsys: pytest.CaptureFixture[str]) -> None:
|
|
assert bench._parse_choice_csv("full,full,delta", option="--modes", choices=("full", "delta")) == ["full", "delta"]
|
|
assert "ignored duplicate value(s): full" in capsys.readouterr().err
|
|
|
|
|
|
@pytest.mark.parametrize("value", ["", "0", "-1", "one", "1,,2"])
|
|
def test_parse_positive_int_csv_rejects_invalid_values(value: str) -> None:
|
|
with pytest.raises(ValueError, match="--updates"):
|
|
bench._parse_positive_int_csv(value, option="--updates")
|
|
|
|
|
|
def test_deterministic_message_has_exact_payload_bytes_and_stable_identity() -> None:
|
|
first = bench._message_for_update(3, 128)
|
|
second = bench._message_for_update(3, 128)
|
|
|
|
assert first == second
|
|
assert first.id == "bench-message-00000003"
|
|
assert first.type == "ai"
|
|
assert len(first.content.encode("utf-8")) == 128
|
|
|
|
|
|
def test_expand_cases_alternates_modes_without_cross_product_reordering() -> None:
|
|
cases = bench._expand_cases(
|
|
modes=["full", "delta"],
|
|
backends=["sqlite"],
|
|
update_counts=[10, 100],
|
|
payload_bytes=[128],
|
|
repetitions=2,
|
|
seed=7,
|
|
)
|
|
|
|
assert [(case.repetition, case.update_count, case.mode) for case in cases] == [
|
|
(0, 10, "full"),
|
|
(0, 10, "delta"),
|
|
(0, 100, "delta"),
|
|
(0, 100, "full"),
|
|
(1, 10, "delta"),
|
|
(1, 10, "full"),
|
|
(1, 100, "full"),
|
|
(1, 100, "delta"),
|
|
]
|
|
|
|
|
|
def test_oversized_filter_skips_full_and_delta_as_a_comparable_pair() -> None:
|
|
cases = bench._expand_cases(
|
|
modes=["full", "delta"],
|
|
backends=["memory"],
|
|
update_counts=[10, 100],
|
|
payload_bytes=[128],
|
|
repetitions=1,
|
|
seed=1,
|
|
)
|
|
|
|
kept, skipped = bench._filter_oversized_pairs(cases, max_bytes=100_000)
|
|
|
|
assert {(case.update_count, case.mode) for case in kept} == {(10, "full"), (10, "delta")}
|
|
assert {(case.update_count, case.mode) for case in skipped} == {(100, "full"), (100, "delta")}
|
|
|
|
|
|
def test_oversized_filter_applies_full_cap_to_every_swept_delta_cadence() -> None:
|
|
cases = bench._expand_cases(
|
|
modes=["full", "delta"],
|
|
backends=["memory"],
|
|
update_counts=[100],
|
|
payload_bytes=[128],
|
|
repetitions=1,
|
|
seed=1,
|
|
snapshot_frequencies=[1, 250, 1000],
|
|
)
|
|
|
|
kept, skipped = bench._filter_oversized_pairs(cases, max_bytes=100_000)
|
|
|
|
assert kept == []
|
|
assert {(case.mode, case.snapshot_frequency) for case in skipped} == {
|
|
("full", bench.PRODUCTION_SNAPSHOT_FREQUENCY),
|
|
("delta", 1),
|
|
("delta", 250),
|
|
("delta", 1000),
|
|
}
|
|
|
|
|
|
def test_oversized_filter_does_not_suppress_a_delta_only_diagnostic() -> None:
|
|
case = bench.BenchmarkCase(
|
|
mode="delta",
|
|
backend="memory",
|
|
update_count=2000,
|
|
payload_bytes=4096,
|
|
repetition=0,
|
|
seed=1,
|
|
)
|
|
|
|
kept, skipped = bench._filter_oversized_pairs([case], max_bytes=1)
|
|
|
|
assert kept == [case]
|
|
assert skipped == []
|
|
|
|
|
|
def test_help_explains_delta_only_runs_bypass_full_payload_cap() -> None:
|
|
assert "delta-only" in bench._build_parser().format_help()
|
|
|
|
|
|
def test_expand_cases_sweeps_delta_frequencies_without_duplicating_full_cases() -> None:
|
|
cases = bench._expand_cases(
|
|
modes=["full", "delta"],
|
|
backends=["memory"],
|
|
update_counts=[10],
|
|
payload_bytes=[128],
|
|
repetitions=1,
|
|
seed=1,
|
|
snapshot_frequencies=[100, 250, 500, 1000],
|
|
)
|
|
|
|
full_cases = [case for case in cases if case.mode == "full"]
|
|
delta_cases = [case for case in cases if case.mode == "delta"]
|
|
assert len(full_cases) == 1
|
|
assert full_cases[0].snapshot_frequency == bench.PRODUCTION_SNAPSHOT_FREQUENCY
|
|
assert sorted(case.snapshot_frequency for case in delta_cases) == [100, 250, 500, 1000]
|
|
|
|
|
|
def test_case_rejects_non_positive_snapshot_frequency() -> None:
|
|
with pytest.raises(ValueError, match="snapshot_frequency"):
|
|
bench.BenchmarkCase(
|
|
mode="delta",
|
|
backend="memory",
|
|
update_count=4,
|
|
payload_bytes=64,
|
|
repetition=0,
|
|
seed=1,
|
|
snapshot_frequency=0,
|
|
)
|
|
|
|
|
|
def test_shared_backend_thread_ids_are_case_scoped_and_stable() -> None:
|
|
full = bench.BenchmarkCase(mode="full", backend="postgres", update_count=4, payload_bytes=64, repetition=0, seed=1)
|
|
delta = bench.BenchmarkCase(mode="delta", backend="postgres", update_count=4, payload_bytes=64, repetition=0, seed=1)
|
|
|
|
full_thread_id = bench._config(full)["configurable"]["thread_id"]
|
|
|
|
assert full_thread_id == bench._config(full)["configurable"]["thread_id"]
|
|
assert full_thread_id != bench._config(delta)["configurable"]["thread_id"]
|
|
assert full_thread_id.startswith("checkpoint-bench-")
|
|
|
|
|
|
def test_memory_smoke_case_materializes_at_low_snapshot_frequency(tmp_path: Path) -> None:
|
|
case = bench.BenchmarkCase(
|
|
mode="delta",
|
|
backend="memory",
|
|
update_count=6,
|
|
payload_bytes=64,
|
|
repetition=0,
|
|
seed=1,
|
|
snapshot_frequency=2,
|
|
)
|
|
|
|
row = bench._run_case(case, work_dir=tmp_path)
|
|
|
|
assert row["success"] is True
|
|
assert row["snapshot_frequency"] == 2
|
|
assert row["actual_message_count"] == 6
|
|
|
|
|
|
def test_cross_mode_validation_rejects_materialized_state_mismatch() -> None:
|
|
rows = [
|
|
{
|
|
"success": True,
|
|
"mode": "full",
|
|
"backend": "sqlite",
|
|
"scenario": "append",
|
|
"snapshot_frequency": 1000,
|
|
"update_count": 10,
|
|
"payload_bytes": 128,
|
|
"repetition": 0,
|
|
"actual_message_count": 10,
|
|
"content_sha256": "full-digest",
|
|
},
|
|
{
|
|
"success": True,
|
|
"mode": "delta",
|
|
"backend": "sqlite",
|
|
"scenario": "append",
|
|
"snapshot_frequency": 1000,
|
|
"update_count": 10,
|
|
"payload_bytes": 128,
|
|
"repetition": 0,
|
|
"actual_message_count": 10,
|
|
"content_sha256": "delta-digest",
|
|
},
|
|
]
|
|
|
|
bench._validate_cross_mode_rows(rows)
|
|
|
|
assert all(row["success"] is False for row in rows)
|
|
assert all("cross-mode" in row["error"] for row in rows)
|
|
|
|
|
|
@pytest.mark.parametrize("mode", ["full", "delta"])
|
|
def test_memory_smoke_case_materializes_expected_state(mode: str, tmp_path: Path) -> None:
|
|
case = bench.BenchmarkCase(
|
|
mode=mode,
|
|
backend="memory",
|
|
update_count=4,
|
|
payload_bytes=64,
|
|
repetition=0,
|
|
seed=1,
|
|
)
|
|
|
|
row = bench._run_case(case, work_dir=tmp_path)
|
|
|
|
assert row["success"] is True
|
|
assert row["expected_message_count"] == 4
|
|
assert row["actual_message_count"] == 4
|
|
assert row["warm_read_ms"] >= 0
|
|
assert row["cold_read_ms"] >= 0
|
|
assert row["saver_reopen_ms"] == 0
|
|
assert len(row["content_sha256"]) == 64
|
|
assert row["db_bytes"] is None
|
|
assert row["logical_checkpoint_bytes"] is not None
|
|
assert row["logical_checkpoint_bytes"] == row["checkpoint_bytes"] + row["blob_bytes"]
|
|
assert row["logical_write_bytes"] == row["write_bytes"]
|
|
assert row["blob_rows"] > 0
|
|
|
|
|
|
def test_memory_case_keeps_timings_when_private_storage_stats_change(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
|
|
case = bench.BenchmarkCase(
|
|
mode="delta",
|
|
backend="memory",
|
|
update_count=2,
|
|
payload_bytes=32,
|
|
repetition=0,
|
|
seed=1,
|
|
)
|
|
|
|
def fail_storage_stats(*_args, **_kwargs):
|
|
raise AttributeError("private saver layout changed")
|
|
|
|
monkeypatch.setattr(bench, "_memory_storage_stats", fail_storage_stats)
|
|
|
|
row = bench._run_case(case, work_dir=tmp_path)
|
|
|
|
assert row["success"] is True
|
|
assert row["write_total_ms"] >= 0
|
|
assert row["logical_checkpoint_bytes"] is None
|
|
assert row["checkpoint_bytes"] is None
|
|
assert row["blob_bytes"] is None
|
|
assert row["logical_write_bytes"] is None
|
|
assert row["write_bytes"] is None
|
|
assert row["checkpoint_rows"] is None
|
|
assert row["blob_rows"] is None
|
|
assert row["write_rows"] is None
|
|
assert "private saver layout changed" in row["storage_stats_error"]
|
|
|
|
|
|
@pytest.mark.parametrize("mode", ["full", "delta"])
|
|
def test_sqlite_smoke_case_reports_durable_and_logical_storage(mode: str, tmp_path: Path) -> None:
|
|
case = bench.BenchmarkCase(
|
|
mode=mode,
|
|
backend="sqlite",
|
|
update_count=3,
|
|
payload_bytes=64,
|
|
repetition=0,
|
|
seed=2,
|
|
)
|
|
|
|
row = bench._run_case(case, work_dir=tmp_path)
|
|
|
|
assert row["success"] is True
|
|
assert row["db_bytes"] > 0
|
|
assert row["durable_db_bytes"] > 0
|
|
assert row["logical_checkpoint_bytes"] > 0
|
|
assert row["logical_write_bytes"] > 0
|
|
assert row["checkpoint_rows"] > 0
|
|
assert row["checkpoint_bytes"] > 0
|
|
assert row["blob_rows"] == 0
|
|
assert row["blob_bytes"] == 0
|
|
assert row["write_rows"] > 0
|
|
assert row["write_bytes"] > 0
|
|
assert row["logical_checkpoint_bytes"] == row["checkpoint_bytes"] + row["blob_bytes"]
|
|
assert row["logical_write_bytes"] == row["write_bytes"]
|
|
|
|
|
|
class _FakePostgresCursor:
|
|
def __init__(self, rows: list[dict[str, int]]) -> None:
|
|
self._rows = iter(rows)
|
|
self.executed: list[tuple[str, tuple[str, ...]]] = []
|
|
|
|
async def execute(self, query: str, params: tuple[str, ...]) -> None:
|
|
self.executed.append((query, params))
|
|
|
|
async def fetchone(self) -> dict[str, int]:
|
|
return next(self._rows)
|
|
|
|
|
|
class _FakePostgresSaver:
|
|
def __init__(self, cursor: _FakePostgresCursor) -> None:
|
|
self.cursor = cursor
|
|
|
|
@asynccontextmanager
|
|
async def _cursor(self) -> Any:
|
|
yield self.cursor
|
|
|
|
|
|
@pytest.mark.anyio
|
|
async def test_postgres_storage_stats_normalize_checkpoint_tables() -> None:
|
|
cursor = _FakePostgresCursor(
|
|
[
|
|
{"rows": 4, "bytes": 100},
|
|
{"rows": 7, "bytes": 250},
|
|
{"rows": 9, "bytes": 400},
|
|
]
|
|
)
|
|
|
|
stats = await bench._postgres_storage_stats(_FakePostgresSaver(cursor), "thread-1")
|
|
|
|
assert stats == {
|
|
"checkpoint_rows": 4,
|
|
"checkpoint_bytes": 100,
|
|
"blob_rows": 7,
|
|
"blob_bytes": 250,
|
|
"write_rows": 9,
|
|
"write_bytes": 400,
|
|
"logical_checkpoint_bytes": 350,
|
|
"logical_write_bytes": 400,
|
|
}
|
|
assert [params for _query, params in cursor.executed] == [("thread-1",)] * 3
|
|
assert "FROM checkpoints" in cursor.executed[0][0]
|
|
assert "FROM checkpoint_blobs" in cursor.executed[1][0]
|
|
assert "FROM checkpoint_writes" in cursor.executed[2][0]
|
|
|
|
|
|
def test_postgres_backend_requires_explicit_connection_uri(monkeypatch: pytest.MonkeyPatch, tmp_path: Path, capsys: pytest.CaptureFixture[str]) -> None:
|
|
monkeypatch.delenv("TEST_POSTGRES_URI", raising=False)
|
|
|
|
with pytest.raises(SystemExit, match="2"):
|
|
bench.main(["--backends", "postgres", "--output", str(tmp_path / "results.jsonl")])
|
|
|
|
assert "TEST_POSTGRES_URI" in capsys.readouterr().err
|
|
|
|
|
|
def test_postgres_failure_does_not_expose_connection_uri(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
|
|
uri = "postgresql://benchmark-user:secret@example.invalid/checkpoints"
|
|
monkeypatch.setenv("TEST_POSTGRES_URI", uri)
|
|
|
|
async def fail_case(*_args: Any, **_kwargs: Any) -> dict[str, Any]:
|
|
raise RuntimeError(f"could not connect to {uri}")
|
|
|
|
monkeypatch.setattr(bench, "_run_postgres_case", fail_case)
|
|
case = bench.BenchmarkCase(mode="delta", backend="postgres", update_count=1, payload_bytes=32, repetition=0, seed=1)
|
|
|
|
row = bench._run_case(case, work_dir=tmp_path)
|
|
|
|
assert row["success"] is False
|
|
assert uri not in row["error"]
|
|
assert "<TEST_POSTGRES_URI>" in row["error"]
|
|
|
|
|
|
@pytest.mark.anyio
|
|
async def test_postgres_smoke_case_reports_normalized_storage() -> None:
|
|
uri = os.environ.get("TEST_POSTGRES_URI")
|
|
if not uri:
|
|
pytest.skip("TEST_POSTGRES_URI is not set")
|
|
|
|
case = bench.BenchmarkCase(
|
|
mode="delta",
|
|
backend="postgres",
|
|
update_count=3,
|
|
payload_bytes=64,
|
|
repetition=0,
|
|
seed=4,
|
|
)
|
|
row = await bench._run_postgres_case(case, [bench._message_for_update(index, case.payload_bytes) for index in range(case.update_count)], uri)
|
|
|
|
assert row["actual_message_count"] == 3
|
|
assert row["checkpoint_rows"] > 0
|
|
assert row["checkpoint_bytes"] > 0
|
|
assert row["blob_rows"] > 0
|
|
assert row["blob_bytes"] > 0
|
|
assert row["write_rows"] > 0
|
|
assert row["write_bytes"] > 0
|
|
|
|
|
|
def test_controller_writes_versioned_jsonl_without_sensitive_case_paths(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
|
|
output = tmp_path / "result.jsonl"
|
|
child_git_shas = []
|
|
|
|
def fake_run_child(case, *, timeout_seconds, git_sha, profile_dir=None):
|
|
child_git_shas.append(git_sha)
|
|
return {
|
|
"schema_version": bench.SCHEMA_VERSION,
|
|
"benchmark_version": bench.BENCHMARK_VERSION,
|
|
"success": True,
|
|
"error": None,
|
|
"mode": case.mode,
|
|
"backend": case.backend,
|
|
"scenario": case.scenario,
|
|
"snapshot_frequency": case.snapshot_frequency,
|
|
"update_count": case.update_count,
|
|
"payload_bytes": case.payload_bytes,
|
|
"repetition": case.repetition,
|
|
"actual_message_count": case.update_count,
|
|
"content_sha256": "same",
|
|
}
|
|
|
|
monkeypatch.setattr(bench, "_run_child_case", fake_run_child)
|
|
monkeypatch.setattr(bench, "_resolve_git_sha", lambda: "controller-sha")
|
|
|
|
rc = bench.main(
|
|
[
|
|
"--modes",
|
|
"full,delta",
|
|
"--backends",
|
|
"memory",
|
|
"--updates",
|
|
"2",
|
|
"--payload-bytes",
|
|
"32",
|
|
"--repetitions",
|
|
"1",
|
|
"--output",
|
|
str(output),
|
|
]
|
|
)
|
|
|
|
assert rc == 0
|
|
rows = [json.loads(line) for line in output.read_text(encoding="utf-8").splitlines()]
|
|
assert [row["mode"] for row in rows] == ["full", "delta"]
|
|
assert all(row["schema_version"] == bench.SCHEMA_VERSION for row in rows)
|
|
assert all("work_dir" not in row and "database_path" not in row for row in rows)
|
|
assert child_git_shas == ["controller-sha", "controller-sha"]
|
|
|
|
|
|
def test_profiled_case_writes_loadable_stats(tmp_path: Path) -> None:
|
|
case = bench.BenchmarkCase(
|
|
mode="delta",
|
|
backend="memory",
|
|
update_count=2,
|
|
payload_bytes=32,
|
|
repetition=0,
|
|
seed=3,
|
|
)
|
|
profile_path = tmp_path / bench._profile_filename(case)
|
|
|
|
row = bench._run_profiled_case(case, work_dir=tmp_path / "work", profile_path=profile_path)
|
|
|
|
assert row["success"] is True
|
|
assert row["profiled"] is True
|
|
assert profile_path.is_file()
|
|
assert profile_path.stat().st_size > 0
|