d4e82d3d56
- vote/merge/reduce/collect convergence proven end-to-end; failure threshold aborts a swarm below min_success_ratio (integer per-mille) and completes when failures are within tolerance, with worker.failed + swarm.aborted tracked durably. - worked around three El runtime/codegen semantics surfaced during the build: json_set inserts RAW (use json_set_str for string values); json_set cannot update an existing key (vote tallies via list rescanning); json_array_get keeps quotes (use json_array_get_string). Also: float division is unreliable (swarm uses integer math), and a let-rebind in a deeply nested if/else does not propagate outward (accumulators kept at one block level). test_convergence: 8/8; test_swarm: 12/12.
56 lines
3.2 KiB
EmacsLisp
56 lines
3.2 KiB
EmacsLisp
// test_convergence.el — convergence strategies + failure threshold / abort.
|
|
|
|
fn assert_true(label: String, cond: Bool, fails: Int) -> Int {
|
|
if cond { print(" ok " + label); return fails }
|
|
print(" FAIL " + label); return fails + 1
|
|
}
|
|
|
|
fn main() -> Int {
|
|
let fails = 0
|
|
let refs: String = "[]"
|
|
|
|
// ── vote: classify 5 inputs; 3 "long" (>4 chars) vs 2 "short" -> winner long ──
|
|
let inputs: String = "[\"alpha\",\"bravo\",\"hi\",\"charlie\",\"ok\"]"
|
|
let cfg_v: String = "{\"concurrency\":\"3\",\"strategy\":\"vote\",\"min_success_ratio\":\"1.0\"}"
|
|
let rv: String = swarm_run("classify", refs, inputs, cfg_v)
|
|
let merged_v: String = json_get_raw(rv, "merged")
|
|
let winner: String = json_get_string(merged_v, "winner")
|
|
let votes: Int = str_to_int(json_get_string(merged_v, "votes"))
|
|
let fails = assert_true("vote winner = long", str_eq(winner, "long"), fails)
|
|
let fails = assert_true("vote count = 3", votes == 3, fails)
|
|
|
|
// ── merge: outputs joined ──
|
|
let cfg_m: String = "{\"concurrency\":\"2\",\"strategy\":\"merge\",\"min_success_ratio\":\"1.0\"}"
|
|
let rm: String = swarm_run("analyze_item", refs, "[\"a\",\"b\",\"c\"]", cfg_m)
|
|
let merged_m: String = json_get_raw(rm, "merged")
|
|
let joined: String = json_get_string(merged_m, "merged")
|
|
let fails = assert_true("merge produced a joined string", str_contains(joined, "|"), fails)
|
|
|
|
// ── reduce: count accumulates ──
|
|
let cfg_r: String = "{\"concurrency\":\"4\",\"strategy\":\"reduce\",\"min_success_ratio\":\"1.0\"}"
|
|
let rr: String = swarm_run("analyze_item", refs, "[\"a\",\"b\",\"c\",\"d\"]", cfg_r)
|
|
let merged_r: String = json_get_raw(rr, "merged")
|
|
let rcount: Int = str_to_int(json_get_string(merged_r, "count"))
|
|
let fails = assert_true("reduce count = 4", rcount == 4, fails)
|
|
|
|
// ── failure threshold: 2 of 5 fail (x-prefixed); ratio 3/5=0.6 < 0.8 -> aborted ──
|
|
let fin: String = "[\"a\",\"xb\",\"c\",\"xd\",\"e\"]"
|
|
let cfg_f: String = "{\"concurrency\":\"5\",\"strategy\":\"collect\",\"min_success_ratio\":\"0.8\"}"
|
|
let rf: String = swarm_run("faildemo", refs, fin, cfg_f)
|
|
let fstatus: String = json_get_string(rf, "status")
|
|
let fails = assert_true("swarm aborted below min_success_ratio (0.6<0.8)", str_eq(fstatus, "aborted"), fails)
|
|
let corr_f: String = json_get_string(rf, "corr_id")
|
|
let failed_n: Int = worktrack_count_kind(corr_f, "worker.failed")
|
|
let aborted_n: Int = worktrack_count_kind(corr_f, "swarm.aborted")
|
|
let fails = assert_true("tracked 2 worker.failed", failed_n == 2, fails)
|
|
let fails = assert_true("tracked swarm.aborted", aborted_n == 1, fails)
|
|
|
|
// ── same failures tolerated when min_success_ratio=0.5 (0.6>=0.5) -> completed ──
|
|
let cfg_ok: String = "{\"concurrency\":\"5\",\"strategy\":\"collect\",\"min_success_ratio\":\"0.5\"}"
|
|
let rok: String = swarm_run("faildemo", refs, fin, cfg_ok)
|
|
let fails = assert_true("swarm completes when failures within tolerance", str_eq(json_get_string(rok, "status"), "completed"), fails)
|
|
|
|
if fails == 0 { print("PASS test_convergence"); return 0 }
|
|
print("FAIL test_convergence (" + int_to_str(fails) + ")"); return 1
|
|
}
|