Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed
- **Flake in `tests/test_store.py::test_do_cleanup_logs_errors`.** Test was using the `caplog.at_level(...)` context manager plus `caplog.text` substring check. That pattern failed intermittently on CI (observed on Python 3.11 and 3.14) even though the code under test (`_do_cleanup`) is fully synchronous — the flake was in pytest's log-capture path, not in the production code. Rewritten to use `caplog.set_level(...)` at fixture scope and inspect `caplog.records` directly (logger name + level + message substring), which is sturdier across pytest/Python versions and produces a richer failure message when it does fire. Verified 10/10 consecutive local runs post-fix. Closes [#374](https://github.com/cmeans/mcp-awareness/issues/374).

### Security
- **Third-party GitHub Actions pinned to full commit SHAs** (instead of floating `@vN` major-version tags). A moving major-version tag on a third-party action is an unreviewed supply-chain channel — the upstream owner can move the tag to any commit at any time, including after a repo compromise. Pinning to the commit SHA freezes the code under review. Affected references in `.github/workflows/`:
- `codecov/codecov-action@v6` → `@57e3a136…` (v6.0.0) in `ci.yml`
Expand Down
35 changes: 28 additions & 7 deletions tests/test_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -676,17 +676,38 @@ def test_get_deleted_pagination(store):


def test_do_cleanup_logs_errors(store, caplog):
"""_do_cleanup logs error instead of silently swallowing."""
"""_do_cleanup logs error instead of silently swallowing.

Uses ``caplog.set_level`` (fixture-scoped) and inspects ``caplog.records``
directly rather than the ``at_level`` context manager + ``caplog.text``
string concat — the latter pattern intermittently failed on CI across
every Python version (observed repeatedly on 3.11 and 3.14) despite
``_do_cleanup`` being fully synchronous. The flake was in the capture
path, not the code under test. Records-based assertion is sturdier
because it doesn't depend on the logging formatter or caplog's
text-buffer flushing semantics. See issue #374.
"""
import logging
from unittest.mock import patch

# Mock pool.connection to raise an error
with (
caplog.at_level(logging.ERROR, logger="mcp_awareness.postgres_store"),
patch.object(store._pool, "connection", side_effect=Exception("test error")),
):
caplog.set_level(logging.ERROR, logger="mcp_awareness.postgres_store")

with patch.object(store._pool, "connection", side_effect=Exception("test error")):
store._do_cleanup()
assert "Cleanup failed: Exception: test error" in caplog.text

matching = [
r
for r in caplog.records
if r.name == "mcp_awareness.postgres_store"
and r.levelno == logging.ERROR
and "Cleanup failed" in r.getMessage()
and "test error" in r.getMessage()
]
assert matching, (
"expected an ERROR log record on mcp_awareness.postgres_store containing "
"'Cleanup failed' and 'test error'. Captured records: "
f"{[(r.name, r.levelname, r.getMessage()) for r in caplog.records]}"
)


# ------------------------------------------------------------------
Expand Down
Loading