Skip to content

test isolation: DataStore writes leak into user's production gflow.db during pytest #86

Closed

Description

@ffroliva

Summary

During a persistence-layer e2e probe on develop (2026-05-26, post-v0.9.0), the user's production catalog at `<GFLOW_CLI_HOME>/gflow.db` was found to contain only pytest fixture data — every row pointed to a `pytest-of-ffrol\pytest-N\test_*` tmp directory. No real user-generated provenance was present.

Evidence

```sql
-- assets
{'id': '4f4f37b0-...', 'profile_name': 'default', 'flow_media_id': 'asset-uuid-123', 'kind': 'image'}
{'id': '127c9737-...', 'profile_name': 'default', 'flow_media_id': 'test-uuid', 'kind': 'video'}

-- local_files (7 rows; sample)
{'asset_id': '4f4f37b0-...', 'path': 'C:\Users\ffrol\AppData\Local\Temp\pytest-of-ffrol\pytest-865\test_image_upload_prints_uuid0\hero.png'}
{'asset_id': '127c9737-...', 'path': 'C:\development\github\gflow-cli\pytest-of-ffrol\pytest-46\test_t2v_does_not_instantiate_0\test-uuid.mp4'}
```

`gflow data list images` and `gflow data list videos` happily return these as if they were real assets.

Root cause hypothesis

Tests instantiate `DataStore` / `OperationRecorder` without overriding the resolved DB path. `Settings.resolved_db_path()` falls back to `<GFLOW_CLI_HOME>/gflow.db`, which is the user's real catalog on a developer machine.

Impact

  • Pollutes user's real provenance data.
  • Makes `gflow data list` output meaningless for actual users on dev machines.
  • Mixes test fixtures with real runs once real runs land (no way to distinguish).
  • Increases the blast radius of any schema migration — test runs migrate the production DB.

Proposed fix

  1. Autouse `tmp_path`-scoped fixture in `tests/conftest.py` that sets `GFLOW_CLI_DB_PATH` to a per-test tmp file before any `get_settings()` call. Same shape as the existing `GFLOW_CLI_HOME` isolation patterns.
  2. Tripwire test that fails the suite if `DataStore.open()` is called with a path under the user's real `platformdirs.user_data_dir`. Mirror the `_forbid_live_playwright` autouse tripwire (`tests/conftest.py`).
  3. One-off cleanup script (`scripts/dev/clean_dev_db.py` or document in CONTRIBUTING) for developers whose DBs are already polluted — delete rows whose `local_files.path` matches the test patterns.

Files

  • `tests/conftest.py` — add fixture + tripwire
  • `src/gflow_cli/data/store.py` — possibly add a debug-mode env var that refuses to open the production path under pytest
  • `CONTRIBUTING.md` — note the developer-machine cleanup

Acceptance

  • Running the full test suite on a clean developer machine produces ZERO writes to `<GFLOW_CLI_HOME>/gflow.db`.
  • Existing dev-machine pollution is documented (cleanup recipe) but not automatically wiped (data safety).

Discovered while triaging persistence-layer state for the gflow:plan housekeeping (2026-05-26).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions