helper used only by the POSIX fork harness below */
| 9898 | |
| 9899 | #ifndef _WIN32 /* helper used only by the POSIX fork harness below */ |
| 9900 | static int idx832_supervised_route_check(const char *repo_dir) { |
| 9901 | /* Become a supervisor host with the kill switch OFF — exactly the real MCP |
| 9902 | * server's state. Done in the FORKED CHILD only (see the harness) so the |
| 9903 | * parent test-runner's process-wide host mark stays clear and the #845 |
| 9904 | * unmarked-embedder guard is unaffected. Bound the recovery loop + worker |
| 9905 | * quiet-timeout so a stuck child cannot run long under the fork+alarm net. */ |
| 9906 | cbm_index_supervisor_mark_host(); |
| 9907 | cbm_unsetenv("CBM_INDEX_SUPERVISOR"); |
| 9908 | cbm_setenv("CBM_INDEX_MAX_RESTARTS", "1", 1); |
| 9909 | cbm_setenv("CBM_INDEX_WORKER_TIMEOUT_S", "30", 1); |
| 9910 | |
| 9911 | int spawns_before = cbm_index_supervisor_spawn_count(); |
| 9912 | char *resp = cbm_mcp_index_run_supervised_path(repo_dir); |
| 9913 | int spawns_after = cbm_index_supervisor_spawn_count(); |
| 9914 | |
| 9915 | if (spawns_after == spawns_before) { |
| 9916 | free(resp); |
| 9917 | return IDX832_NO_SPAWN; /* the discriminating assertion: RED in-process */ |
| 9918 | } |
| 9919 | if (!resp) { |
| 9920 | return IDX832_NULL_RESP; |
| 9921 | } |
| 9922 | bool indexed = response_contains_json_fragment(resp, "\"status\":\"indexed\""); |
| 9923 | free(resp); |
| 9924 | if (!indexed) { |
| 9925 | return IDX832_NOT_INDEXED; |
| 9926 | } |
| 9927 | |
| 9928 | /* Store-level proof the worker child did real work: the Function node it wrote |
| 9929 | * must be queryable from a fresh server reading the DB the child produced. */ |
| 9930 | char *project = cbm_project_name_from_path(repo_dir); |
| 9931 | cbm_mcp_server_t *srv = cbm_mcp_server_new(NULL); |
| 9932 | if (!srv) { |
| 9933 | free(project); |
| 9934 | return IDX832_SERVER_FAIL; |
| 9935 | } |
| 9936 | int code = IDX832_OK; |
| 9937 | if (project) { |
| 9938 | char q[512]; |
| 9939 | snprintf(q, sizeof(q), |
| 9940 | "{\"project\":\"%s\",\"name_pattern\":\"idx832_fn\",\"label\":\"Function\"}", |
| 9941 | project); |
| 9942 | char *sr = cbm_mcp_handle_tool(srv, "search_graph", q); |
| 9943 | if (!sr || !strstr(sr, "idx832_fn")) { |
| 9944 | code = IDX832_NOT_INDEXED; |
| 9945 | } |
| 9946 | free(sr); |
| 9947 | } |
| 9948 | cbm_mcp_server_free(srv); |
| 9949 | free(project); |
| 9950 | return code; |
| 9951 | } |
| 9952 | #endif /* !_WIN32 */ |
| 9953 | |
| 9954 | TEST(index_bg_paths_route_through_supervisor_issue832) { |
no test coverage detected