// Unit tests for bmoe-server's policy (server/): the rules that decide what the engine is fed and // which value wins, driven without HTTP, a session or a model. // // * the chat protocol: which request fields become an engine turn, and what a turn's result // (text, tool calls, token counts) looks like on the wire; // * the turn queue: first come first served, a bound, and a caller that gives its place up; // * the settings layers: defaults < plan < launch < user, what a reset removes, what persists; // * the JSON edges: form values to parameter strings and back; // * access: which host names, origins, keys and content types reach the API, and when the server // may not start at all; // * decide: the request fields a decision is read from, and its answer on the wire; // * model files: which names make a split set, and how a directory's files group into models; // * the plan view: one shape for every machine (an NPU phone, a discrete card, the cores alone), // the device roles and their words, the memory pools, the decision groups. // * downloads: which curl failures are retried and after how long, what a resume still needs on // disk, and that deleting a partial download stays inside the models folder. // // Checks are explicit (not ): the Release build defines NDEBUG, which compiles assert out. #include "access.h" #include "decide_protocol.h" #include "download_policy.h" #include "hf_repo.h" #include "json_util.h" #include "model_files.h" #include "openai_chat.h" #include "plan_view.h" #include "settings_store.h" #include "turn_queue.h" #include "bmoe/planner.h" #include #include #include #include #include #include #include #include #include #include #include using namespace bmoe; using namespace bmoe::server; static int failures = 0; static void check(bool ok, const std::string & what) { std::printf("[%s] %s\n", ok ? "PASS" : "FAIL", what.c_str()); if (!ok) ++failures; } static OpenAiChatRequest parsed(const char * body, bool * ok = nullptr, std::string * err = nullptr) { OpenAiChatRequest r; std::string e; RunConfig cfg; cfg.n_predict = 100; cfg.think = true; const bool good = parse_chat_request(json::parse(body), cfg, r, e); if (ok) *ok = good; if (err) *err = e; return r; } static void protocol_tests() { bool ok = false; std::string err; { const OpenAiChatRequest r = parsed(R"j({"messages":[{"role":"developer","content":"be brief"}, {"role":"user","content":[{"type":"text","text":"a"},{"type":"text","text":"b"}]}]})j", &ok); check(ok && r.turn.messages.size() == 2 && r.turn.messages[0].role == "system" && r.turn.messages[1].content == "ab", "developer is system, and text parts join"); check(r.turn.n_predict == 100 && r.turn.think && !r.stream && !r.include_usage && r.turn.tools.empty(), "what a request leaves out comes from the config"); } { const OpenAiChatRequest r = parsed(R"j({"messages":[{"role":"user","content":"read it"}, {"role":"assistant","content":null,"tool_calls":[{"id":"c1","type":"function", "function":{"name":"read","arguments":"{\"path\":\"a.py\"}"}}]}, {"role":"tool","tool_call_id":"c1","content":"print(1)"}], "tools":[{"type":"function","function":{"name":"read","description":"Read a file", "parameters":{"type":"object","properties":{"path":{"type":"string"}}}}}], "tool_choice":"required","stream":true,"stream_options":{"include_usage":true}, "max_tokens":7})j", &ok); check(ok && r.turn.messages.size() == 3, "an agent's history parses"); const ChatMessage & call = r.turn.messages[1]; check(call.content.empty() && call.tool_calls.size() == 1 && call.tool_calls[0].id == "c1" && call.tool_calls[0].name == "read" && call.tool_calls[0].arguments == "{\"path\":\"a.py\"}", "an assistant turn with null content keeps its call"); check(r.turn.messages[2].role == "tool" && r.turn.messages[2].tool_call_id == "c1" && r.turn.messages[2].content == "print(1)", "a tool message keeps the call it answers"); check(r.turn.tools.size() == 1 && r.turn.tools[0].name == "read" && json::parse(r.turn.tools[0].parameters)["properties"].contains("path"), "a tool's schema travels as JSON text"); check(r.turn.tool_choice == ToolChoice::Required && r.stream && r.include_usage && r.turn.n_predict == 7, "tool_choice, stream, include_usage and max_tokens are read"); } { const OpenAiChatRequest r = parsed(R"j({"messages":[{"role":"user","content":"x"}, {"role":"assistant","tool_calls":[{"function":{"name":"f","arguments":{"k":1}}}]}, {"role":"tool","content":"ok"}]})j", &ok); check(ok && r.turn.messages[1].tool_calls[0].arguments == "{\"k\":1}", "arguments sent as an object are carried as their text"); } parsed(R"j({"messages":[{"role":"user","content":"hi"},{"role":"assistant","content":"yo"}]})j", &ok, &err); check(!ok && err.find("last message") != std::string::npos, "a conversation ending on an answer is refused"); parsed(R"j({"messages":[{"role":"user","content":[{"type":"image_url","image_url":{"url":"x"}}]}]})j", &ok); check(!ok, "an image part is refused, not dropped"); parsed(R"j({"messages":[{"role":"user","content":"hi"}],"tools":[{"type":"web_search"}]})j", &ok); check(!ok, "a tool that is not a function is refused"); parsed(R"j({"messages":[{"role":"user","content":"hi"}],"tool_choice":"sometimes"})j", &ok); check(!ok, "an unknown tool_choice is refused"); parsed(R"j({"messages":[]})j", &ok); check(!ok, "an empty conversation is refused"); // A field of the wrong type is the client's mistake: refused with a reason, never thrown. parsed(R"j({"messages":[{"role":1,"content":"hi"}]})j", &ok, &err); check(!ok && err.find("role") != std::string::npos, "a role that is not a string is refused, not thrown"); parsed(R"j({"messages":[{"role":"user","content":[{"type":{"x":1},"text":"a"}]}]})j", &ok, &err); check(!ok && err.find("content") != std::string::npos, "a part type that is not a string is refused"); parsed(R"j({"messages":[{"role":"user","content":"hi"}],"tools":[{"type":7,"function":{"name":"f"}}]})j", &ok); check(!ok, "a tool type that is not a string is refused"); parsed(R"j({"messages":[{"role":"user","content":"hi"}],"tools":[{"function":{"name":"f"}}]})j", &ok); check(ok, "a tool with no type is a function, as before"); parsed(R"j({"messages":[{"role":null,"content":"hi"}]})j", &ok, &err); check(!ok && err.find("role") != std::string::npos, "a null role is an unsupported one"); int shape = 0; for (const char * body : {R"j({"messages":[{"role":"user","content":"hi","tool_calls":7}]})j", R"j({"messages":[{"role":"assistant","content":"a","tool_calls":[{"function": {"name":"f","arguments":[1]}}]},{"role":"user","content":"b"}]})j", R"j({"messages":"hi"})j", R"j({"messages":[[1]]})j", R"j([1])j", R"j(7)j", R"j({"messages":[{"role":"user","content":"hi"}],"stream":"yes","think":3, "stream_options":7,"tool_choice":7,"max_tokens":"9"})j"}) { bool threw = false; try { parsed(body, &ok, &err); } catch (const std::exception &) { threw = true; } check(!threw, "a body of the wrong shape is answered, not thrown (#" + std::to_string(++shape) + ")"); } check(!parsed(R"j({"messages":[{"role":"user","content":"hi"}],"think":false})j").turn.think && !parsed(R"j({"messages":[{"role":"user","content":"hi"}],"reasoning_effort":"none"})j").turn.think && parsed(R"j({"messages":[{"role":"user","content":"hi"}],"reasoning_effort":"low"})j").turn.think && parsed(R"j({"messages":[{"role":"user","content":"hi"}],"reasoning_effort":"none","think":true})j") .turn.think, "thinking: the server's own field wins, and only effort none turns it off"); // The token budget is bounded where it enters: by the parameter table, not by what an int holds. const auto budget = [&](const char * field) { const std::string body = std::string(R"j({"messages":[{"role":"user","content":"hi"}],)j") + field + "}"; return parsed(body.c_str(), &ok, &err).turn.n_predict; }; const int top = (int) find_param("n-predict")->max; check(budget(R"j("max_tokens":7)j") == 7 && ok, "a budget inside the bound is taken as given"); check(budget(R"j("max_tokens":2147483647)j") == top && ok, "a budget past the bound is clamped to it"); check(budget(R"j("max_tokens":18446744073709551615)j") == top && ok, "and so is one no int could hold"); check(budget(R"j("max_completion_tokens":5,"max_tokens":9)j") == 5 && ok, "max_completion_tokens wins"); check(budget(R"j("max_tokens":null)j") == 100 && ok && budget(R"j("max_tokens":0)j") == 100 && ok, "null and 0 leave the configured budget"); budget(R"j("max_tokens":-1)j"); check(!ok && err.find("max_tokens") != std::string::npos, "a negative budget is refused"); budget(R"j("max_tokens":12.5)j"); check(!ok, "a fractional budget is refused"); budget(R"j("max_completion_tokens":"100")j"); check(!ok && err.find("max_completion_tokens") != std::string::npos, "a budget that is not a number is refused"); // Responses. RunResult r; r.ok = true; r.generated_text = ""; r.tool_calls = {{"", "read", "{\"path\":\"a.py\"}"}, {"given", "grep", "{}"}}; r.summary.n_generated = 12; r.summary.n_prompt = 30; // prefilled this turn r.summary.n_past = 512; // context after the turn ensure_tool_call_ids(r.tool_calls, "chatcmpl-9"); check(r.tool_calls[0].id == "call_chatcmpl-9_0" && r.tool_calls[1].id == "given", "a call without an id gets one, and a given id is kept"); check(finish_reason(r, 100) == "tool_calls", "a turn that calls finishes with tool_calls"); const ChatResponseMeta meta{"chatcmpl-9", 5, "m.gguf"}; const json c = completion_json(meta, r, finish_reason(r, 100)); const json & msg = c["choices"][0]["message"]; check(msg["content"].is_null() && msg["tool_calls"].size() == 2 && msg["tool_calls"][0]["function"]["arguments"] == "{\"path\":\"a.py\"}" && msg["tool_calls"][0]["type"] == "function" && !msg["tool_calls"][0].contains("index"), "a completion carries the calls, with null content"); check(c["usage"]["prompt_tokens"] == 500 && c["usage"]["completion_tokens"] == 12 && c["usage"]["total_tokens"] == 512 && c["usage"]["prompt_tokens_details"]["cached_tokens"] == 470, "usage counts the whole prompt and reports the reused part as cached"); const json d = tool_calls_delta(r.tool_calls); check(d["tool_calls"][1]["index"] == 1 && d["tool_calls"][1]["id"] == "given", "a streamed call carries its index"); const json uc = usage_chunk_json(meta, r.summary); check(uc["choices"].empty() && uc["usage"]["total_tokens"] == 512, "the usage chunk has no choices"); RunResult plain; plain.generated_text = "hi"; plain.summary.n_generated = 3; check(finish_reason(plain, 3) == "length" && finish_reason(plain, 4) == "stop", "stop or length by the budget"); // Every failure kind has its own stable name, and only Failed closes the session. { const RunError kinds[] = { RunError::None, RunError::ContextFull, RunError::EmptyPrompt, RunError::TemplateRejected, RunError::NeedsChatMode, RunError::InvalidRequest, RunError::Failed}; std::set names; for (RunError k : kinds) names.insert(run_error_name(k)); check(names.size() == sizeof(kinds) / sizeof(kinds[0]), "every failure kind has its own name"); check(std::string(run_error_name(RunError::ContextFull)) == "context_full", "a full context is context_full"); check(!run_error_recoverable(RunError::Failed) && !run_error_recoverable(RunError::None) && run_error_recoverable(RunError::ContextFull) && run_error_recoverable(RunError::TemplateRejected), "only a failed run closes the session"); } plain.summary.n_predict = 3; check(finish_reason(plain, 1000) == "length", "a budget the context cut short is a length stop"); plain.summary.n_predict = 8; check(finish_reason(plain, 1000) == "stop", "an answer that ended under the cut budget is a stop"); plain.summary.n_predict = 0; plain.cancelled = true; check(finish_reason(plain, 4) == "cancelled", "a cancelled turn says so"); check(completion_json(meta, plain, "stop")["choices"][0]["message"]["content"] == "hi" && !completion_json(meta, plain, "stop")["choices"][0]["message"].contains("tool_calls"), "an ordinary answer has text and no calls"); } static void queue_tests() { using Admit = TurnQueue::Admit; const auto fast = std::chrono::milliseconds(5); { TurnQueue q(1); check(q.enter() == Admit::Granted, "an empty line is entered at once"); std::vector order; std::mutex om; std::thread second([&] { if (q.enter(nullptr, fast) == Admit::Granted) { std::lock_guard g(om); order.push_back(2); } q.leave(); }); while (q.waiting() < 1) std::this_thread::sleep_for(fast); check(q.enter(nullptr, fast) == Admit::Full, "a full line turns the next caller away"); { std::lock_guard g(om); order.push_back(1); } q.leave(); second.join(); check(order == std::vector({1, 2}), "the waiting caller runs after the running one"); check(q.enter() == Admit::Granted, "the line is free again afterwards"); q.leave(); } { // Three callers behind the running one; the middle one gives up. The others still run, in // the order they arrived. TurnQueue q(8); q.enter(); std::vector order; std::mutex om; std::atomic give_up{false}; std::vector ts; std::atomic abandoned{0}; for (int i = 0; i < 3; ++i) { ts.emplace_back([&, i] { const Admit a = q.enter([&, i] { return !(i == 1 && give_up); }, fast); if (a == Admit::Abandoned) { ++abandoned; return; } { std::lock_guard g(om); order.push_back(i); } q.leave(); }); while (q.waiting() < (size_t) i + 1) std::this_thread::sleep_for(fast); } give_up = true; while (abandoned == 0) std::this_thread::sleep_for(fast); check(q.waiting() == 2, "a caller that gives up leaves the line"); q.leave(); for (std::thread & t : ts) t.join(); check(order == std::vector({0, 2}), "the line moves past the place that was given up"); check(q.enter() == Admit::Granted, "and is free once everyone has run"); q.leave(); } } static void settings_tests() { RunConfig defaults; defaults.n_threads = 4; defaults.moe.enabled = true; const std::filesystem::path path = std::filesystem::temp_directory_path() / "bmoe_server_test_settings.json"; std::error_code ec; std::filesystem::remove(path, ec); SettingsStore s(defaults, path.u8string()); check(s.load().empty(), "no settings file is a clean start"); check(s.config().n_threads == 4, "defaults apply"); s.apply_plan({{"threads", "6"}, {"io-threads", "2"}}, json::array()); check(s.config().n_threads == 6 && s.config().moe.io_threads == 2, "plan layer overrides defaults"); check(s.operator_keys().empty(), "a plan is not an operator choice"); s.set_launch_values({{"threads", "8"}}); check(s.config().n_threads == 8, "launch flags override the plan"); json rejected = s.apply(json{{"threads", 12}, {"top-k", "abc"}, {"nope", 1}}, {}); check(s.config().n_threads == 12, "user values override launch flags"); check(rejected.contains("top-k") && rejected.contains("nope") && !rejected.contains("threads"), "unparseable values and unknown keys are rejected, the rest applied"); const auto keys = s.operator_keys(); check(keys.size() == 1 && keys[0] == "threads", "operator keys: launch and user"); s.apply(json::object(), {"threads"}); check(s.config().n_threads == 6, "reset removes the key from every operator layer: the plan shows through"); s.apply(json{{"cache-mb", "auto"}, {"temp", 0.7}, {"overlap", true}}, {}); SettingsStore again(defaults, path.u8string()); check(again.load().empty(), "saved settings reload without warnings"); const RunConfig c = again.config(); check(c.moe.cache_auto && c.sampling.temp == 0.7f && c.moe.overlap, "user layer persists with its types"); check(again.auto_plan(true) && !again.auto_plan(false), "auto_plan follows the fallback until it is set"); again.set_auto_plan(false); SettingsStore third(defaults, path.u8string()); third.load(); check(!third.auto_plan(true), "auto_plan, once turned off, stays off across a restart"); std::filesystem::remove(path, ec); } static void planning_config_tests() { const std::string path = (std::filesystem::temp_directory_path() / "bmoe_server_test_plan.json").string(); std::filesystem::remove(path); RunConfig defaults; defaults.moe.enabled = true; SettingsStore store(defaults, path); store.apply(json{{"threads", 6}}, {}); store.apply_plan({{"cache-mb", "1333"}, {"force-cache", "true"}}, json::array()); check(store.config().moe.cache_mb == 1333 && store.config().moe.force_cache && store.config().n_threads == 6, "the plan layer is in the config"); const RunConfig base = store.planning_config(); check(base.moe.cache_mb == defaults.moe.cache_mb && !base.moe.force_cache && base.n_threads == 6, "the planning config leaves the plan layer out and keeps the person's values"); // What a second plan would do: its values are what differ from the planning config, so a // choice it repeats is still a value, and replacing the layer keeps it. std::map second; RunConfig planned = base; planned.moe.cache_mb = 1233; planned.moe.force_cache = true; for (const ParamDesc & d : params()) if (d.get(planned) != d.get(base)) second[d.key] = d.get(planned); check(second.count("force-cache") == 1 && second.count("cache-mb") == 1, "a repeated choice is still a value"); store.apply_plan(second, json::array()); // (validate() wants a model path too; the cache rule is the one this guards.) check(store.config().moe.cache_mb == 1233 && store.config().moe.force_cache && validate(store.config()).error.find("pathological") == std::string::npos, "the second plan applies whole, and the cache rule is satisfied"); std::filesystem::remove(path); } static void json_tests() { std::string s; check(value_to_param_string(json(true), s) && s == "true", "bool to parameter string"); check(value_to_param_string(json(4), s) && s == "4", "int to parameter string"); check(value_to_param_string(json(4.0), s) && s == "4", "integral float is an int"); check(value_to_param_string(json(0.95), s) && s == "0.95", "float keeps its value"); check(value_to_param_string(json("auto"), s) && s == "auto", "string passes through"); check(!value_to_param_string(json::array(), s), "an array is not a parameter value"); const ParamDesc * cache = find_param("cache-mb"); check(param_string_to_value(*cache, "auto") == json("auto") && param_string_to_value(*cache, "2000") == json(2000), "an accepts-auto int renders as auto or a number"); check(param_string_to_value(*find_param("moe-stream"), "true") == json(true), "bool renders as a JSON bool"); // What a write to the API must declare. The three types a form can send are the ones to refuse. check(is_json_content_type("application/json") && is_json_content_type("Application/JSON; charset=utf-8") && is_json_content_type(" application/json ;charset=UTF-8"), "JSON is JSON in any case, with or without parameters"); check(!is_json_content_type("") && !is_json_content_type("text/plain") && !is_json_content_type("application/x-www-form-urlencoded") && !is_json_content_type("multipart/form-data; boundary=x"), "what a form can send is not JSON, and neither is no type at all"); check(!is_json_content_type("application/jsonp") && !is_json_content_type("text/plain; application/json") && !is_json_content_type("application/json, text/plain"), "a type that only contains the word is not JSON"); } static void access_tests() { check(is_api_path("/api/info") && is_api_path("/v1/chat/completions") && !is_api_path("/") && !is_api_path("/assets/app.js") && !is_api_path("/apix"), "the API is /api/* and /v1/*, nothing else"); check(is_loopback_host("127.0.0.1") && is_loopback_host("localhost:8765") && is_loopback_host("[::1]:8765") && is_loopback_host("::1") && !is_loopback_host("0.0.0.0") && !is_loopback_host("example.com:8765") && !is_loopback_host("192.168.1.10"), "loopback host names, with or without a port"); check(bearer_matches("Bearer s3cret", "s3cret") && bearer_matches("bearer s3cret", "s3cret"), "a bearer token matches the key, the scheme in either case"); check(!bearer_matches("Bearer s3cre", "s3cret") && !bearer_matches("Bearer s3cret1", "s3cret") && !bearer_matches("Bearer S3CRET", "s3cret") && !bearer_matches("s3cret", "s3cret") && !bearer_matches("Basic s3cret", "s3cret") && !bearer_matches("", "s3cret"), "a shorter, longer, differently cased, bare or basic token does not"); check(!bearer_matches("Bearer ", "") && !bearer_matches("", ""), "an empty key matches nothing"); AccessPolicy local; local.loopback = true; local.origins = {"http://127.0.0.1:8765"}; auto req = [](const char * method, const char * path) { RequestFacts f; f.method = method; f.path = path; f.host = "127.0.0.1:8765"; return f; }; check(check_access(local, req("GET", "/api/info")).allowed(), "a local program's GET is answered"); { RequestFacts f = req("POST", "/api/cancel"); f.content_type = "application/json"; check(check_access(local, f).allowed(), "a local program's JSON write is answered"); f.content_type = "text/plain"; check(check_access(local, f).status == 415, "a write that is not JSON is refused with 415"); } { RequestFacts f = req("GET", "/api/info"); f.host = "evil.example:8765"; check(check_access(local, f).status == 403, "a loopback server refuses a foreign host name"); AccessPolicy open = local; open.loopback = false; check(check_access(open, f).allowed(), "a server bound beyond loopback answers to its name"); } { RequestFacts f = req("GET", "/api/plan"); f.has_origin = true; f.origin = "http://evil.example"; check(check_access(local, f).status == 403, "a cross-origin GET to the API is refused"); f.origin = "http://127.0.0.1:8765"; check(check_access(local, f).allowed(), "the UI's own origin is answered"); RequestFacts g = req("GET", "/api/events"); g.sec_fetch_site = "cross-site"; check(check_access(local, g).status == 403, "a cross-site read with no Origin is refused too"); RequestFacts h = req("GET", "/assets/app.js"); h.sec_fetch_site = "cross-site"; check(check_access(local, h).allowed(), "the UI's files are not the API"); // Another port of the same host is the same site, and exactly where a hostile local page is. for (const char * site : {"same-site", "cross-site", "something-new"}) { RequestFacts s = req("GET", "/api/plan"); s.sec_fetch_site = site; check(check_access(local, s).status == 403, std::string("Sec-Fetch-Site: ") + site + " is refused on the API"); } for (const char * site : {"same-origin", "none", ""}) { RequestFacts s = req("GET", "/api/plan"); s.sec_fetch_site = site; check(check_access(local, s).allowed(), std::string("Sec-Fetch-Site: '") + site + "' (this page, the person, or no browser) is answered"); } RequestFacts so = req("GET", "/api/plan"); so.sec_fetch_site = "same-site"; so.has_origin = true; so.origin = "http://127.0.0.1:8765"; check(check_access(local, so).allowed(), "an Origin the server knows decides over Sec-Fetch-Site"); } { AccessPolicy keyed = local; keyed.api_key = "s3cret"; RequestFacts f = req("GET", "/v1/models"); const AccessDecision d = check_access(keyed, f); check(d.status == 401, "with a key set, an API request without it gets 401"); f.authorization = "Bearer s3cret"; check(check_access(keyed, f).allowed(), "and is answered with it"); f.authorization = "Bearer wrong"; check(check_access(keyed, f).status == 401, "a wrong key is 401"); RequestFacts page = req("GET", "/index.html"); check(check_access(keyed, page).allowed(), "the key gates the API, not the UI's files"); RequestFacts w = req("PUT", "/api/config"); w.authorization = "Bearer s3cret"; check(check_access(keyed, w).status == 415, "the key does not excuse a write from naming JSON"); RequestFacts x = req("POST", "/v1/chat/completions"); x.has_origin = true; x.origin = "http://evil.example"; x.authorization = "Bearer s3cret"; check(check_access(keyed, x).status == 403, "a foreign origin is refused before the key is looked at"); } check(launch_refusal("127.0.0.1", "", false).empty() && launch_refusal("localhost", "", false).empty() && launch_refusal("::1", "", false).empty(), "loopback needs no key"); check(!launch_refusal("0.0.0.0", "", false).empty() && !launch_refusal("192.168.1.10", "", false).empty(), "beyond loopback without a key the server does not start"); check(launch_refusal("0.0.0.0", "s3cret", false).empty() && launch_refusal("0.0.0.0", "", true).empty(), "a key, or --no-api-key, lets it"); check(is_loopback_peer("127.0.0.1") && is_loopback_peer("127.8.9.10") && is_loopback_peer("::1") && is_loopback_peer("::ffff:127.0.0.1"), "a loopback peer, IPv4, IPv6 or mapped"); check(!is_loopback_peer("192.168.1.10") && !is_loopback_peer("::ffff:10.0.0.2") && !is_loopback_peer("") && !is_loopback_peer("fe80::1") && !is_loopback_peer("1127.0.0.1"), "anything else is the network"); const auto csp = [] { for (const auto & h : security_headers()) if (h.first == "Content-Security-Policy") return h.second; return std::string(); }(); check(csp.find("img-src 'self' data:;") != std::string::npos && csp.find("frame-ancestors 'none'") != std::string::npos && csp.find("script-src 'self';") != std::string::npos && csp.find("unsafe-") == std::string::npos, "the page loads images from itself or data: only, runs no inline script and cannot be framed"); std::set names; for (const auto & h : security_headers()) names.insert(h.first); check(names.count("X-Content-Type-Options") && names.count("Referrer-Policy"), "no sniffing, no referrer"); } static void file_tests() { namespace fs = std::filesystem; const fs::path dir = fs::temp_directory_path() / ("bmoe-server-test-" + std::to_string(std::rand())); fs::create_directories(dir / "models" / "sub"); const auto write = [](const fs::path & p, const char * s) { std::error_code ec; fs::create_directories(p.parent_path(), ec); std::FILE * f = std::fopen(p.u8string().c_str(), "wb"); check(f != nullptr, "the test can write its fixture"); if (!f) return; std::fputs(s, f); std::fclose(f); }; std::string key, err; write(dir / "key", "s3cret\r\n"); check(read_api_key_file((dir / "key").u8string(), key, err) && key == "s3cret", "a key file is read without its trailing line break"); write(dir / "blank", " \n\n"); key = "kept"; check(!read_api_key_file((dir / "blank").u8string(), key, err) && !err.empty() && key == "kept", "a key file with no key is refused"); check(!read_api_key_file((dir / "absent").u8string(), key, err) && !err.empty(), "and so is a missing one"); const std::vector models = {(dir / "models").u8string()}; write(dir / "models" / "a.gguf", ""); write(dir / "secret.gguf", ""); std::string out; check(confine_model_path((dir / "models" / "a.gguf").u8string(), models, out, err) && fs::equivalent(fs::u8path(out), dir / "models" / "a.gguf"), "a model in the models folder is opened"); check(confine_model_path("sub/b.gguf", models, out, err) && fs::u8path(out).lexically_relative(fs::weakly_canonical(dir / "models")) == fs::path("sub/b.gguf"), "a relative path is taken inside the models folder"); check(!confine_model_path((dir / "secret.gguf").u8string(), models, out, err) && !err.empty(), "a file outside it is refused"); check(!confine_model_path((dir / "models" / ".." / "secret.gguf").u8string(), models, out, err), "and so is a way out through .."); check(!confine_model_path("../secret.gguf", models, out, err), "relative too"); check(!confine_model_path(models.front(), models, out, err), "the folder itself is not a model"); std::error_code ec; fs::create_symlink(dir / "secret.gguf", dir / "models" / "link.gguf", ec); if (!ec) check(!confine_model_path((dir / "models" / "link.gguf").u8string(), models, out, err), "a link inside the folder to a file outside it is refused"); check(confine_model_path("", models, out, err) && out.empty(), "no model is no path to confine"); // A folder the server lists models from beside the models folder (--scan-dir) is a root too, and // only the models folder takes relative paths. write(dir / "elsewhere" / "c.gguf", ""); const std::vector roots = {models.front(), (dir / "elsewhere").u8string()}; check(confine_model_path((dir / "elsewhere" / "c.gguf").u8string(), roots, out, err) && fs::equivalent(fs::u8path(out), dir / "elsewhere" / "c.gguf"), "a model in a scanned folder is opened"); check(!confine_model_path((dir / "elsewhere" / "c.gguf").u8string(), models, out, err), "and refused where that folder is not listed"); check(!confine_model_path((dir / "secret.gguf").u8string(), roots, out, err), "a second root widens nothing else"); check(!confine_model_path("x.gguf", {}, out, err) && !err.empty(), "no folder at all opens nothing"); // The scan goes one folder deep (a split set kept in a folder of its own), and no further: not // into a folder inside that one, and not through a link to a folder, which could loop or lead // out of the root. What the listing shows is still opened only through the confinement. write(dir / "models" / "set" / "big-00001-of-00002.gguf", ""); write(dir / "models" / "set" / "big-00002-of-00002.gguf", ""); write(dir / "models" / "set" / "deeper" / "hidden.gguf", ""); write(dir / "outside" / "far.gguf", ""); fs::create_directory_symlink(dir / "outside", dir / "models" / "linked", ec); const bool linked = !ec; const std::vector scanned = scan_model_files(models.front()); const auto listed = [&](const std::string & folder, const std::string & first) { for (const ModelFiles & m : scanned) if (m.folder == folder && m.first == first) return &m; return (const ModelFiles *) nullptr; }; check(listed("", "a.gguf") != nullptr, "scan: a model in the folder itself is listed"); const ModelFiles * set = listed("set", "big-00001-of-00002.gguf"); check(set && set->complete() && set->files.size() == 2, "scan: a split set in a subfolder is one model, complete"); check(!listed("set/deeper", "hidden.gguf") && !listed("deeper", "hidden.gguf"), "scan: a folder inside a subfolder is not entered"); if (linked) { check(!listed("linked", "far.gguf"), "scan: a link to a folder is not followed"); check(!confine_model_path("linked/far.gguf", models, out, err) && !confine_model_path((dir / "models" / "linked" / "far.gguf").u8string(), models, out, err), "scan: and a model through it, named by hand, is refused by the confinement"); } check(confine_model_path("set/big-00001-of-00002.gguf", models, out, err) && fs::equivalent(fs::u8path(out), dir / "models" / "set" / "big-00001-of-00002.gguf"), "scan: a model in a subfolder opens through the confinement"); check(!confine_model_path("set/../../secret.gguf", models, out, err) && !confine_model_path((dir / "models" / "set" / ".." / ".." / "secret.gguf").u8string(), models, out, err), "scan: a way out through the subfolder is refused"); fs::remove_all(dir, ec); } static void decide_tests() { DecideRequest r; std::string err; check(parse_decide_request(json::parse(R"({"prefix":"p","suffix":"s","choices":["A","B"]})"), r, err) && r.prefix == "p" && r.suffix == "s" && r.choices.size() == 2 && r.choices[1] == "B" && r.reuse_prefix, "a decide body is read whole, reuse_prefix defaulting to true"); check(parse_decide_request(json::parse(R"({"choices":["A"],"reuse_prefix":false})"), r, err) && r.prefix.empty() && !r.reuse_prefix, "prefix and suffix may be left out; reuse_prefix may be turned off"); check(!parse_decide_request(json::parse(R"({"prefix":"p"})"), r, err) && err.find("choices") != std::string::npos, "no choices is refused"); check(!parse_decide_request(json::parse(R"({"choices":["A",1]})"), r, err), "a choice that is not a string is refused"); check(!parse_decide_request(json::parse(R"({"choices":["A"],"prefix":3})"), r, err), "a prefix that is not a string is refused"); check(!parse_decide_request(json::parse(R"({"choices":["A"],"reuse_prefix":"yes"})"), r, err), "reuse_prefix must be a boolean"); check(!parse_decide_request(json::parse(R"([1])"), r, err), "a body that is not an object is refused"); DecideResult d; d.ok = true; d.best = 1; d.choice_logp = {-3.25, -0.5, -std::numeric_limits::infinity()}; d.n_tokens = 10; d.n_reused = 4; d.n_prefilled = 6; d.prefill.seconds = 0.5; d.prefix_state_bytes = 2 * 1024 * 1024; const json j = decide_json(d); check(j["best"] == 1 && j["choice_logp"].size() == 3 && j["choice_logp"][0] == -3.25 && j["choice_logp"][2].is_null(), "the answer carries best and the log-probabilities, null for a choice with no mass"); check(j["n_tokens"] == 10 && j["n_reused"] == 4 && j["n_prefilled"] == 6 && j["prefill_s"] == 0.5 && j["prefix_state_mib"] == 2.0 && j["cancelled"] == false, "the counts, the prefill figures and the kept state travel with it"); } static void model_files_tests() { ShardName sh; check(parse_shard_name("Qwen3-235B-A22B-Q2_K-00002-of-00005.gguf", sh) && sh.stem == "Qwen3-235B-A22B-Q2_K" && sh.index == 2 && sh.count == 5, "a gguf-split name parses into stem, index and count"); check(parse_shard_name("m-00001-OF-00002.GGUF", sh) && sh.stem == "m" && sh.index == 1 && sh.count == 2, "the separator and the extension match in any case"); check(!parse_shard_name("model.gguf", sh) && !parse_shard_name("-00001-of-00002.gguf", sh) && !parse_shard_name("m-0001-of-00002.gguf", sh) && !parse_shard_name("m-00001-of-0002.gguf", sh) && !parse_shard_name("m-000a1-of-00002.gguf", sh) && !parse_shard_name("m-00001_of-00002.gguf", sh) && !parse_shard_name("m-00001-of-00002.gguf.part", sh), "anything else is not a shard: no stem, a digit short, a letter, another separator, a partial file"); check(!parse_shard_name("m-00000-of-00002.gguf", sh) && !parse_shard_name("m-00003-of-00002.gguf", sh) && !parse_shard_name("m-00001-of-00000.gguf", sh), "an index of 0, past the count, or a count of 0 cannot be a shard"); check(shard_file_name("m", 1, 12) == "m-00001-of-00012.gguf", "a shard's name, as gguf-split writes it"); check(is_gguf_name("a.GGUF") && !is_gguf_name("a.gguf.part") && !is_gguf_name("gguf"), "what a gguf file is"); const std::vector g = group_model_files({"b-00002-of-00003.gguf", "a.gguf", "notes.txt", "b-00001-of-00003.gguf", "c-00002-of-00002.gguf", "a.gguf.part"}); check(g.size() == 3, "three models: a file, a set, and a set without its first shard"); check(g.size() == 3 && g[0].first == "a.gguf" && g[0].count == 1 && g[0].complete(), "a single file is complete"); check(g.size() == 3 && g[1].first == "b-00001-of-00003.gguf" && g[1].count == 3 && !g[1].complete() && g[1].files == std::vector{"b-00001-of-00003.gguf", "b-00002-of-00003.gguf"}, "a set is listed by its first shard, with the files present in shard order"); check(g.size() == 3 && g[2].first == "c-00001-of-00002.gguf" && g[2].files.size() == 1 && !g[2].complete(), "a set missing its first shard is still listed under the first shard's name, incomplete"); // What a file is for, from its header. The facts mirror three companion files of one released // repository and a model that carries its own prediction head. GgufHeaderFacts h; check(file_role(h) == FileRole::Unknown && std::string(file_role_name(file_role(h))).empty(), "role: an unreadable header says nothing"); h.ok = true; h.arch = "clip"; h.type = "mmproj"; check(file_role(h) == FileRole::Projector, "role: a projector says so in general.type"); h.type.clear(); check(file_role(h) == FileRole::Projector, "role: and an older one by its projector architecture"); h = {}; h.ok = true; h.arch = "dflash"; h.type = "model"; h.n_block = 5; h.reads_target = true; check(file_role(h) == FileRole::Draft, "role: a file that reads another model's layers is a draft"); h.arch = "gemma4-assistant"; h.reads_target = false; h.n_block = 4; h.n_nextn = 4; check(file_role(h) == FileRole::Draft, "role: a file of prediction heads and nothing else is a draft"); h.arch = "glm4moe"; h.n_block = 47; h.n_nextn = 1; check(file_role(h) == FileRole::Model, "role: a model with its own prediction head is a model"); h.type.clear(); check(file_role(h) == FileRole::Model, "role: and so is one with no general.type"); h.n_block = 0; h.n_nextn = 0; check(file_role(h) == FileRole::Other, "role: no transformer blocks is no language model"); h.n_block = 10; h.type = "adapter"; check(file_role(h) == FileRole::Other && std::string(file_role_name(FileRole::Other)) == "other", "role: another file type is not a model"); check(file_role_hint("mmproj-gemma-4-26B-A4B-it-Q8_0.gguf") == FileRole::Projector && file_role_hint("sub/Model-MMPROJ-f16.gguf") == FileRole::Projector && file_role_hint("mtp-gemma-4-26B-A4B-it-Q8_0.gguf") == FileRole::Draft && file_role_hint("dflash-x-BF16.gguf") == FileRole::Draft && file_role_hint("gemma-4-26B-A4B-it-Q4_0.gguf") == FileRole::Model, "role: a name only hints, for ordering a listing whose headers are unread"); } // A repository as a person types it, what a listing holds, and the catalog entry a model becomes. static void hf_tests() { HfRef r; std::string err; check(parse_hf_ref("ggml-org/gemma-4-26B-A4B-it-GGUF", r, err) && r.repo == "ggml-org/gemma-4-26B-A4B-it-GGUF" && r.revision == "main" && r.file.empty(), "hf: an id is owner/name on main"); check(parse_hf_ref(" https://huggingface.co/unsloth/Qwen3.8-Flash-Next-GGUF/tree/main/UD-IQ3_XXS ", r, err) && r.repo == "unsloth/Qwen3.8-Flash-Next-GGUF" && r.revision == "main" && r.file.empty(), "hf: a tree URL names the repository and no file"); check(parse_hf_ref("https://hf.co/a/b/resolve/v2/sub/model-Q4_0.gguf?download=true", r, err) && r.repo == "a/b" && r.revision == "v2" && r.file == "sub/model-Q4_0.gguf", "hf: a resolve URL names the file, the revision, and drops the query"); check(!parse_hf_ref("https://example.com/a/b", r, err), "hf: another host is refused"); check(!parse_hf_ref("onlyowner", r, err), "hf: one segment is refused"); check(!parse_hf_ref("a/b/blob/main/../x.gguf", r, err), "hf: a path that climbs is refused"); check(!parse_hf_ref("a/b c", r, err), "hf: a space in the id is refused"); check(!parse_hf_ref("a/b/resolve/main/x%2F..%2Fy.gguf", r, err), "hf: an escaped path is refused"); check(quant_from_name("Qwen3.6-35B-A3B-Q4_K_M.gguf") == "Q4_K_M", "hf: quant Q4_K_M"); check(quant_from_name("UD-IQ3_XXS/Qwen3.8-Flash-Next-UD-IQ3_XXS-00001-of-00003.gguf") == "UD-IQ3_XXS", "hf: quant with the unsloth prefix, off a shard name"); check(quant_from_name("gemma-4-26B-A4B-it-BF16.gguf") == "BF16", "hf: quant BF16"); check(quant_from_name("mmproj-gemma-4-26B-A4B-it.gguf").empty(), "hf: no quant token is empty"); const json tree = json::parse(R"([ {"type":"file","path":"README.md","size":467}, {"type":"file","path":"Qwen3.6-35B-A3B-Q4_K_M.gguf","size":20419565568}, {"type":"file","path":"mmproj-Qwen3.6-35B-A3B-Q8_0.gguf","size":614194304}, {"type":"file","path":"mtp-Qwen3.6-35B-A3B-Q8_0.gguf","size":4194304}, {"type":"file","path":"Q2_K/big-Q2_K-00002-of-00003.gguf","size":200}, {"type":"file","path":"Q2_K/big-Q2_K-00001-of-00003.gguf","size":100}, {"type":"directory","path":"Q2_K"} ])"); std::vector models; check(parse_hf_tree(tree, models, err) && models.size() == 4, "hf: a listing's gguf files, shards grouped"); check(models.size() == 4 && models[0].role == "model" && models[1].role == "model" && models[2].role == "draft" && models[3].role == "projector", "hf: what the names suggest are models come first, the companion files after them"); check(models[0].name == "Q2_K/big-Q2_K-00001-of-00003.gguf" && models[0].count == 3 && models[0].files.size() == 2 && !models[0].complete() && models[0].bytes == 300 && models[0].files[0].bytes == 100, "hf: a split set is listed by its first shard, in shard order, with the shards it has"); check(models[1].name == "Qwen3.6-35B-A3B-Q4_K_M.gguf" && models[1].quant == "Q4_K_M" && models[1].complete() && models[1].bytes == 20419565568ull, "hf: a lone file is a complete model of one"); std::vector none; check(!parse_hf_tree(json{{"error", "Repository not found"}}, none, err) && err == "Repository not found" && none.empty(), "hf: the site's error object is the reason, and the listing is empty"); check(hf_tree_url("https://huggingface.co", r) == "https://huggingface.co/api/models/a/b/tree/v2?recursive=true", "hf: the listing URL"); check(hf_search_url("https://huggingface.co", "gemma 4 26B/it", 20) == "https://huggingface.co/api/" "models?search=gemma%204%2026B%2Fit&filter=gguf&sort=downloads&direction=-1&limit=20" "&expand%5B%5D=downloads&expand%5B%5D=likes&expand%5B%5D=lastModified&expand%5B%5D=gated", "hf: the search URL, the query percent-encoded and every field a hit carries asked for"); std::vector hits; check(parse_hf_search(json::parse(R"([ {"id":"unsloth/gemma-4-26B-A4B-it-GGUF","downloads":886490,"likes":1224,"lastModified":"2026-10-01T00:00:00.000Z","gated":false}, {"id":"google/gemma-4-26B-A4B-it-qat-q4_0-gguf","downloads":229421,"likes":194,"gated":"auto"}, {"id":"bad id with spaces","downloads":1}, {"downloads":5} ])"), hits, err) && hits.size() == 2 && hits[0].id == "unsloth/gemma-4-26B-A4B-it-GGUF" && hits[0].downloads == 886490 && hits[0].likes == 1224 && !hits[0].gated && hits[1].gated && hits[0].modified.rfind("2026-10-01", 0) == 0, "hf: a search answer's repositories, a gated one marked, an invalid id and a nameless entry dropped"); check(!parse_hf_search(json{{"error", "Bad request"}}, hits, err) && err == "Bad request", "hf: the site's search error"); HfRef g; parse_hf_ref("ggml-org/gemma-4-26B-A4B-it-GGUF", g, err); const CatalogEntry e = hf_catalog_entry("https://huggingface.co", g, models[1]); check(e.id == "hf:ggml-org/gemma-4-26B-A4B-it-GGUF/Qwen3.6-35B-A3B-Q4_K_M.gguf" && e.title == "Qwen3.6-35B-A3B-Q4_K_M" && e.quant == "Q4_K_M" && e.files.size() == 1 && e.files[0].name == "Qwen3.6-35B-A3B-Q4_K_M.gguf" && e.files[0].url == "https://huggingface.co/ggml-org/gemma-4-26B-A4B-it-GGUF/resolve/main/" "Qwen3.6-35B-A3B-Q4_K_M.gguf?download=true" && e.files[0].bytes == 20419565568ull && is_hf_catalog_id(e.id), "hf: the catalog entry a model becomes"); const CatalogEntry split = hf_catalog_entry("https://mirror.example", g, models[0]); check(split.files.size() == 2 && split.files[1].name == "big-Q2_K-00002-of-00003.gguf" && split.files[1].url == "https://mirror.example/ggml-org/gemma-4-26B-A4B-it-GGUF/resolve/main/Q2_K/" "big-Q2_K-00002-of-00003.gguf?download=true", "hf: shards keep their names and their folder in the URL, on the endpoint given"); FitInputs in; in.file_bytes = 10ull << 30; in.disk_free = 4ull << 30; in.readable = true; in.is_moe = true; in.streamable = true; in.dense_bytes = 1ull << 30; in.token_cycle = 512ull << 20; in.budget = 6ull << 30; FitVerdict v = fit_verdict(in); check(!v.downloadable && v.disk.find("6144 MiB short") != std::string::npos && v.mode == "streams", "hf: a disk too small is the one thing that refuses the download, and says by how much"); in.disk_free = 40ull << 30; in.present_bytes = 2ull << 30; v = fit_verdict(in); check(v.downloadable && v.disk.find("needs 8192 MiB") != std::string::npos && v.memory.find("fits in the 6144 MiB") != std::string::npos, "hf: what is already on disk is not downloaded again, and the floor against the budget"); in.budget = 1ull << 30; check(fit_verdict(in).memory.find("more than the 1024 MiB") != std::string::npos, "hf: a floor past the budget says so"); in.is_moe = false; in.streamable = false; check(fit_verdict(in).mode == "plain mmap", "hf: a dense model runs as plain mmap"); in.is_moe = true; in.refusal = "layer 1 names {ffn_up_exps} where layer 0 names more"; v = fit_verdict(in); check(v.mode == "plain mmap" && v.memory.find(in.refusal) != std::string::npos, "hf: a refused MoE carries the reason"); in.readable = false; check(fit_verdict(in).mode == "not readable", "hf: an unreadable header is a fact, not a guess"); in.readable = true; in.refusal.clear(); in.role = "projector"; v = fit_verdict(in); check(v.mode == "not a model" && !v.downloadable && v.memory.find("projector") != std::string::npos, "hf: a projector is not a model, and is not offered for download"); in.role = "draft"; check(fit_verdict(in).mode == "not a model" && fit_verdict(in).memory.find("draft") != std::string::npos, "hf: nor is a draft head"); in.role = "other"; check(fit_verdict(in).mode == "not a model", "hf: nor a file with no transformer blocks"); // The model loaded now is given back: loading this one unloads it first (#285). The figures are // the measured case: 450 MiB free with a session holding ~8.6 GB, 9323 MiB once it was unloaded. in.role = "model"; in.is_moe = true; in.streamable = true; in.disk_free = 40ull << 30; in.file_bytes = 14ull << 30; in.dense_bytes = 2ull << 30; in.token_cycle = 600ull << 20; in.budget = 450ull << 20; v = fit_verdict(in); check(v.memory.find("more than the 450 MiB") != std::string::npos && v.budget == (450ull << 20), "hf: with nothing loaded, the budget is what is free now"); in.session_model = "Qwen3.6-35B-A3B-Q4_K_M.gguf"; v = fit_verdict(in); check(v.budget == (450ull << 20) && v.memory.find("measured with Qwen3.6-35B-A3B-Q4_K_M.gguf loaded") != std::string::npos, "hf: a session with no ledger cannot be given back, and the verdict says the figure is with it loaded"); in.session_held = 8873ull << 20; v = fit_verdict(in); check(v.budget == (9323ull << 20) && v.memory.find("fits in the 9323 MiB") != std::string::npos && v.memory.find("8873 MiB of it held now by Qwen3.6-35B-A3B-Q4_K_M.gguf") != std::string::npos, "hf: the session's ledger is given back, and the verdict says how much and by whom"); in.memory_total = 8ull << 30; check(fit_verdict(in).budget == (8ull << 30), "hf: never more than the machine has"); in.is_moe = false; in.streamable = false; check(fit_verdict(in).memory.find("held now by") != std::string::npos, "hf: a dense model's verdict is given the same budget"); } // A synthetic machine and plan: the view is pure, so it is driven with the facts alone. static ComputeDevice device(const char * name, bool cpu = false) { ComputeDevice d; d.name = name; d.is_cpu = cpu; return d; } static const json * device_named(const json & view, const std::string & name) { for (const json & d : view["devices"]) if (d.value("name", "") == name) return &d; return nullptr; } static void plan_view_tests() { // A phone: the NPU is armed for the prompt, a GPU is slower, another gave the wrong results, // one did not survive its probe, and the device slots take turns with the cache. HardwareProfile hw; hw.backends_looked = true; hw.backends_placeable = 3; hw.host_wide_matmul_gibs = 30; hw.host_bandwidth_gibs = 30; hw.devices.push_back(device("CPU", true)); ComputeDevice npu = device("NPU0"); npu.wide_matmul_gibs = 1200; npu.wide_identity_ok = Tri::Yes; hw.devices.push_back(npu); ComputeDevice gpu = device("GPU0"); gpu.wide_matmul_gibs = 180; gpu.wide_identity_ok = Tri::Yes; hw.devices.push_back(gpu); ComputeDevice wrong = device("GPU1"); wrong.wide_matmul_gibs = 300; wrong.wide_identity_ok = Tri::No; hw.devices.push_back(wrong); ComputeDevice dead = device("GPU2"); dead.usable = Tri::No; dead.unusable_reason = "the probe ended without an answer"; hw.devices.push_back(dead); ModelProfile model; model.expert_bytes = 10ull << 30; Plan plan; plan.regime = Regime::ExpertsStream; plan.config.prefill.device = "NPU0"; plan.allocation.cache_bytes = 2ull << 30; plan.allocation.seconds_per_token = 0.3; plan.allocation.ledger.holdable_cap = 5ull << 30; plan.allocation.ledger.rows = {{"dense", 1ull << 30, true, false}, {"expert cache", 2ull << 30, true, false}, {"device slots", 1ull << 29, true, true}}; json v = plan_view(hw, model, plan); check(v["summary"]["sentence"] == "Experts stream from flash, with a 2.0 GiB cache.", "plan view: the sentence"); check(v["summary"]["lanes"][0]["on"] == json::array({"NPU0"}) && v["summary"]["lanes"][0]["label"] == "Prompt", "plan view: the prompt lane names the armed device"); check(v["summary"]["lanes"][1]["on"] == json::array({"CPU"}), "plan view: tokens stay on the host"); check(v["predicted"]["s_per_token"] == 0.3 && v["predicted"]["cache_hit_pct"] == 20.0, "plan view: the prediction the CLI prints"); const json * c = device_named(v, "CPU"); check(c && (*c)["uses"] == json::array({"tokens"}) && (*c)["badge"] == "Tokens" && (*c)["rate_text"] == "The reference", "plan view: the host decodes, the prompt went to a device"); const json * n = device_named(v, "NPU0"); check(n && (*n)["status"] == "used" && (*n)["badge"] == "Prompt" && (*n)["rate_text"] == "40x the host on a prompt", "plan view: the armed device, with its rate"); const json * g = device_named(v, "GPU0"); check(g && (*g)["status"] == "unused" && (*g)["badge"] == "Not used" && (*g)["why"].get().find("NPU0") != std::string::npos, "plan view: a slower device says which one was armed"); const json * w = device_named(v, "GPU1"); check(w && (*w)["status"] == "refused" && (*w)["badge"] == "Wrong results", "plan view: wrong results refuse"); const json * d = device_named(v, "GPU2"); check(d && (*d)["status"] == "unusable" && (*d)["why"] == "the probe ended without an answer", "plan view: a device that died says why"); check(v["devices_none"] == "" && v["devices_none_text"] == "", "plan view: devices, so no none line"); const json & pools = v["memory"]["pools"]; check(pools.size() == 1 && pools[0]["label"] == "This process" && pools[0]["rows"].size() == 3 && pools[0]["rows"][1]["label"] == "Expert cache" && pools[0]["rows"][2]["in_turn"] == true, "plan view: one pool, the ledger rows worded, the slots in turn"); check(pools[0]["lockable_cap_known"] == true && pools[0]["cache_lock_unverified"] == false, "plan view: a measured lock ceiling retains its known status"); Plan unknown_lock = plan; unknown_lock.allocation.ledger.lockable_cap_known = false; unknown_lock.allocation.cache_lock_unverified = true; const json uncertain_memory = plan_view(hw, model, unknown_lock)["memory"]["pools"][0]; check(uncertain_memory["lockable_cap_known"] == false && uncertain_memory["cache_lock_unverified"] == true && uncertain_memory["cap_bytes"] == pools[0]["cap_bytes"], "plan view: an unmeasured lock ceiling and pending grant stay distinct from process capacity"); // The same view on a desktop whose card holds layers in memory of its own: a second pool, and // the card on the tokens lane beside the host. HardwareProfile desk; desk.backends_looked = true; desk.devices.push_back(device("CPU", true)); ComputeDevice card = device("CUDA0"); card.shares_host_memory = Tri::No; card.memory_total = 12ull << 30; desk.devices.push_back(card); Plan dp; dp.regime = Regime::ExpertsStream; dp.placement.fitted = true; dp.placement.device_bytes = 9ull << 30; dp.placement.device_compute_bytes = 1ull << 30; dp.placement.projected_devices = {"CUDA0"}; dp.placement.projected_compute_bytes = {1ull << 30}; v = plan_view(desk, model, dp); check(v["memory"]["pools"].size() == 2 && v["memory"]["pools"][1]["name"] == "CUDA0" && v["memory"]["pools"][1]["rows"][0]["bytes"] == (8ull << 30) && v["memory"]["pools"][1]["estimated"] == false, "plan view: a device's own memory is its own pool"); check(v["summary"]["lanes"][1]["on"] == json::array({"CPU", "CUDA0"}), "plan view: layers put the card on tokens"); check((*device_named(v, "CUDA0"))["badge"] == "Layers", "plan view: the card's badge"); dp.placement.shared_memory_placement = true; v = plan_view(desk, model, dp); check(v["memory"]["pools"].size() == 1, "plan view: a declined placement holds nothing on the device"); // The cores alone: three answers to "no device", kept apart. HardwareProfile cpu; cpu.devices.push_back(device("CPU", true)); check(plan_view(cpu, model, Plan{})["devices_none"] == "not_probed", "plan view: nobody looked"); cpu.backends_looked = true; check(plan_view(cpu, model, Plan{})["devices_none"] == "build", "plan view: the build carries no backend"); cpu.backends_placeable = 1; json cv = plan_view(cpu, model, Plan{}); check(cv["devices_none"] == "machine" && !cv["devices_none_text"].get().empty(), "plan view: a backend found nothing here"); check(plan_view(cpu, model, Plan{})["summary"]["sentence"] == "The model could not be read.", "plan view: an unread model says so"); // Decisions: who decided, and what. Decision dec{"cache-mb", "2048", Source::Measured, "r"}; json dj = decision_json(dec); check(dj["group"] == "set" && !dj["label"].get().empty(), "plan view: a decided setting, labelled"); dec.source = Source::Operator; check(decision_json(dec)["group"] == "kept", "plan view: the person's value is kept"); dec.source = Source::Unprobed; check(decision_json(dec)["group"] == "kept", "plan view: an unmeasured value is kept"); check(value_text(Decision{"cache-mb", "4737", Source::Derived, "r", "b"}) == "4.6 GiB" && value_text(Decision{"dense-weights", "ahwb", Source::Derived, "r", "b"}) == "pinned in memory" && value_text(Decision{"o-direct", "true", Source::Measured, "r", "b"}) == "on" && value_text(Decision{"memory-ledger", "7265 MiB", Source::Derived, "r", "b"}) == "7.1 GiB" && value_text(Decision{"regime", "experts-stream", Source::Derived, "r", "b"}) == "experts stream" && value_text(Decision{"shared-memory", "-", Source::Derived, "r", "b"}).empty(), "plan view: a value as a person reads it"); check(decision_json(Decision{"storage-rate", "6.3 GiB/s", Source::Derived, "r", "b"})["group"] == "notes", "plan view: a cost model's note is a note"); check(decision_json(Decision{"regime", "experts-stream", Source::Derived, "r"})["label"] == "Streaming mode", "plan view: a note is titled by its topic"); check(decision_json(Decision{"some-new-topic", "-", Source::Derived, "r"})["label"] == "Some new topic", "plan view: a topic it does not know is titled from its key"); check(decision_json(Decision{"regime", "-", Source::Derived, "the reason"})["brief"] == "the reason", "plan view: a decision without a brief shows its reason"); // A real plan, through the wire form: every line says itself in one sentence, and every note has a // name to be read under. { ModelProfile m; m.arch = "qwen3moe"; m.is_moe = m.ok = true; m.n_layer = m.n_moe_layer = 48; m.n_expert = 256; m.n_expert_used = 8; m.n_expert_projections = 3; m.expert_slice_bytes = 530432; m.token_cycle_bytes = 48ull * 8 * 3 * 530432; m.file_bytes = 21ull << 30; m.expert_bytes = 18ull << 30; m.dense_bytes = 3ull << 30; m.largest_dense_tensor = 243ull << 20; m.group(WeightGroup::Attention) = {1400ull << 20, 1400ull << 20, false, false}; m.group(WeightGroup::Output) = {700ull << 20, 700ull << 20, false, false}; m.group(WeightGroup::Experts) = {18ull << 30, m.token_cycle_bytes, false, true}; HardwareProfile h; h.residency_budget = 12ull << 30; h.memory_total = 16ull << 30; h.anon_overflow = Overflow::Compress; h.host_bandwidth_gibs = 60; h.storage.direct_ok = Tri::Yes; h.storage.refault_mibs = 40; h.storage.rate_curve = {{576u << 10, 1, 1600.0}, {576u << 10, 4, 6400.0}}; h.devices.push_back(device("CPU", true)); ComputeDevice gpu = device("GPU0"); gpu.shares_host_memory = Tri::Yes; h.devices.push_back(gpu); const Plan p = plan_run(RunConfig{}, h, m, PlanRequest{}); bool briefs = !p.decisions.empty(), labels = true, any_note = false; std::string bad; for (const Decision & d : p.decisions) { const json j = decision_json(d); const std::string brief = j["brief"]; if (d.brief.empty() || brief.size() > 120) briefs = false, bad += d.knob + " "; if (j["group"] == "notes") { any_note = true; if (j["label"].get().empty()) labels = false, bad += d.knob + " "; } } check(briefs, "plan view: every decision of a plan has a brief of one line" + (bad.empty() ? "" : ": " + bad)); check(any_note && labels, "plan view: every note of a plan has a label" + (bad.empty() ? "" : ": " + bad)); } check(plan_step_label("rules") == "Decisions" && plan_step_label("future") == "Future", "plan view: stage words, and a stage it does not know"); } static void download_tests() { namespace fs = std::filesystem; check(is_transient_curl_exit(18) && is_transient_curl_exit(56) && is_transient_curl_exit(7) && is_transient_curl_exit(28), "downloads: a short body, a reset, a refused connection and a stall are retried"); check(!is_transient_curl_exit(0) && !is_transient_curl_exit(22) && !is_transient_curl_exit(23) && !is_transient_curl_exit(33), "downloads: an HTTP error, a write error (full disk) and a refused range are not"); check(download_retry_delay(1) == kDownloadRetryFirstDelay && download_retry_delay(2) == 2 * kDownloadRetryFirstDelay, "downloads: the wait doubles after each failed attempt"); check(download_retry_delay(1000) == kDownloadRetryMaxDelay, "downloads: and stops at its cap"); bool rising = true; for (int i = 2; i <= kDownloadMaxAttempts; ++i) rising = rising && download_retry_delay(i) >= download_retry_delay(i - 1); check(rising, "downloads: never shorter than the one before"); check(bytes_still_needed(47, 33) == 14 && bytes_still_needed(10, 12) == 0, "downloads: a resume needs only what the partial file lacks"); check(free_space_refusal(14'000'000'000ull, 20'000'000'000ull).empty(), "downloads: 14 GB still to fetch fits in 20 GB free, whatever the whole model weighs"); const std::string no = free_space_refusal(14'000'000'000ull, 3'000'000'000ull); check(no == "needs 14.0 GB more, only 3.0 GB free", "downloads: and a disk too small says by how much: " + no); check(free_space_refusal(14'000'000'000ull, 0).empty(), "downloads: unknown free space refuses nothing"); const fs::path dir = fs::temp_directory_path() / ("bmoe-dl-test-" + std::to_string(std::rand())); const fs::path models = dir / "models"; fs::create_directories(models); const auto write = [](const fs::path & p, const char * s) { std::FILE * f = std::fopen(p.u8string().c_str(), "wb"); if (!f) return; std::fputs(s, f); std::fclose(f); }; std::string out; check(partial_file_path(models.u8string(), "m.gguf", out) && fs::u8path(out) == models / "m.gguf.part", "downloads: a file's partial is .part in the models folder"); for (const char * bad : {"../m.gguf", "a/b.gguf", "a\\b.gguf", "..", ".", "", "C:m.gguf"}) check(!partial_file_path(models.u8string(), bad, out), std::string("downloads: '") + bad + "' names no partial"); write(models / "a.gguf.part", "12345"); write(models / "b.gguf.part", "678"); write(models / "a.gguf", "whole"); write(dir / "outside.part", "keep"); uint64_t freed = 0; std::string err; check(delete_partial_files(models.u8string(), {"a.gguf", "b.gguf", "absent.gguf"}, freed, err) && freed == 8 && !fs::exists(models / "a.gguf.part") && !fs::exists(models / "b.gguf.part"), "downloads: deleting a partial download removes its .part files, a missing one included"); check(fs::exists(models / "a.gguf"), "downloads: and never the finished file beside them"); check(!delete_partial_files(models.u8string(), {"../outside"}, freed, err) && !err.empty() && fs::exists(dir / "outside.part"), "downloads: a name that walks out of the models folder deletes nothing"); write(models / "ok.gguf.part", "x"); check(!delete_partial_files(models.u8string(), {"ok.gguf", "../outside"}, freed, err) && fs::exists(models / "ok.gguf.part") && fs::exists(dir / "outside.part"), "downloads: one bad name refuses the whole request before anything is deleted"); std::error_code ec; fs::create_symlink(dir / "outside.part", models / "link.gguf.part", ec); if (!ec) check(delete_partial_files(models.u8string(), {"link.gguf"}, freed, err) && fs::exists(dir / "outside.part") && !fs::exists(fs::symlink_status(models / "link.gguf.part")), "downloads: a link named like a partial is removed as the link, its target kept"); check(gb_label(47'000'000'000ull) == "47.0 GB", "downloads: sizes are decimal GB, as the Android app writes them"); fs::remove_all(dir, ec); } int main() { protocol_tests(); queue_tests(); settings_tests(); planning_config_tests(); json_tests(); access_tests(); file_tests(); decide_tests(); model_files_tests(); hf_tests(); plan_view_tests(); download_tests(); if (failures) { std::printf("\n%d check(s) FAILED\n", failures); return 1; } std::printf("\nall server policy checks passed\n"); return 0; }