ci(test): gate new session-mock assignments in api unit tests (#42854)

Co-authored-by: Harsh Kashyap <Harsh23Kashyap@users.noreply.github.com>
Co-authored-by: Harsh Kashyap <harsh@harshkashyap.dev>
This commit is contained in:
authored and GitHub committed 2026-09-29 02:11:45 +00:00
1 parent 1b9ddf9ae5
commit 1545517fe8
4 files changed
+66

No files matched your search

+3
View File
@@ -66,6 +66,7 @@ jobs:
- 'scripts/lint_controller_sqlalchemy.py'
- 'scripts/ast_grep_rules/no_new_getattr.yml'
- 'scripts/ast_grep_rules/no_new_controller_sqlalchemy.yml'
- 'scripts/ast_grep_rules/no_new_session_mock.yml'
- '.github/workflows/style.yml'
- '.github/workflows/main-ci.yml'
- '.github/workflows/api-tests.yml'
@@ -160,9 +161,11 @@ jobs:
- 'scripts/ast_grep_guard.py'
- 'scripts/check_no_new_getattr.py'
- 'scripts/check_no_new_controller_sqlalchemy.py'
- 'scripts/check_no_new_session_mock.py'
- 'scripts/lint_controller_sqlalchemy.py'
- 'scripts/ast_grep_rules/no_new_getattr.yml'
- 'scripts/ast_grep_rules/no_new_controller_sqlalchemy.yml'
- 'scripts/ast_grep_rules/no_new_session_mock.yml'
- '.github/workflows/style.yml'
- '.github/workflows/main-ci.yml'
dify-agent-style:
+4
View File
@@ -89,6 +89,10 @@ jobs:
if: inputs.run-python-style
run: uv run --project api python scripts/check_no_new_controller_sqlalchemy.py --base-rev "${{ inputs.base-rev }}"
- name: Run No New Session Mock Guard
if: inputs.run-python-style
run: uv run --project api python scripts/check_no_new_session_mock.py --base-rev "${{ inputs.base-rev }}"
- name: Run Type Checks
if: inputs.run-python-style
env:
@@ -0,0 +1,11 @@
id: no-new-session-mock
language: python
rule:
any:
- pattern: $SESSION = MagicMock($$$ARGS)
- pattern: $SESSION = Mock($$$ARGS)
constraints:
SESSION:
regex: ^(session|db_session|mock_session|read_session|write_session)$
message: net-new session mock assignment in test code
severity: error
+48
View File
@@ -0,0 +1,48 @@
#!/usr/bin/env python3
"""Block net-new session mock assignments in unit tests.
This catches net-new top-level session mocks like
`session = MagicMock()` or `db_session = Mock()` added to
`tests/unit_tests/**`. Pre-existing matches are ignored via the
shared baseline diff (`scripts/ast_grep_guard.py`), so historical
mocks that haven't been cleaned up yet do not block the gate.
A `# guard-ignore: no-new-session-mock -- <reason>` line on the same
source line suppresses a violation with a human-readable reason.
"""
from __future__ import annotations
from pathlib import Path
from ast_grep_guard import Match, has_reasoned_guard_ignore, is_python_source_path, rule_path, run_guard
RULE_ID = "no-new-session-mock"
RULE_PATH = rule_path("no_new_session_mock.yml")
TEST_ROOT = Path("api/tests/unit_tests")
VIOLATION_MESSAGE = "no-new-session-mock net-new session mock assignment in test code"
def is_test_source_path(path: str) -> bool:
if not is_python_source_path(path):
return False
return Path(path).is_relative_to(TEST_ROOT)
def is_reportable_match(match: Match) -> bool:
return not has_reasoned_guard_ignore(match.source_line, RULE_ID)
def main() -> int:
return run_guard(
description=__doc__,
rule=RULE_PATH,
is_scanned_path=is_test_source_path,
is_reportable_match=is_reportable_match,
violation_message=VIOLATION_MESSAGE,
)
if __name__ == "__main__":
raise SystemExit(main())