Files
wehub-resource-sync 7a0da7932b
Backwards Compatibility / Verify Encryption Constants (push) Waiting to run
Backwards Compatibility / PyPI Version Compatibility (push) Waiting to run
Backwards Compatibility / Database Migration Tests (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CodeQL Advanced / Analyze (python) (push) Waiting to run
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Blocked by required conditions
Docker Tests (Consolidated) / detect-changes (push) Waiting to run
Docker Tests (Consolidated) / Build Test Image (push) Waiting to run
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Blocked by required conditions
Docker Tests (Consolidated) / Accessibility Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Unit Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Example Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / Production Image Smoke Test (push) Blocked by required conditions
Docker Tests (Consolidated) / Infrastructure Tests (push) Blocked by required conditions
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Waiting to run
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

229 lines
7.8 KiB
Python

#!/usr/bin/env python3
# allow: no-sut-import — guardian; scans the codebase for raw SQL outside allowed locations
"""Test to verify no raw SQL is used in the codebase (except in allowed locations)."""
import sys
from pathlib import Path
sys.path.insert(
0,
str(Path(__file__).parent.parent.parent.resolve()),
)
import re
def check_file_for_raw_sql(filepath):
"""Check a single file for raw SQL usage."""
with open(filepath, "r", encoding="utf-8") as f:
content = f.read()
# Skip if it's a test file, migration file, or database-specific files
filepath_str = str(filepath).lower()
if any(
skip in filepath_str
for skip in [
"test",
"migration",
"encrypted_db.py",
"sqlcipher_utils.py",
"thread_local_session.py",
"queue/processor.py",
"database/initialize.py", # Schema migrations using DDL
"alembic_runner.py", # Migration runner: drops orphan _alembic_tmp_* tables (#3817), toggles foreign_keys (#3990)
"auth_db.py", # SQLAlchemy DDL (CreateTable/CreateIndex), not raw SQL
"backup_service.py", # SQLCipher ATTACH/DETACH/export operations
"journal_quality/db.py", # Read-only SQLite DB build + PRAGMA user_version
]
):
return []
violations = []
lines = content.split("\n")
# Patterns that indicate raw SQL
sql_patterns = [
r"cursor\.execute\s*\(",
r"conn\.execute\s*\(",
r'session\.execute\s*\(\s*["\']',
r'["\']SELECT\s+.*FROM\s+',
r'["\']INSERT\s+INTO\s+',
r'["\']UPDATE\s+.*SET\s+',
r'["\']DELETE\s+FROM\s+',
r'["\']CREATE\s+TABLE\s+',
r'["\']DROP\s+TABLE\s+',
r'["\']ALTER\s+TABLE\s+',
]
# Allowed patterns (SQLCipher PRAGMAs and simple connection tests)
allowed_patterns = [
r"PRAGMA\s+(cipher_|quick_check|rekey)", # SQLCipher pragmas
r"SELECT\s+1(?:\s|$|;)", # Simple connection test
r'text\s*\(\s*["\'](?:SELECT\s+1|PRAGMA)', # SQLAlchemy text() with allowed queries
]
for line_num, line in enumerate(lines, 1):
for pattern in sql_patterns:
if re.search(pattern, line, re.IGNORECASE):
# Check if it's in a comment or docstring
stripped = line.strip()
if (
stripped.startswith("#")
or stripped.startswith('"""')
or stripped.startswith("'''")
):
continue
# Check if it's an allowed pattern
is_allowed = False
for allowed in allowed_patterns:
if re.search(allowed, line, re.IGNORECASE):
is_allowed = True
break
if not is_allowed:
violations.append((line_num, line.strip()))
return violations
def test_no_raw_sql_in_src():
"""Test that no raw SQL is used in src directory (except allowed patterns).
Allowed exceptions:
- encrypted_db.py file (SQLCipher-specific operations)
- PRAGMA commands for SQLCipher (cipher_*, quick_check, rekey)
- Simple connection tests (SELECT 1)
"""
src_path = Path(__file__).parent.parent.parent / "src"
violations = {}
# Walk through all Python files
for filepath in src_path.rglob("*.py"):
file_violations = check_file_for_raw_sql(filepath)
if file_violations:
violations[str(filepath)] = file_violations
# Report violations
if violations:
print("\n❌ Found raw SQL in the following files:")
for filepath, file_violations in violations.items():
print(f"\n{filepath}:")
for line_num, line in file_violations:
print(f" Line {line_num}: {line[:80]}...")
# This should fail the test
assert False, f"Found raw SQL in {len(violations)} files"
else:
print(
"✓ No raw SQL found in src directory (excluding allowed patterns)"
)
def test_orm_imports_used():
"""Files that touch the DB should reach for the ORM, not raw SQL.
Walk the src tree, collect every file that performs a DB operation
(``get_db_session``, references to ``ResearchHistory`` or
``ResearchResource``), and require that the vast majority of them
also import SQLAlchemy or use ORM-style query helpers.
The ratio guard is intentionally loose (≥80%) because a handful of
helper modules legitimately reference these names without
constructing queries themselves (e.g. type-only imports, fixtures,
docstring examples).
"""
src_path = Path(__file__).parent.parent.parent / "src"
files_with_db_operations = []
files_with_orm_imports = []
for filepath in src_path.rglob("*.py"):
with open(filepath, "r", encoding="utf-8") as f:
content = f.read()
# Check if file has database operations
if any(
pattern in content
for pattern in [
"get_db_session",
"ResearchHistory",
"ResearchResource",
]
):
files_with_db_operations.append(filepath)
# Check if it has ORM imports
if any(
pattern in content
for pattern in [
"from sqlalchemy",
"import.*session",
".query(",
".filter",
]
):
files_with_orm_imports.append(filepath)
# Sanity: at least some files matched the DB-operation heuristic, or
# the test has silently stopped finding anything (e.g., a refactor
# renamed the symbols above and the test would otherwise pass with 0
# files inspected).
assert files_with_db_operations, (
"No files with DB operations detected — patterns may be stale"
)
orm_ratio = len(files_with_orm_imports) / len(files_with_db_operations)
assert orm_ratio >= 0.8, (
f"Only {len(files_with_orm_imports)}/{len(files_with_db_operations)} "
f"files with DB operations use ORM imports (ratio {orm_ratio:.2f} < 0.80)"
)
def test_models_imported_from_correct_location():
"""Test that models are imported from the consolidated location."""
src_path = Path(__file__).parent.parent.parent / "src"
incorrect_imports = {}
# Old import patterns that should not be used
old_patterns = [
r"from.*web\.models\.database import.*(?:Research|ResearchHistory)",
r"from.*web\.database\.models import",
r"from.*benchmarks\.models\.benchmark_models import",
]
for filepath in src_path.rglob("*.py"):
with open(filepath, "r", encoding="utf-8") as f:
content = f.read()
violations = []
lines = content.split("\n")
for line_num, line in enumerate(lines, 1):
for pattern in old_patterns:
if re.search(pattern, line):
violations.append((line_num, line.strip()))
if violations:
incorrect_imports[str(filepath)] = violations
if incorrect_imports:
print("\n❌ Found imports from old model locations:")
for filepath, violations in incorrect_imports.items():
print(f"\n{filepath}:")
for line_num, line in violations:
print(f" Line {line_num}: {line}")
# This should fail the test
assert False, (
f"Found {len(incorrect_imports)} files with incorrect model imports"
)
else:
print("✓ All models imported from correct location (database.models)")
if __name__ == "__main__":
test_no_raw_sql_in_src()
test_orm_imports_used()
test_models_imported_from_correct_location()
print("\n✅ All SQL/ORM compliance tests passed!")