chore(profiling): add append_profiling_history function for persistent profiling records

Adds two new functions to harness.py:
- _current_git_ref(): Gets the current git short SHA
- append_profiling_history(): Appends JSON line to profiling/results/history.jsonl

This enables profiling numbers to persist across sessions/dates, with every run
appended to an immutable timeline rather than overwriting per-stage snapshots.

Also adds corresponding test to verify the function writes valid JSON lines.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
stumpylog
2026-07-27 15:49:14 -07:00
co-authored by Claude Sonnet 5
parent 91647eecb5
commit 0506dcad05
2 changed files with 84 additions and 0 deletions
+56
View File
@@ -1,8 +1,13 @@
# profiling/harness.py
from __future__ import annotations
import json
import subprocess
import time
from dataclasses import dataclass
from datetime import UTC
from datetime import datetime
from pathlib import Path
from typing import TYPE_CHECKING
from typing import Any
from typing import Generic
@@ -17,6 +22,8 @@ if TYPE_CHECKING:
from django.db.models import QuerySet
from profiling.seed import ScaleProfile
T = TypeVar("T")
@@ -65,3 +72,52 @@ def capture_explain_analyze(queryset: QuerySet[Any]) -> str:
with connection.cursor() as cur:
cur.execute(f"EXPLAIN ANALYZE {sql}", params)
return "\n".join(row[0] for row in cur.fetchall())
def _current_git_ref() -> str:
result = subprocess.run(
["git", "rev-parse", "--short", "HEAD"],
capture_output=True,
text=True,
check=False,
)
return result.stdout.strip() or "unknown"
def append_profiling_history(
*,
stage: str,
scenario: str,
best_seconds: float,
query_count: int,
scale: ScaleProfile,
code_ref: str | None = None,
) -> None:
"""
Append one line to profiling/results/history.jsonl -- an append-only,
cross-session record of every profiling run. Unlike the per-stage
before/after snapshot JSON files (which the next run of the same stage
overwrites), this never gets clobbered, so a profiling effort picked
back up days later has a full timeline to resume from instead of only
the single most recent comparison.
``code_ref`` should identify the *production* code under test (a short
SHA on the feature branch, not this `profiling` branch) -- pass it
explicitly when known. Left as ``None``, it falls back to this repo's
current ``git rev-parse --short HEAD``, which is only meaningful if
you're actually running from a checkout where that reflects the code
being measured.
"""
results_dir = Path(__file__).parent / "results"
results_dir.mkdir(exist_ok=True)
entry = {
"timestamp": datetime.now(UTC).isoformat(),
"code_ref": code_ref or _current_git_ref(),
"stage": stage,
"scenario": scenario,
"scale": scale,
"best_seconds": best_seconds,
"query_count": query_count,
}
with (results_dir / "history.jsonl").open("a") as f:
f.write(json.dumps(entry) + "\n")
+28
View File
@@ -1,8 +1,12 @@
# profiling/test_harness_self_check.py
from __future__ import annotations
import json
from pathlib import Path
import pytest
from profiling.harness import append_profiling_history
from profiling.harness import require_postgres
from profiling.harness import run_profile
from profiling.seed import seed_permission_dataset
@@ -44,3 +48,27 @@ def test_run_profile_reports_query_count_and_timing() -> None:
assert result.best_seconds >= 0
assert len(result.all_seconds) == 3
assert result.query_count >= 1
def test_append_profiling_history_writes_a_valid_json_line() -> None:
history_path = Path(__file__).parent / "results" / "history.jsonl"
before_lines = (
history_path.read_text().splitlines() if history_path.exists() else []
)
append_profiling_history(
stage="self-check",
scenario="test_append_profiling_history_writes_a_valid_json_line",
best_seconds=0.001,
query_count=0,
scale="medium",
code_ref="test-run",
)
after_lines = history_path.read_text().splitlines()
assert len(after_lines) == len(before_lines) + 1
entry = json.loads(after_lines[-1])
assert entry["stage"] == "self-check"
assert entry["code_ref"] == "test-run"
assert entry["scale"] == "medium"
assert "timestamp" in entry