Files
el/lang/swarm/tests/test_convergence.el
T
bigmerge d4e82d3d56 swarm: convergence strategies + failure threshold, hardened El JSON usage
- 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.
2026-08-14 20:37:35 -05:00

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
}