helper used only by the POSIX fork harness below */
| 9329 | |
| 9330 | #ifndef _WIN32 /* helper used only by the POSIX fork harness below */ |
| 9331 | static int idx832_supervised_route_check(const char *repo_dir) { |
| 9332 | /* Become a supervisor host with the kill switch OFF — exactly the real MCP |
| 9333 | * server's state. Done in the FORKED CHILD only (see the harness) so the |
| 9334 | * parent test-runner's process-wide host mark stays clear and the #845 |
| 9335 | * unmarked-embedder guard is unaffected. Bound the recovery loop + worker |
| 9336 | * quiet-timeout so a stuck child cannot run long under the fork+alarm net. */ |
| 9337 | cbm_index_supervisor_mark_host(); |
| 9338 | cbm_unsetenv("CBM_INDEX_SUPERVISOR"); |
| 9339 | cbm_setenv("CBM_INDEX_MAX_RESTARTS", "1", 1); |
| 9340 | cbm_setenv("CBM_INDEX_WORKER_TIMEOUT_S", "30", 1); |
| 9341 | |
| 9342 | int spawns_before = cbm_index_supervisor_spawn_count(); |
| 9343 | char *resp = cbm_mcp_index_run_supervised_path(repo_dir); |
| 9344 | int spawns_after = cbm_index_supervisor_spawn_count(); |
| 9345 | |
| 9346 | if (spawns_after == spawns_before) { |
| 9347 | free(resp); |
| 9348 | return IDX832_NO_SPAWN; /* the discriminating assertion: RED in-process */ |
| 9349 | } |
| 9350 | if (!resp) { |
| 9351 | return IDX832_NULL_RESP; |
| 9352 | } |
| 9353 | bool indexed = response_contains_json_fragment(resp, "\"status\":\"indexed\""); |
| 9354 | free(resp); |
| 9355 | if (!indexed) { |
| 9356 | return IDX832_NOT_INDEXED; |
| 9357 | } |
| 9358 | |
| 9359 | /* Store-level proof the worker child did real work: the Function node it wrote |
| 9360 | * must be queryable from a fresh server reading the DB the child produced. */ |
| 9361 | char *project = cbm_project_name_from_path(repo_dir); |
| 9362 | cbm_mcp_server_t *srv = cbm_mcp_server_new(NULL); |
| 9363 | if (!srv) { |
| 9364 | free(project); |
| 9365 | return IDX832_SERVER_FAIL; |
| 9366 | } |
| 9367 | int code = IDX832_OK; |
| 9368 | if (project) { |
| 9369 | char q[512]; |
| 9370 | snprintf(q, sizeof(q), |
| 9371 | "{\"project\":\"%s\",\"name_pattern\":\"idx832_fn\",\"label\":\"Function\"}", |
| 9372 | project); |
| 9373 | char *sr = cbm_mcp_handle_tool(srv, "search_graph", q); |
| 9374 | if (!sr || !strstr(sr, "idx832_fn")) { |
| 9375 | code = IDX832_NOT_INDEXED; |
| 9376 | } |
| 9377 | free(sr); |
| 9378 | } |
| 9379 | cbm_mcp_server_free(srv); |
| 9380 | free(project); |
| 9381 | return code; |
| 9382 | } |
| 9383 | #endif /* !_WIN32 */ |
| 9384 | |
| 9385 | TEST(index_bg_paths_route_through_supervisor_issue832) { |
no test coverage detected