helper used only by the POSIX fork harness below */
| 9107 | |
| 9108 | #ifndef _WIN32 /* helper used only by the POSIX fork harness below */ |
| 9109 | static int idx832_supervised_route_check(const char *repo_dir) { |
| 9110 | /* Become a supervisor host with the kill switch OFF — exactly the real MCP |
| 9111 | * server's state. Done in the FORKED CHILD only (see the harness) so the |
| 9112 | * parent test-runner's process-wide host mark stays clear and the #845 |
| 9113 | * unmarked-embedder guard is unaffected. Bound the recovery loop + worker |
| 9114 | * quiet-timeout so a stuck child cannot run long under the fork+alarm net. */ |
| 9115 | cbm_index_supervisor_mark_host(); |
| 9116 | cbm_unsetenv("CBM_INDEX_SUPERVISOR"); |
| 9117 | cbm_setenv("CBM_INDEX_MAX_RESTARTS", "1", 1); |
| 9118 | cbm_setenv("CBM_INDEX_WORKER_TIMEOUT_S", "30", 1); |
| 9119 | |
| 9120 | int spawns_before = cbm_index_supervisor_spawn_count(); |
| 9121 | char *resp = cbm_mcp_index_run_supervised_path(repo_dir); |
| 9122 | int spawns_after = cbm_index_supervisor_spawn_count(); |
| 9123 | |
| 9124 | if (spawns_after == spawns_before) { |
| 9125 | free(resp); |
| 9126 | return IDX832_NO_SPAWN; /* the discriminating assertion: RED in-process */ |
| 9127 | } |
| 9128 | if (!resp) { |
| 9129 | return IDX832_NULL_RESP; |
| 9130 | } |
| 9131 | bool indexed = response_contains_json_fragment(resp, "\"status\":\"indexed\""); |
| 9132 | free(resp); |
| 9133 | if (!indexed) { |
| 9134 | return IDX832_NOT_INDEXED; |
| 9135 | } |
| 9136 | |
| 9137 | /* Store-level proof the worker child did real work: the Function node it wrote |
| 9138 | * must be queryable from a fresh server reading the DB the child produced. */ |
| 9139 | char *project = cbm_project_name_from_path(repo_dir); |
| 9140 | cbm_mcp_server_t *srv = cbm_mcp_server_new(NULL); |
| 9141 | if (!srv) { |
| 9142 | free(project); |
| 9143 | return IDX832_SERVER_FAIL; |
| 9144 | } |
| 9145 | int code = IDX832_OK; |
| 9146 | if (project) { |
| 9147 | char q[512]; |
| 9148 | snprintf(q, sizeof(q), |
| 9149 | "{\"project\":\"%s\",\"name_pattern\":\"idx832_fn\",\"label\":\"Function\"}", |
| 9150 | project); |
| 9151 | char *sr = cbm_mcp_handle_tool(srv, "search_graph", q); |
| 9152 | if (!sr || !strstr(sr, "idx832_fn")) { |
| 9153 | code = IDX832_NOT_INDEXED; |
| 9154 | } |
| 9155 | free(sr); |
| 9156 | } |
| 9157 | cbm_mcp_server_free(srv); |
| 9158 | free(project); |
| 9159 | return code; |
| 9160 | } |
| 9161 | #endif /* !_WIN32 */ |
| 9162 | |
| 9163 | TEST(index_bg_paths_route_through_supervisor_issue832) { |
no test coverage detected