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

PredicateTest.pudu

Pudu45 lines3.4 KB

GitHub ↗
1/** @Test.Predicate.Suite — which outcomes each predicate handles */2module PuduLangResilience.PredicateTest34import Std.Io as Io5import Std.Test as Test6import PuduLangResilience.Context as Context7import PuduLangResilience.Predicate as Predicate8import PuduLangResilience as Resilience910/// Whether `test` handles each of a fixed set of outcomes, in order.11fn verdicts(test: Predicate.Predicate[Int, Str]) -> Array[Bool] {12  let outcomes: Array[Resilience.Outcome[Int, Str]] = [13    Ok(200), Ok(503), Err(Resilience.Raised("transient")), Err(Resilience.Raised("fatal")), Err(Resilience.TimedOut(10)),14    Err(Resilience.BrokenCircuit(5)), Err(Resilience.IsolatedCircuit), Err(Resilience.RateLimited(None)), Err(Resilience.Cancelled("x")), Err(Resilience.Crashed("y"))15  ]16  let context = Context.create()17  outcomes.map(|outcome: Resilience.Outcome[Int, Str]| Predicate.handles(&test, &Predicate.arguments(outcome, context, 0)))18}1920/// Runs the suite.21fn main() -> Int {22  let combined = Predicate.anyOf(&[Predicate.result(503), Predicate.raised(|problem: Str| problem == "transient")])23  let noneOf: Array[Predicate.Predicate[Int, Str]] = []24  let checks = Test.suite("Predicate", &[25      Test.equals("failures handles everything but values and cancellation", &verdicts(Predicate.failures()), &[false, false, true, true, true, true, true, true, false, true]),26      Test.equals("raised handles the accepted errors", &verdicts(Predicate.raised(|problem: Str| problem == "transient")), &[false, false, true, false, false, false, false, false, false, false]),27      Test.equals("anyRaised handles every callback error", &verdicts(Predicate.anyRaised()), &[false, false, true, true, false, false, false, false, false, false]),28      Test.equals("results handles the accepted values", &verdicts(Predicate.results(|status: Int| status >= 500)), &[false, true, false, false, false, false, false, false, false, false]),29      Test.equals("result handles an equal value", &verdicts(Predicate.result(200)), &[true, false, false, false, false, false, false, false, false, false]),30      Test.equals("failure handles the accepted failures", &verdicts(Predicate.failure(|found: Resilience.Failure[Str]| Resilience.isCancellation(&found))), &[false, false, false, false, false, false, false, false, true, false]),31      Test.equals("timeouts handles timeouts", &verdicts(Predicate.timeouts()), &[false, false, false, false, true, false, false, false, false, false]),32      Test.equals("brokenCircuits handles open and isolated circuits", &verdicts(Predicate.brokenCircuits()), &[false, false, false, false, false, true, true, false, false, false]),33      Test.equals("rateLimited handles rate limiting", &verdicts(Predicate.rateLimited()), &[false, false, false, false, false, false, false, true, false, false]),34      Test.equals("anyOf handles what any part handles", &verdicts(combined), &[false, true, true, false, false, false, false, false, false, false]),35      Test.equals("anyOf of nothing handles nothing", &verdicts(Predicate.anyOf(&noneOf)), &[false, false, false, false, false, false, false, false, false, false]),36      Test.equals("never handles nothing", &verdicts(Predicate.never()), &[false, false, false, false, false, false, false, false, false, false]),37      Test.equals("arguments carry the attempt", &Predicate.arguments(Ok(1), Context.create(), 4).attempt, &4)38    ])39  let ran = Test.run(&checks)40  for failure in Test.failuresOf(&ran) {41    let _reported = Io.writeErrorLine(failure)42  }43  Test.report(&ran)44}45