`stack llm index` read index_docket_state before anything had created it: migrate() only ran inside index_refs, so the first sealed run on an un-migrated database died with UndefinedTable. Build one engine in the CLI, migrate it, and hand it down (index_refs takes an `engine` kwarg); --force still builds nothing. index_refs also marked a sealed docket complete when some of its refs loaded blank or produced no chunks — a seal claiming coverage the run never achieved. Count unindexable refs per docket and write index_docket_state only for dockets with none.
152 lines
4.7 KiB
Python
152 lines
4.7 KiB
Python
"""Exercise cli/llm.py's `index` seal-skip wiring: sealed/complete dockets
|
|
are excluded from the comment listing, and only pending seals are passed
|
|
through to be re-marked."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from typer.testing import CliRunner
|
|
|
|
from cli.llm import app
|
|
|
|
runner = CliRunner()
|
|
_STATS = {
|
|
"indexed": 0,
|
|
"skipped": 0,
|
|
"chunks": 0,
|
|
"fingerprint_skipped": 5,
|
|
"hash_skipped": 0,
|
|
"docket_complete": 0,
|
|
}
|
|
|
|
|
|
@patch("llm.index._engine")
|
|
@patch(
|
|
"llm.index.docket_complete",
|
|
return_value={"CMS-2019-0111": "s1", "CMS-2020-0088": "old"},
|
|
)
|
|
@patch("llm.source.iter_comment_refs")
|
|
@patch("llm.pool.HostPool.from_config")
|
|
@patch("llm.index.index_refs")
|
|
@patch("conf.connect.bib")
|
|
@patch("llm.config.load")
|
|
def test_complete_sealed_dockets_are_not_listed(
|
|
mock_load, mock_bib, mock_index, mock_pool, mock_iter, mock_complete, _engine
|
|
):
|
|
mock_load.return_value = MagicMock()
|
|
store = MagicMock()
|
|
store.sealed_dockets.return_value = {"CMS-2019-0111": "s1", "CMS-2020-0088": "s2"}
|
|
mock_bib.return_value = store
|
|
mock_iter.return_value = iter([])
|
|
mock_index.return_value = _STATS
|
|
|
|
result = runner.invoke(app, ["index"])
|
|
|
|
assert result.exit_code == 0, result.output
|
|
kwargs = mock_iter.call_args.kwargs
|
|
assert kwargs["skip_dockets"] == {"CMS-2019-0111"} # seal matches → skipped
|
|
ikw = mock_index.call_args.kwargs
|
|
assert ikw["sealed"] == {
|
|
"CMS-2020-0088": "s2"
|
|
} # re-sealed docket will be re-marked
|
|
assert ikw["mark_complete"] is True
|
|
assert "fp_skipped=5" in result.output
|
|
|
|
|
|
@patch("llm.index._engine")
|
|
@patch("llm.index.docket_complete", return_value={})
|
|
@patch("llm.source.iter_comment_refs")
|
|
@patch("llm.pool.HostPool.from_config")
|
|
@patch("llm.index.index_refs")
|
|
@patch("conf.connect.bib")
|
|
@patch("llm.config.load")
|
|
def test_force_and_limit_disable_skips_and_completion(
|
|
mock_load, mock_bib, mock_index, mock_pool, mock_iter, mock_complete, _engine
|
|
):
|
|
mock_load.return_value = MagicMock()
|
|
store = MagicMock()
|
|
store.sealed_dockets.return_value = {"CMS-2019-0111": "s1"}
|
|
mock_bib.return_value = store
|
|
mock_iter.return_value = iter([])
|
|
mock_index.return_value = _STATS
|
|
|
|
result = runner.invoke(app, ["index", "--force", "--limit", "5"])
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert mock_iter.call_args.kwargs["skip_dockets"] == set()
|
|
assert mock_index.call_args.kwargs["mark_complete"] is False
|
|
|
|
|
|
@patch("llm.index._engine")
|
|
@patch("llm.migrate.migrate")
|
|
@patch("llm.index.docket_complete", return_value={})
|
|
@patch("llm.source.iter_comment_refs")
|
|
@patch("llm.pool.HostPool.from_config")
|
|
@patch("llm.index.index_refs")
|
|
@patch("conf.connect.bib")
|
|
@patch("llm.config.load")
|
|
def test_migrate_runs_before_docket_complete_and_engine_is_reused(
|
|
mock_load,
|
|
mock_bib,
|
|
mock_index,
|
|
mock_pool,
|
|
mock_iter,
|
|
mock_complete,
|
|
mock_migrate,
|
|
mock_engine,
|
|
):
|
|
"""index_docket_state may not exist yet on the first sealed run."""
|
|
order: list[str] = []
|
|
mock_migrate.side_effect = lambda e: order.append("migrate")
|
|
mock_complete.side_effect = lambda e, c: (order.append("complete"), {})[1]
|
|
mock_load.return_value = MagicMock()
|
|
store = MagicMock()
|
|
store.sealed_dockets.return_value = {"CMS-2019-0111": "s1"}
|
|
mock_bib.return_value = store
|
|
mock_iter.return_value = iter([])
|
|
mock_index.return_value = _STATS
|
|
|
|
result = runner.invoke(app, ["index"])
|
|
|
|
assert result.exit_code == 0, result.output
|
|
assert order == ["migrate", "complete"]
|
|
mock_engine.assert_called_once() # one engine, shared
|
|
assert mock_migrate.call_args.args[0] is mock_engine.return_value
|
|
assert mock_complete.call_args.args[0] is mock_engine.return_value
|
|
assert mock_index.call_args.kwargs["engine"] is mock_engine.return_value
|
|
|
|
|
|
@patch("llm.index._engine")
|
|
@patch("llm.migrate.migrate")
|
|
@patch("llm.index.docket_complete", return_value={})
|
|
@patch("llm.source.iter_comment_refs")
|
|
@patch("llm.pool.HostPool.from_config")
|
|
@patch("llm.index.index_refs")
|
|
@patch("conf.connect.bib")
|
|
@patch("llm.config.load")
|
|
def test_force_touches_neither_engine_nor_migrate(
|
|
mock_load,
|
|
mock_bib,
|
|
mock_index,
|
|
mock_pool,
|
|
mock_iter,
|
|
mock_complete,
|
|
mock_migrate,
|
|
mock_engine,
|
|
):
|
|
mock_load.return_value = MagicMock()
|
|
store = MagicMock()
|
|
store.sealed_dockets.return_value = {"CMS-2019-0111": "s1"}
|
|
mock_bib.return_value = store
|
|
mock_iter.return_value = iter([])
|
|
mock_index.return_value = _STATS
|
|
|
|
result = runner.invoke(app, ["index", "--force"])
|
|
|
|
assert result.exit_code == 0, result.output
|
|
mock_engine.assert_not_called()
|
|
mock_migrate.assert_not_called()
|
|
mock_complete.assert_not_called()
|
|
assert mock_index.call_args.kwargs["engine"] is None
|