From 8f0d123e692a1a2a4e94d1d3690f9e3920fe2ac4 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 10 May 2026 10:12:01 -0500 Subject: [PATCH 1/2] tests(perf[conftest]) Pin \$SHELL=/bin/sh in autouse fixture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit why: Profiling tmuxp's test suite showed the dominant per-pane cost was tmux spawning the contributor's interactive \$SHELL — typically ``/bin/zsh`` with a full rcfile chain (oh-my-zsh, plugins, prompt themes, etc.) — for every pane created across the suite. Each init costs ~60ms warm and up to ~400ms cold; multiplied across hundreds of pane spawns in workspace/builder tests, that's the single largest line item in suite wall time. tmux falls back to ``\$SHELL`` for new panes when ``default-shell`` is unset (the default in libtmux's bundled test ``.tmux.conf``), so monkey-patching \$SHELL=/bin/sh in an autouse function-scoped fixture forces every test pane to spawn ``/bin/sh`` instead. Empty rcfiles, deterministic prompt, no plugin chains. A/B measured locally with the project's standard ``uv run py.test`` (defaults: ``--reruns=0 --doctest-modules``): master ~76-78s pytest, ~71s wall this branch (1st run) 37.01s pytest, 35.08s wall this branch (2nd run) 36.24s pytest, 34.29s wall That's a ~51% wall-time reduction, consistent with the upstream libtmux PR (tmux-python/libtmux#662) that pins the same env var in libtmux's pytest plugin and reports a similar "~70s -> ~32s" delta. Applying the pin at the tmuxp conftest level lands the gain immediately without waiting for the libtmux PR to merge and release; once libtmux ships the upstream pin, this commit becomes redundant and can be reverted cleanly. what: - conftest.py: add ``_pin_test_shell_env`` function-scoped autouse fixture that calls ``monkeypatch.setenv("SHELL", "/bin/sh")``. ``monkeypatch`` restores the prior value at teardown so no global state leaks across tests or out of pytest's process. - Leading-underscore name signals "internal autouse plumbing" — no test should depend on it explicitly. - USING_ZSH constant and ``zshrc`` autouse-on-USING_ZSH fixture retained for now; they become dead at runtime once \$SHELL is always ``/bin/sh`` (no zsh first-run greeting to suppress) but the cleanup is left as a follow-up to keep this commit's diff minimal and the perf claim independently revertible. --- conftest.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/conftest.py b/conftest.py index 5ae04a57a3..1f0583439e 100644 --- a/conftest.py +++ b/conftest.py @@ -30,6 +30,20 @@ USING_ZSH = "zsh" in os.getenv("SHELL", "") +@pytest.fixture(autouse=True) +def _pin_test_shell_env(monkeypatch: pytest.MonkeyPatch) -> None: + """Pin ``$SHELL`` to ``/bin/sh`` for every test. + + tmux falls back to ``$SHELL`` for new panes when ``default-shell`` is + unset, so pinning the env var here forces every test pane to spawn + ``/bin/sh`` instead of the contributor's interactive shell. Eliminates + rcfile init cost (zsh / oh-my-zsh / bash profile chains) and yields + deterministic prompt output that doesn't flake capture-pane assertions. + ``monkeypatch`` restores the prior value at teardown. + """ + monkeypatch.setenv("SHELL", "/bin/sh") + + @pytest.fixture(autouse=USING_ZSH, scope="session") def zshrc(user_path: pathlib.Path) -> pathlib.Path | None: """Quiets ZSH default message. From a4b416b4fa148c1c7c78ded93fd0a8889bf4fedb Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 10 May 2026 13:22:06 -0500 Subject: [PATCH 2/2] docs(CHANGES) Pin \$SHELL=/bin/sh for tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit why: Document the contributor-side test-suite speedup landing on the unreleased tmuxp 1.68.0 block so anyone skimming next-version notes can confirm the change is dev-only — `tmuxp load`, `tmuxp freeze`, and workspace YAML behaviour are unchanged. what: - Add a Development entry under the unreleased 1.68.0 block, placed after the existing Documentation section per the mandatory section order. Heading style mirrors tmuxp 1.66.0's `#### Structured logging with extra context` entry — name the product surface that changed (test panes), describe what's different (spawn /bin/sh instead of \$SHELL), and cap with a one-line non-user-impact disclaimer. - Frame the speedup as "roughly halve... on systems with slow shell startup" rather than the precise 51% measured locally — the gain depends entirely on the contributor's shell init weight; quoting a single number would be brittle. --- CHANGES | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGES b/CHANGES index 8a54b45431..6fc7f773ab 100644 --- a/CHANGES +++ b/CHANGES @@ -56,6 +56,16 @@ _Notes on the upcoming release will go here._ via `gp-furo-theme`, a Tailwind v4 respin of Furo, with `sphinx-vite-builder` handling theme-asset builds (#1037) +### Development + +#### Test panes spawn `/bin/sh` instead of the developer's `$SHELL` (#1041) + +An autouse pytest fixture pins `$SHELL=/bin/sh` so test panes skip +the contributor's interactive shell init. On systems with slow shell +startup (zsh + oh-my-zsh, heavy bash profiles) this can roughly halve +`uv run py.test` wall time; smaller gain on stripped-down shells. No +effect on tmuxp's runtime behavior. + ## tmuxp 1.67.0 (2026-03-08)