From d312bdf9689d30690571d39b3dd5cc9409567654 Mon Sep 17 00:00:00 2001 From: 1445043649 <> Date: Mon, 11 May 2026 09:12:28 +0800 Subject: [PATCH] test(config): pin default postgres backend + sqlite regression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新建 backend/tests/test_default_database_backend.py 两个测试: - test_explicit_sqlite_backend_still_works (T2.3) 显式 database.backend=sqlite 仍生效;防 PR2 改默认后 SQLite 用户 悄无声息 regression - test_config_example_default_backend_is_postgres (T2.4) 直接读 on-disk config.example.yaml,断言 database.backend == 'postgres' 且 postgres_url == '\$DATABASE_URL'(不允许硬编码凭据) Stage 0 PR2 T2.3 + T2.4. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../tests/test_default_database_backend.py | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 backend/tests/test_default_database_backend.py diff --git a/backend/tests/test_default_database_backend.py b/backend/tests/test_default_database_backend.py new file mode 100644 index 00000000..1421bca0 --- /dev/null +++ b/backend/tests/test_default_database_backend.py @@ -0,0 +1,90 @@ +"""Stage 0 PR2 · default backend regression + sqlite-still-works. + +Two facts pinned here: + T2.3 — explicit ``database.backend: sqlite`` still produces a working + config (backwards-compat for users who deliberately stay on SQLite). + T2.4 — ``config.example.yaml`` default ``database.backend`` is ``postgres`` + (Stage 0 PR2 flipped this from sqlite). +""" + +from __future__ import annotations + +import json +from pathlib import Path + +import pytest +import yaml + +from deerflow.config.app_config import AppConfig + +REPO_ROOT = Path(__file__).resolve().parents[2] + + +def _write_extensions_config(path: Path) -> None: + path.write_text(json.dumps({"mcpServers": {}, "skills": {}}), encoding="utf-8") + + +# --------------------------------------------------------------------------- +# T2.3 · sqlite backend regression +# --------------------------------------------------------------------------- + + +def test_explicit_sqlite_backend_still_works(tmp_path, monkeypatch) -> None: + """A config with explicit ``database.backend: sqlite`` must still parse. + + Pin: PR2 made postgres the example default. This test guarantees that + users who copy the SQLite fallback block to their config.yaml do not + silently regress. + """ + config_path = tmp_path / "config.yaml" + extensions_path = tmp_path / "extensions_config.json" + _write_extensions_config(extensions_path) + config_path.write_text( + yaml.safe_dump( + { + "models": [ + { + "name": "test", + "use": "langchain_openai:ChatOpenAI", + "model": "gpt-4", + } + ], + "database": { + "backend": "sqlite", + "sqlite_dir": "/custom/sqlite/path", + }, + "sandbox": {"use": "deerflow.sandbox.local:LocalSandboxProvider"}, + } + ), + encoding="utf-8", + ) + monkeypatch.setenv("DEER_FLOW_EXTENSIONS_CONFIG_PATH", str(extensions_path)) + + config = AppConfig.from_file(str(config_path)) + + assert config.database.backend == "sqlite" + assert config.database.sqlite_dir == "/custom/sqlite/path" + + +# --------------------------------------------------------------------------- +# T2.4 · default config.example.yaml uses postgres +# --------------------------------------------------------------------------- + + +def test_config_example_default_backend_is_postgres(monkeypatch) -> None: + """Pin Stage 0 PR2's commitment: the example config defaults to Postgres. + + Loaded directly from the on-disk ``config.example.yaml`` so any future + accidental flip back to sqlite would fail this test. + """ + example_path = REPO_ROOT / "config.example.yaml" + if not example_path.exists(): + pytest.skip(f"config.example.yaml not found at {example_path}") + + raw = yaml.safe_load(example_path.read_text(encoding="utf-8")) or {} + db = raw.get("database") or {} + + assert db.get("backend") == "postgres", f"config.example.yaml database.backend is {db.get('backend')!r}; PR2 requires 'postgres' as the default" + # The PG URL must come from the env (referenced as $DATABASE_URL), + # never hardcoded with credentials. + assert db.get("postgres_url") == "$DATABASE_URL", f"postgres_url should be '$DATABASE_URL' env reference, got {db.get('postgres_url')!r}"