#ifndef _DEFAULT_SOURCE #define _DEFAULT_SOURCE #endif #include "cst_agent.h" #include #include #include #include #include #include "cst_test_util.h" #ifdef _WIN32 #include #include #endif #define CHECK(c) \ do { \ if (!(c)) { \ fprintf(stderr, "%s:%d: CHECK(%s) failed\n", __FILE__, __LINE__, #c); \ exit(1); \ } \ } while (0) static char g_dir[256]; static void write_file(const char *name, const char *text) { char path[512]; snprintf(path, sizeof(path), "%s/cst-agent/%s", g_dir, name); FILE *fp = fopen(path, "wb"); CHECK(fp); fputs(text, fp); fclose(fp); } static void test_creds(void) { char key[512]; const char *from = NULL; CHECK(cst_creds_resolve("deepseek", key, sizeof(key), &from) != 0); /* legacy single-key file follows its api_base */ write_file("credentials", "api_key=sk-legacy\n" "api_base=https://api.minimax.cn/v1/\n"); CHECK(cst_creds_load("minimax", key, sizeof(key)) == 0); CHECK(strcmp(key, "sk-legacy") == 0); CHECK(cst_creds_load("deepseek", key, sizeof(key)) != 0); write_file("credentials", "api_key=sk-old\n"); CHECK(cst_creds_load("minimax", key, sizeof(key)) == 0); CHECK(cst_creds_load("openai", key, sizeof(key)) != 0); CHECK(cst_creds_save("deepseek", "sk-ds-1") == 0); CHECK(cst_creds_save("openai", "sk-oa") == 0); CHECK(cst_creds_save("deepseek", "sk-ds-2") == 0); CHECK(cst_creds_load("deepseek", key, sizeof(key)) == 0); CHECK(strcmp(key, "sk-ds-2") == 0); CHECK(cst_creds_load("openai", key, sizeof(key)) == 0); CHECK(strcmp(key, "sk-oa") == 0); CHECK(cst_creds_load("minimax", key, sizeof(key)) == 0); /* legacy kept */ CHECK(strcmp(key, "sk-old") == 0); CHECK(cst_creds_save("deepseek", "bad\nkey") != 0); char path[512]; snprintf(path, sizeof(path), "%s/cst-agent/credentials", g_dir); #ifdef _WIN32 { wchar_t *wp = os_utf8_to_wide(path); PSECURITY_DESCRIPTOR sd = NULL; LPWSTR s = NULL; CHECK(wp && GetNamedSecurityInfoW(wp, SE_FILE_OBJECT, LABEL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &sd) == ERROR_SUCCESS); CHECK(ConvertSecurityDescriptorToStringSecurityDescriptorW( sd, SDDL_REVISION_1, LABEL_SECURITY_INFORMATION, &s, NULL)); CHECK(wcsstr(s, L"NR") && wcsstr(s, L";ME)")); /* Low-IL cannot read */ LocalFree(s); LocalFree(sd); free(wp); } #else struct stat st; CHECK(stat(path, &st) == 0); CHECK((st.st_mode & 0077) == 0); #endif CHECK(cst_creds_resolve("deepseek", key, sizeof(key), &from) == 0); CHECK(strcmp(from, "saved") == 0); setenv("MINIMAX_API_KEY", "sk-env", 1); unlink(path); CHECK(cst_creds_resolve("minimax", key, sizeof(key), &from) == 0); CHECK(strcmp(key, "sk-env") == 0 && strcmp(from, "MINIMAX_API_KEY") == 0); unsetenv("MINIMAX_API_KEY"); } static void test_settings(void) { cst_settings_t s; CHECK(cst_settings_load(&s) != 0); CHECK(cst_settings_model(&s, "deepseek") == NULL); cst_agent_config_t cfg; memset(&cfg, 0, sizeof(cfg)); snprintf(cfg.provider, sizeof(cfg.provider), "deepseek"); snprintf(cfg.model, sizeof(cfg.model), "deepseek-v4-pro"); snprintf(cfg.effort, sizeof(cfg.effort), "high"); CHECK(cst_settings_remember(&cfg) == 0); snprintf(cfg.provider, sizeof(cfg.provider), "openai"); snprintf(cfg.model, sizeof(cfg.model), "gpt-5"); snprintf(cfg.effort, sizeof(cfg.effort), "max"); CHECK(cst_settings_remember(&cfg) == 0); CHECK(cst_settings_load(&s) == 0); CHECK(strcmp(s.provider, "openai") == 0); CHECK(strcmp(s.effort, "max") == 0); CHECK(strcmp(cst_settings_model(&s, "deepseek"), "deepseek-v4-pro") == 0); CHECK(strcmp(cst_settings_model(&s, "openai"), "gpt-5") == 0); CHECK(s.nmodels == 2); write_file("settings.json", "{not json"); CHECK(cst_settings_load(&s) != 0); CHECK(s.provider[0] == 0); } static void test_effort(void) { CHECK(cst_effort_valid("low") && cst_effort_valid("max")); CHECK(!cst_effort_valid("ultra") && !cst_effort_valid(NULL)); CHECK(strcmp(cst_effort_wire("deepseek", "deepseek-flash", "max"), "max") == 0); CHECK(strcmp(cst_effort_wire("openai", "o3-mini", "max"), "high") == 0); CHECK(cst_effort_wire("openai", "gpt-4.1-mini", "high") == NULL); CHECK(cst_effort_wire("minimax", "MiniMax-M2.7", "high") == NULL); cst_message_t m = {0}; m.role = CST_ROLE_USER; m.content = "hi"; cst_llm_request_t req = {0}; req.model = "deepseek-flash"; req.msgs = &m; req.nmsgs = 1; char *body = cst_llm_build_body(&req); CHECK(body && !strstr(body, "reasoning_effort")); free(body); req.reasoning_effort = "high"; body = cst_llm_build_body(&req); CHECK(body && strstr(body, "\"reasoning_effort\":\"high\"")); free(body); } int main(void) { CHECK(test_tmpdir(g_dir, sizeof(g_dir), "cst-config") == 0); setenv("XDG_CONFIG_HOME", g_dir, 1); unsetenv("DEEPSEEK_API_KEY"); unsetenv("MINIMAX_API_KEY"); unsetenv("OPENAI_API_KEY"); char sub[300]; snprintf(sub, sizeof(sub), "%s/cst-agent", g_dir); CHECK(test_mkdir(sub, 0755) == 0); test_creds(); test_settings(); test_effort(); CHECK(test_rmrf(g_dir) == 0); printf("test_config: OK\n"); return 0; }