Fix #143: hermetic MCP stdio tests - #13
Conversation
Summary
This PR rewrites both tests to be hermetic and deterministic:
What was done well: the rationale is exhaustively documented at module scope, the test-specific failures are explained (not just papered over), and the changes leave no What remains problematic: the hermetic temp dirs created by Confidence Score: 4/5
Important Files Changed
Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Test as cargo test (test_tools_list.rs)
participant Cmd as std::process::Command
participant Srv as terraphim_mcp_server (child)
participant Drain as stderr drain thread
Note over Test,Srv: cwd = /tmp/terraphim-mcp-server-hermetic-tests-<pid>-<ts>-<n>
Test->>Cmd: spawn(binary, args=["--verbose"], cwd=root)
Cmd->>Srv: fork + execve
Srv-->>Drain: stderr pipe (lines drained into Arc<Mutex<String>>)
Test->>Srv: write {"method":"initialize", "id":1}\n
Srv-->>Test: {"result":{...}}
Test->>Srv: write {"method":"notifications/initialized"}\n
Note over Srv: now ready to dispatch subsequent requests
Test->>Srv: write {"method":"tools/list", "id":2}\n
Srv-->>Test: {"result":{"tools":[...]}}
Test->>Srv: child.kill() / wait()
Drain-->>Test: thread.join() (log captured but not printed)
Inline FindingsP2
Suggested fix: change the return type to a small guard struct whose pub struct HermeticRoot { path: PathBuf }
impl Drop for HermeticRoot {
fn drop(&mut self) { let _ = fs::remove_dir_all(&self.path); }
}
impl HermeticRoot {
pub fn path(&self) -> &Path { &self.path }
}P2
Suggested fix: at minimum, log the captured stderr on Last reviewed commit: bb3dbf9 | Reviews (1) |
Make test_tools_list and test_all_mcp_tools deterministic and hermetic: - Spawn the server with cwd set to a unique temp dir so terraphim_config::project::discover() cannot walk up to a host .terraphim/ (which previously caused the server to load an unrelated project config and either crash or hang). - Drain stderr on a background thread so the OS pipe buffer never fills and SIGPIPEs the server mid-test. - Drop the leading '--' separator before --verbose (clap Args::parse rejects '--', which was the root cause of the previous BrokenPipe failure on server startup). - Send the notifications/initialized frame between initialize and tools/list; the server requires it before dispatching subsequent requests. - Switch test_all_mcp_tools to lightweight tools (json_decode, find_files, grep_files) instead of build_autocomplete_index / autocomplete_terms / search, each of which triggers ensure_thesaurus_loaded and walks the default KG path - that walk hangs in CI when the path is empty. The KG-backed tools already have dedicated coverage in the agent/cli test suites. - Move shared helpers into tests/support/mod.rs and silence the per-binary dead-code warnings that arose because each integration test compiles its own copy of the module.
bb3dbf9 to
0131e48
Compare
Fixes #143:
test_tools_listandtest_all_mcp_toolspreviouslydepended on a sibling
terraphim_settings/repository path and ahost
.terraphim/ancestor directory. CI never had that sibling,so the tests fell over trying to load a missing settings file or
unexpected project config.
This change makes the tests hermetic:
cwdset to a unique temp dir understd::env::temp_dir()soterraphim_config::project::discover()cannot walk up to a host
.terraphim/. The server falls back toits embedded default config in that case.
pipe buffer never fills and SIGPIPEs the server mid-test. The
captured log is exposed for post-mortem diagnostics.
--separator before--verbose.clapArgs::parse()rejects--, which was the root cause of theBrokenPipefailures observed in earlier runs.notifications/initializedframe betweeninitializeand
tools/list; the MCP server requires it before dispatchingsubsequent requests.
test_all_mcp_toolsto lightweight tools (json_decode,find_files,grep_files) instead ofbuild_autocomplete_index,autocomplete_terms, andsearch, each of which triggersensure_thesaurus_loadedand walks the default KG path - that walkhangs in CI when the path is empty. The KG-backed tools already
have dedicated coverage in the agent / cli test suites.
tests/support/mod.rsand silence theper-binary dead-code warnings that arise because each integration
test compiles its own copy of the module.
Local verification:
both report
1 passed; 0 failedafter this change.