Skip to content
2 changes: 2 additions & 0 deletions .github/workflows/codspeed.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ jobs:
version: '1.16.5'
- name: Run the benchmarks
uses: CodSpeedHQ/action@f99becdce5e5d51fd556489ebef684f4ecfd6286 # v4.18.5
env:
ZARR_BENCHMARK_CLEAR_CACHE: '1'
with:
mode: walltime
run: hatch run test.py3.12-minimal:pytest tests/benchmarks --codspeed
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ jobs:
- name: Install Hatch
run: python -m pip install hatch==1.16.5
- name: Run Benchmarks
env:
ZARR_BENCHMARK_CLEAR_CACHE: '1'
run: |
hatch env run --env "test.py3.13-minimal" run-benchmark

Expand Down
1 change: 1 addition & 0 deletions changes/4199.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The end-to-end benchmarks no longer invoke `sudo` to drop the OS page cache during a regular `pytest` run. Cache clearing is now opt-in via the `ZARR_BENCHMARK_CLEAR_CACHE` environment variable, which the benchmark CI jobs set.
23 changes: 20 additions & 3 deletions tests/benchmarks/test_e2e.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

from __future__ import annotations

import os
import platform
import subprocess
import warnings
from functools import lru_cache
from operator import getitem, setitem
from typing import TYPE_CHECKING, Any, Literal
Expand All @@ -21,12 +23,27 @@


def clear_cache() -> None:
"""Drop the OS page cache between benchmark rounds.

Requires passwordless sudo, so it is opt-in: set `ZARR_BENCHMARK_CLEAR_CACHE=1`
to enable it (as the benchmark CI jobs do). By default this is a no-op, so a
plain `pytest` run never prompts for a sudo password (see issue #4199).
`sudo -n` guarantees we fail instead of blocking on a password prompt even
when the variable is set.
"""
if os.environ.get("ZARR_BENCHMARK_CLEAR_CACHE", "") not in ("1", "true"):
return
if platform.system() == "Darwin":
subprocess.call(["sync", "&&", "sudo", "purge"])
subprocess.call(["sync"])
subprocess.call(["sudo", "-n", "purge"])
elif platform.system() == "Linux":
subprocess.call(["sudo", "sh", "-c", "sync; echo 3 > /proc/sys/vm/drop_caches"])
subprocess.call(["sudo", "-n", "sh", "-c", "sync; echo 3 > /proc/sys/vm/drop_caches"])
else:
raise Exception("Unsupported platform") # noqa: TRY002
warnings.warn(
f"ZARR_BENCHMARK_CLEAR_CACHE is set but cache clearing is not supported on "
f"{platform.system()}; skipping.",
stacklevel=2,
)


if TYPE_CHECKING:
Expand Down
Loading