Pudu programming language
Menu
Package

@chrismichaelps / pudu-lang-resilience

Resilience pipelines for Pudu: retry, circuit breaker, timeout, fallback, hedging, rate limiting, and chaos injection

0.1.0Apache-2.01

InstallClose

ContextTest.pudu

Pudu66 lines3.8 KB

GitHub ↗
1/** @Test.Context.Suite — keys, typed properties, forks, and cancellation */2module PuduLangResilience.ContextTest34import Std.Concurrent.Cancel as Cancel5import Std.Io as Io6import Std.Test as Test7import PuduLangResilience.Context as Context8import PuduLangResilience as Resilience910/// Runs the suite.11fn main() -> Int {12  let context = Context.keyed("orders")13  let attempts = Context.intKey("attempts")14  let region = Context.textKey("region")15  let cached = Context.boolKey("cached")16  let point = Context.key("point", fn(value: (Int, Int)) -> Str { show(value[0]) + "," + show(value[1]) }, fn(_text: Str) -> Option[(Int, Int)] { None })17  Context.set(&context, &attempts, -3)18  Context.set(&context, &region, "eu")19  Context.set(&context, &cached, false)20  Context.set(&context, &point, (1, 2))21  let shared = Context.withToken(&context, Cancel.token())22  Context.set(&shared, &region, "us")23  let seenThroughOriginal = Context.get(&context, &region)24  let forked = Context.fork(&context, Cancel.token())25  Context.set(&forked, &region, "ap")26  Context.set(&forked, &Context.textKey("forked-only"), "yes")27  let beforeAdopt = Context.get(&context, &Context.textKey("forked-only"))28  Context.adopt(&context, &forked)29  Context.remove(&context, &cached)30  let flagged = Context.create()31  Context.set(&flagged, &Context.textKey("cached"), "maybe")32  let stopping = Context.create()33  let beforeCancel: Result[(), Resilience.Failure[Str]] = Context.check(&stopping)34  Context.cancel(&stopping, "done")35  Context.cancel(&stopping, "later")36  let afterCancel: Result[(), Resilience.Failure[Str]] = Context.check(&stopping)37  let paused: Result[(), Resilience.Failure[Str]] = Context.pause(&stopping, 1000)38  let quick: Result[(), Resilience.Failure[Str]] = Context.pause(&Context.create(), 1)39  let checks = Test.suite("Context", &[40      Test.equals("a keyed context names its operation", &context.operationKey, &Some("orders")),41      Test.equals("a fresh context names no operation", &Context.create().operationKey, &None),42      Test.equals("a whole number reads back", &Context.get(&context, &attempts), &Some(-3)),43      Test.equals("a false flag reads back before removal", &Context.get(&flagged, &cached), &None),44      Test.equals("a value that does not decode reads as absent", &Context.get(&context, &point), &None),45      Test.that("an undecodable value is still stored", Context.has(&context, &point)),46      Test.equals("getOr falls back for an absent key", &Context.getOr(&context, &Context.intKey("missing"), 7), &7),47      Test.equals("a context with another token shares properties", &seenThroughOriginal, &Some("us")),48      Test.equals("a fork starts from a copy", &Context.get(&forked, &attempts), &Some(-3)),49      Test.equals("a fork's changes stay in the fork", &beforeAdopt, &None),50      Test.equals("adopting copies the fork's properties", &(Context.get(&context, &region), Context.get(&context, &Context.textKey("forked-only"))), &(Some("ap"), Some("yes"))),51      Test.not("a removed property is gone", Context.has(&context, &cached)),52      Test.equals("every stored name is listed", &Context.names(&context), &["attempts", "forked-only", "point", "region"]),53      Test.equals("a context whose token has not fired checks out", &beforeCancel, &Ok(())),54      Test.that("a cancelled context is stopped", Context.stopped(&stopping)),55      Test.equals("the first cancellation reason is kept", &afterCancel, &Err(Resilience.Cancelled("cancelled: done"))),56      Test.equals("a pause on a cancelled context ends at once", &paused, &Err(Resilience.Cancelled("cancelled: done"))),57      Test.equals("a short pause completes", &quick, &Ok(())),58      Test.equals("a cancellable context observes its token", &Context.stopped(&Context.cancellable(Cancel.expiring(0))), &true)59    ])60  let ran = Test.run(&checks)61  for failure in Test.failuresOf(&ran) {62    let _reported = Io.writeErrorLine(failure)63  }64  Test.report(&ran)65}66