#include "testlib.h" RENDER(Request& context) { if(!test_demo_request_allowed(context)) { site_tests_restricted(context, "Tasks", "spawn and inspect background worker processes"); return; } u64 passed = 0; u64 failed = 0; u64 skipped = 0; auto check = [&](String name, bool ok, String detail) { site_tests_case(name, ok ? "pass" : "fail", detail); if(ok) passed++; else failed++; }; String mode = first(context.get["mode"], "run"); pid_t repeat_existing = task_pid("site-tests-repeat"); if(mode == "stop" && repeat_existing != 0) task_kill(repeat_existing, 15); pid_t short_pid = 0; pid_t repeat_pid = 0; if(mode != "stop") { short_pid = task("site-tests-short", []() { sleep(5); }); repeat_pid = task_repeat("site-tests-repeat", 1.0, []() { file_put_contents("/tmp/uce-site-tests-repeat.txt", time_format_utc("%Y-%m-%d %H:%M:%S")); }, 4); } pid_t timeout_pid = 0; pid_t unsafe_key_pid = 0; if(mode != "stop") { timeout_pid = task("site-tests-timeout", []() { sleep(5); }, 1); unsafe_key_pid = task("site-tests/../unsafe key", []() { sleep(5); }); sleep(2); } pid_t seen_short_pid = task_pid("site-tests-short"); pid_t seen_repeat_pid = task_pid("site-tests-repeat"); pid_t seen_timeout_pid = task_pid("site-tests-timeout"); pid_t seen_unsafe_key_pid = task_pid("site-tests/../unsafe key"); int short_alive = seen_short_pid == 0 ? -1 : task_kill(seen_short_pid, 0); int repeat_alive = seen_repeat_pid == 0 ? -1 : task_kill(seen_repeat_pid, 0); site_tests_page_start("Tasks", "Local-only checks for one-shot and repeating background task helpers."); if(mode == "stop") { site_tests_case("repeat worker stop request", "skip", "stop mode requested; no new tasks were started on this request"); skipped++; } else { check("task()", short_pid != 0 && seen_short_pid != 0, "started=" + std::to_string(short_pid) + " seen=" + std::to_string(seen_short_pid)); check("task_pid() + task_kill(pid, 0)", short_alive == 0, "kill(0) result=" + std::to_string(short_alive)); check("task_repeat()", repeat_pid != 0 && seen_repeat_pid != 0, "started=" + std::to_string(repeat_pid) + " seen=" + std::to_string(seen_repeat_pid)); check("repeat worker liveness", repeat_alive == 0, "kill(0) result=" + std::to_string(repeat_alive)); check("task() timeout", timeout_pid != 0 && seen_timeout_pid == 0, "started=" + std::to_string(timeout_pid) + " seen_after_timeout=" + std::to_string(seen_timeout_pid)); check("task key normalization", unsafe_key_pid != 0 && seen_unsafe_key_pid != 0, "started=" + std::to_string(unsafe_key_pid) + " seen=" + std::to_string(seen_unsafe_key_pid)); check("task_kill() rejects negative pid", task_kill(-1, 0) == -1, "kill(-1, 0) rejected"); } ?>
site_tests_summary(passed, failed, skipped, "The repeat worker writes its heartbeat to /tmp/uce-site-tests-repeat.txt and is bounded by a short timeout."); site_tests_page_end(); }