fix(tests): keep local backend test runs off the real library database - #1498
fix(tests): keep local backend test runs off the real library database#1498VanshajPoonia wants to merge 1 commit into
Conversation
settings.py gated the test database path on GITHUB_ACTIONS alone. CI sets that
for free, so `cd backend && pytest` locally resolved DATABASE_PATH to the user's
PictoPy.db and the session fixture created tables inside it. Several tests drop
and truncate, so a run on an indexed library could destroy real data.
settings.py now honours TEST_MODE too, and a new tests/db_isolation.py sets it
before any app import: settings.py resolves the path at import time, so the old
assignment inside the session fixture ran too late to redirect anything. The
same module refuses to start a run whose DATABASE_PATH lands inside
user_data_dir("PictoPy"), turning a silent redirect failure into a loud one.
Closes AOSSIE-Org#1483
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review. WalkthroughThe backend test setup now selects a disposable SQLite database when ChangesTest database isolation
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to The change redirects local test runs away from the real library database and adds guard coverage; no actionable merge-blocking risk remains after normal checks and review. Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Link your account with GitcordThanks for opening this PR, @VanshajPoonia! To receive Discord notifications and contributor tracking for this organization:
Once linked, Gitcord can notify you about reviews, merges, and more. — Posted by Gitcord |
Closes #1483
cd backend && pytest, the command inbackend/AGENTS.md, pointedDATABASE_PATHat the user's realPictoPy.dband created every application table inside it. Several testsDROP TABLEandDELETE FROM, so on an indexed library a local test run could destroy real data. CI was never affected.Why it happened
Two independent faults, and fixing either one alone leaves the bug live.
1.
settings.pygated the test path on the wrong variable.GitHub sets
GITHUB_ACTIONS=trueautomatically, so CI got isolation for free and nobody noticed. Locally nothing sets it.2.
conftest.pysetTEST_MODEtoo late to matter.It set it inside the
setup_before_all_testsfixture body. Butconftest.py's own module-levelfrom app.database.faces import ...imports run during collection, long before any fixture executes, andsettings.pycomputesDATABASE_PATHat import time. By the time the fixture ran, every module had already frozen the wrong value.The fix
settings.pynow honoursTEST_MODEalongsideGITHUB_ACTIONS, and a newbackend/tests/db_isolation.pysets it before any app import.conftest.pyimports that module as its first statement, so ordering is enforced by the import graph rather than by a comment asking people not to move a line.Same module refuses to start a run whose resolved
DATABASE_PATHlands insideuser_data_dir("PictoPy"). If the redirect ever silently breaks again, the session dies with a message instead of quietly writing to the library.The fixture's teardown no longer deletes
TEST_MODE. Unsetting it mid-process would let any later import ofsettings.pyresolve straight back to the real library.Evidence
Recorded the library database's mtime and size, ran the full suite, compared.
main1787161142 987136001787162533 987136001787162533 987136001787162533 98713600Tables land in
backend/test_db.sqlite3instead, whichbackend/.gitignorealready covers. I hit themainrow by accident while verifying an unrelated branch, which is a fair illustration of how easy this is to trip.Tests
backend/tests/test_db_isolation.py, four cases:TEST_MODEis setDATABASE_PATHresolves outsideuser_data_dir("PictoPy")app/database/connection.pysees the redirected value, since it bindsDATABASE_PATHat import time and a redirect landing after it would leave every query pointed at the libraryBackend suite goes from 1110 to 1114.
Credit
@tanmaysachann's analysis on the issue reached the same two-part root cause independently, and added a point worth recording: because each module does
from app.config.settings import DATABASE_PATH, a name copy rather than a live reference, patchingapp.config.settings.DATABASE_PATHalone is not enough. The existing "safe" tests each have to patch several targets by hand. Quantified across the suite, 17 test files carry that pattern, between 1 and 5 targets each:Fixing the value at the source does not remove that per-file patching, since those tests still want their own isolated tempfile per test. What it does remove is the consequence of forgetting: a file that misses a target now falls back to a throwaway database rather than the user's library.
@Ankushh0027 also offered to take this one. I was assigned the issue so I carried it through, but the analysis above is largely shared ground.
Docs
Three files stated the old behaviour.
agent-kit/skills/add-backend-endpoint/SKILL.mdread "so tests get a real database", which was true in a way nobody intended.Scope
THUMBNAIL_IMAGES_PATHandVIDEO_FRAMES_PATHstill resolve touser_data_dirunconditionally, and this PR does not change that.I looked at whether they are a second live exposure. They are not, but the reason is worth stating precisely rather than waving at. Tests do reach filesystem writes under those paths, including
video_util_purge_frame_cache, which callsshutil.rmtree(VIDEO_FRAMES_PATH). Every call site redirects the path to a tempdir first: both purge tests request theframes_dirfixture (tests/test_video_frames.py:71-78), and the thumbnail tests patchapp.utils.videos.THUMBNAIL_IMAGES_PATHper test. Confirmed empirically too, the real thumbnails directory's mtime predates any of this work.So the filesystem side is safe by per-test fixture discipline, not by construction. If someone later adds a test that calls
video_util_purge_frame_cachewithout requestingframes_dir, it recursively deletes the user's real frame cache and nothing stops it. That is the same shape of latent fault this PR fixes for the database, and I have deliberately left it out rather than widen the diff. Happy to file it separately if a maintainer wants it tracked.One note for anyone who ran pytest locally before this
The fix stops future runs from writing to the library database. It does not undo writes that already happened. If you ran
cd backend && pyteston an indexed library, that database may contain tables the fixture created, and rows that tests inserted or deleted. Worth checking before assuming a clean slate.Verification
Summary by CodeRabbit
Bug Fixes
Tests