Merge pull request #411 from mcdonc/chore/coverage-gaps

chore: close coverage gaps in cli, filter, registry, and migrations
This commit is contained in:
Yiorgis Gozadinos 2026-06-01 18:12:22 +03:00 committed by GitHub
commit 20634376a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 153 additions and 4 deletions

View file

@ -36,7 +36,7 @@ async def apply_migrations(conn: aiosqlite.Connection) -> int:
)
else:
current = row[0]
if current < SCHEMA_VERSION:
if current < SCHEMA_VERSION: # pragma: no cover - no migrations yet
# No diff migrations exist yet — future versions add UPDATE/ALTER
# statements between here and the version bump.
await _exec(conn, "UPDATE schema_version SET version = ?", SCHEMA_VERSION)

View file

@ -1,8 +1,9 @@
"""haiku-ingester run-batch CLI: echoes the batch report and exits non-zero
when any job dead-letters. IngesterApp is patched so no real ingestion runs."""
"""haiku-ingester CLI: exercises every subcommand via CliRunner with
IngesterApp / open_queue patched out so no real ingestion runs."""
from unittest.mock import AsyncMock
from unittest.mock import AsyncMock, MagicMock
import pytest
from typer.testing import CliRunner
from haiku.rag.ingester.app import BatchReport
@ -11,6 +12,9 @@ from haiku.rag.ingester.cli import _cli as cli
runner = CliRunner()
# --- helpers ---
def _fake_app(report: BatchReport, monkeypatch) -> AsyncMock:
fake = AsyncMock()
fake.run_batch.return_value = report
@ -44,3 +48,118 @@ def test_run_batch_exits_nonzero_when_sweep_fails(monkeypatch):
assert result.exit_code == 1
assert "failed to sweep: docs" in result.output
# --- serve ---
def test_serve_invokes_app(monkeypatch):
fake = AsyncMock()
monkeypatch.setattr("haiku.rag.ingester.cli.IngesterApp", lambda **_: fake)
result = runner.invoke(cli, ["serve", "--db", "x.lancedb", "--no-api"])
assert result.exit_code == 0
fake.serve.assert_awaited_once_with(api=False)
def test_serve_passes_host_and_port(monkeypatch):
fake = AsyncMock()
captured = {}
def _capture(**kwargs):
captured.update(kwargs)
return fake
monkeypatch.setattr("haiku.rag.ingester.cli.IngesterApp", _capture)
result = runner.invoke(
cli, ["serve", "--db", "x.lancedb", "--host", "0.0.0.0", "--port", "9999"]
)
assert result.exit_code == 0
assert captured["config"].ingester.api.host == "0.0.0.0"
assert captured["config"].ingester.api.port == 9999
# --- queue init / migrate ---
def test_queue_init(tmp_path, monkeypatch):
fake_conn = AsyncMock()
monkeypatch.setattr(
"haiku.rag.ingester.cli.open_queue", AsyncMock(return_value=fake_conn)
)
db_path = tmp_path / "queue.db"
result = runner.invoke(cli, ["queue", "init", "--queue", str(db_path)])
assert result.exit_code == 0
assert "initialized" in result.output
def test_queue_migrate(tmp_path, monkeypatch):
fake_conn = AsyncMock()
monkeypatch.setattr(
"haiku.rag.ingester.cli.open_queue", AsyncMock(return_value=fake_conn)
)
db_path = tmp_path / "queue.db"
result = runner.invoke(cli, ["queue", "migrate", "--queue", str(db_path)])
assert result.exit_code == 0
assert "up to date" in result.output
# --- config loading ---
def test_load_config_with_explicit_path(tmp_path):
from haiku.rag.ingester.cli import _load_config_with_override
config_file = tmp_path / "test.yaml"
config_file.write_text("embeddings:\n model:\n provider: ollama\n")
config = _load_config_with_override(config_file)
assert config.embeddings.model.provider == "ollama"
def test_load_config_falls_back_to_default(monkeypatch):
from haiku.rag.ingester.cli import _load_config_with_override, get_config
monkeypatch.setattr("haiku.rag.ingester.cli.find_config_file", lambda _: None)
config = _load_config_with_override(None)
assert config == get_config()
# --- cli() entry point ---
def test_cli_entry_point(monkeypatch):
from haiku.rag.ingester.cli import cli as cli_entry
mock_cli = MagicMock()
monkeypatch.setattr("haiku.rag.ingester.cli._cli", mock_cli)
monkeypatch.setattr("haiku.rag.ingester.cli.configure_cli_logging", lambda: None)
monkeypatch.setattr("haiku.rag.telemetry.configure", lambda **_: None)
cli_entry()
mock_cli.assert_called_once()
def test_cli_entry_point_exits_on_migration_error(monkeypatch):
from haiku.rag.ingester.cli import cli as cli_entry
from haiku.rag.store.exceptions import MigrationRequiredError
monkeypatch.setattr(
"haiku.rag.ingester.cli._cli",
MagicMock(side_effect=MigrationRequiredError("need migration")),
)
monkeypatch.setattr("haiku.rag.ingester.cli.configure_cli_logging", lambda: None)
monkeypatch.setattr("haiku.rag.telemetry.configure", lambda **_: None)
with pytest.raises(SystemExit) as exc_info:
cli_entry()
assert exc_info.value.code == 1

View file

@ -0,0 +1,25 @@
from watchfiles import Change
from haiku.rag.ingester.sources.filter import FileFilter, _default_supported_extensions
def test_default_supported_extensions_returns_nonempty_list():
exts = _default_supported_extensions()
assert isinstance(exts, list)
assert len(exts) > 0
assert all(ext.startswith(".") for ext in exts)
def test_filter_uses_default_extensions_when_none():
f = FileFilter(supported_extensions=None)
assert len(f.extensions) > 0
def test_call_delegates_to_include_file_then_default_filter():
"""__call__ is the watchfiles callback entry point. It should reject
files that don't pass include_file and accept ones that do."""
f = FileFilter(supported_extensions=[".md"])
# DefaultFilter rejects dotfiles and common noise; a normal .md path passes.
assert f(Change.added, "/tmp/docs/readme.md") is True
# Wrong extension — include_file returns False before DefaultFilter runs.
assert f(Change.added, "/tmp/docs/readme.log") is False

View file

@ -44,6 +44,11 @@ def test_adhoc_resolves_s3_forwards_storage_options():
assert src.storage_options["endpoint"] == "http://seaweed:8333"
def test_adhoc_s3_without_bucket_raises():
with pytest.raises(ValueError, match="Invalid S3 URI"):
resolve_adhoc_fetcher("s3:///key-only")
def test_adhoc_unknown_scheme_raises():
with pytest.raises(ValueError, match="No source adapter"):
resolve_adhoc_fetcher("ftp://example.com/x")