@@ -332,6 +332,56 @@ def test_publish_index_second_build_replaces_cleanly(self, tmp_path, monkeypatch
332332 assert not wal_sidecars , f"WAL sidecar leaked after 2nd build: { entries } "
333333 assert not shm_sidecars , f"SHM sidecar leaked after 2nd build: { entries } "
334334
335+ def test_publish_index_leaves_no_wal_sidecars_on_smoke_failure (
336+ self , tmp_path , monkeypatch
337+ ):
338+ """Round 3: smoke-test failure path must also finalize WAL.
339+
340+ Forces run_smoke_tests to return (False, [...]) and asserts publish_index
341+ returns False AND leaves no -wal/-shm sidecars in the cache dir.
342+ """
343+ from mcp_server_python_docs .ingestion import publish as publish_mod
344+
345+ target_index = tmp_path / "index.db"
346+ monkeypatch .setattr (
347+ "mcp_server_python_docs.storage.db.get_cache_dir" ,
348+ lambda : tmp_path ,
349+ )
350+ monkeypatch .setattr (
351+ "mcp_server_python_docs.storage.db.get_index_path" ,
352+ lambda : target_index ,
353+ )
354+ monkeypatch .setattr (publish_mod , "get_index_path" , lambda : target_index )
355+
356+ # Force smoke test failure regardless of DB contents.
357+ monkeypatch .setattr (
358+ publish_mod ,
359+ "run_smoke_tests" ,
360+ lambda * args , ** kwargs : (False , ["FAIL: forced for test" ]),
361+ )
362+
363+ build_db = tmp_path / "build-smoke-fail.db"
364+ self ._seed_passing_build (build_db )
365+
366+ assert publish_mod .publish_index (build_db , "3.13" ) is False
367+
368+ # No WAL/SHM sidecars anywhere in tmp_path.
369+ wal_sidecars = [
370+ p .name for p in tmp_path .iterdir () if p .name .endswith ("-wal" )
371+ ]
372+ shm_sidecars = [
373+ p .name for p in tmp_path .iterdir () if p .name .endswith ("-shm" )
374+ ]
375+ assert not wal_sidecars , (
376+ f"WAL sidecar leaked on failure path: { wal_sidecars } "
377+ )
378+ assert not shm_sidecars , (
379+ f"SHM sidecar leaked on failure path: { shm_sidecars } "
380+ )
381+
382+ # index.db must not have been created (atomic_swap was not reached).
383+ assert not target_index .exists ()
384+
335385
336386class TestReadOnlyConnection :
337387 def test_can_query_existing_db (self , tmp_path ):
0 commit comments