Coverage for app/backend/src/tests/test_profiling.py: 100%
83 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-05-31 14:08 +0000
« prev ^ index » next coverage.py v7.14.1, created at 2026-05-31 14:08 +0000
1import pyroscope
2import pytest
4from couchers import profiling
5from couchers.config import config
7TAGS = {"role": "api", "instance": "api-1761"}
10@pytest.fixture
11def fake_agent(monkeypatch):
12 """Replace the native pyroscope agent with recorders and reset the per-process agent state."""
13 configure_calls: list[dict[str, object]] = []
14 shutdown_calls: list[None] = []
15 monkeypatch.setattr(pyroscope, "configure", lambda **kw: configure_calls.append(kw))
16 monkeypatch.setattr(pyroscope, "shutdown", lambda: shutdown_calls.append(None))
17 monkeypatch.setattr(profiling, "_tags", TAGS)
18 monkeypatch.setattr(profiling, "_running", False)
19 monkeypatch.setattr(profiling, "_sample_rate", None)
20 monkeypatch.setattr(profiling, "_oncpu", None)
21 monkeypatch.setitem(config, "PYROSCOPE_SERVER", "https://localhost")
22 monkeypatch.setitem(config, "PYROSCOPE_AUTH_TOKEN", "token")
23 return configure_calls, shutdown_calls
26def _enable(feature_flags, *, rate=20, mode="wall"):
27 feature_flags.set("profiling_enabled", True)
28 feature_flags.set("profiling_sample_rate", rate)
29 feature_flags.set("profiling_mode", mode)
32def test_disabled_does_nothing(feature_flags, fake_agent):
33 configure_calls, shutdown_calls = fake_agent
34 feature_flags.set("profiling_enabled", False)
35 profiling._reconcile()
36 assert configure_calls == []
37 assert shutdown_calls == []
38 assert profiling._running is False
41def test_enables_with_flag_driven_params(feature_flags, fake_agent, monkeypatch):
42 monkeypatch.setitem(config, "PYROSCOPE_SERVER", "https://pyroscope.couchershq.org")
43 monkeypatch.setitem(config, "PYROSCOPE_AUTH_TOKEN", "secret-token")
44 configure_calls, _ = fake_agent
45 _enable(feature_flags, rate=50, mode="cpu")
46 profiling._reconcile()
48 assert len(configure_calls) == 1
49 kw = configure_calls[0]
50 assert kw["sample_rate"] == 50
51 assert kw["oncpu"] is True
52 assert kw["server_address"] == "https://pyroscope.couchershq.org"
53 assert kw["http_headers"] == {"Authorization": "Bearer secret-token"}
54 assert kw["tags"] == TAGS
55 # enable_logging must never be True on a reconfigure (re-init aborts the process)
56 assert kw["enable_logging"] is False
57 assert (profiling._running, profiling._sample_rate, profiling._oncpu) == (True, 50, True)
60def test_idempotent_when_unchanged(feature_flags, fake_agent):
61 configure_calls, shutdown_calls = fake_agent
62 _enable(feature_flags)
63 profiling._reconcile()
64 profiling._reconcile()
65 assert len(configure_calls) == 1
66 assert shutdown_calls == []
69def test_rate_change_restarts_agent(feature_flags, fake_agent):
70 configure_calls, shutdown_calls = fake_agent
71 _enable(feature_flags, rate=20)
72 profiling._reconcile()
73 feature_flags.set("profiling_sample_rate", 73)
74 profiling._reconcile()
75 assert len(configure_calls) == 2
76 assert len(shutdown_calls) == 1
77 assert configure_calls[-1]["sample_rate"] == 73
78 assert profiling._sample_rate == 73
81def test_mode_change_restarts_agent(feature_flags, fake_agent):
82 configure_calls, shutdown_calls = fake_agent
83 _enable(feature_flags, mode="wall")
84 profiling._reconcile()
85 feature_flags.set("profiling_mode", "cpu")
86 profiling._reconcile()
87 assert len(shutdown_calls) == 1
88 assert configure_calls[-1]["oncpu"] is True
89 assert profiling._oncpu is True
92def test_disable_after_running_shuts_down(feature_flags, fake_agent):
93 _, shutdown_calls = fake_agent
94 _enable(feature_flags)
95 profiling._reconcile()
96 feature_flags.set("profiling_enabled", False)
97 profiling._reconcile()
98 assert len(shutdown_calls) == 1
99 assert profiling._running is False
102def test_sample_rate_is_clamped(feature_flags, fake_agent):
103 configure_calls, _ = fake_agent
104 _enable(feature_flags, rate=100000)
105 profiling._reconcile()
106 assert configure_calls[0]["sample_rate"] == 250