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

ClockTest.pudu

Pudu64 lines3.2 KB

GitHub ↗
1/** @Test.Clock.Suite — manual and system clocks, and randomizers */2module PuduLangResilience.ClockTest34import Std.Concurrent.Cancel as Cancel5import Std.Io as Io6import Std.Test as Test7import PuduLangResilience.Clock as Clock8import PuduLangResilience.Randomizer as Randomizer910/// `count` draws below `bound`.11fn draws(source: &Randomizer.Randomizer, bound: Int, count: Int) -> Array[Int] {12  var drawn: Array[Int] = []13  while drawn.length() < count { drawn = drawn.push(Randomizer.below(source, bound)) }14  drawn15}1617/// Runs the suite.18fn main() -> Int {19  let manual = Clock.manual(100)20  let clock = Clock.ofManual(&manual)21  let startedAt = Clock.now(&clock)22  let slept = Clock.sleep(&clock, 50, &Cancel.token())23  let negative = Clock.sleep(&clock, -5, &Cancel.token())24  Clock.advance(&manual, 10)25  Clock.advance(&manual, -10)26  let stopped = Cancel.token()27  let _fired = Cancel.cancel(&stopped, "no")28  let refused = Clock.sleep(&clock, 30, &stopped)29  let system = Clock.system()30  let before = Clock.now(&system)31  let systemSlept = Clock.sleep(&system, 5, &Cancel.token())32  let after = Clock.now(&system)33  let seeded = draws(&Randomizer.seeded(42), 100, 20)34  let again = draws(&Randomizer.seeded(42), 100, 20)35  let other = draws(&Randomizer.seeded(-7), 100, 20)36  let live = Randomizer.system()37  let fixedHalf = Randomizer.fixed(0.5d)38  let checks = Test.suite("Clock", &[39      Test.equals("a manual clock starts where told", &startedAt, &100),40      Test.equals("sleeping on a manual clock advances it", &(slept, Clock.now(&clock)), &(Ok(()), 160)),41      Test.equals("a negative sleep is recorded as none", &(negative, Clock.sleeps(&manual)), &(Ok(()), [50, 0])),42      Test.that("a fired token refuses to sleep", match refused { case Err(_) => true case Ok(_) => false }),43      Test.equals("a refused sleep is not recorded", &Clock.sleeps(&manual).length(), &2),44      Test.that("the system clock waits", systemSlept == Ok(()) && after - before >= 5),45      Test.equals("a seed repeats its sequence", &seeded, &again),46      Test.differs("different seeds differ", &seeded, &other),47      Test.all("draws stay below their bound", &draws(&live, 7, 200), |drawn: Int| drawn >= 0 && drawn < 7),48      Test.equals("a bound below one draws zero", &Randomizer.below(&live, 0), &0),49      Test.equals("a fixed ratio draws that share of the bound", &draws(&fixedHalf, 10, 2), &[5, 5]),50      Test.equals("a fixed ratio is clamped", &(Randomizer.below(&Randomizer.fixed(-1d), 10), Randomizer.below(&Randomizer.fixed(2d), 10)), &(0, 9)),51      Test.equals("a fraction is parts of the scale", &Randomizer.fraction(&fixedHalf), &(Randomizer.SCALE / 2)),52      Test.that("a unit draw is a fraction of one", Randomizer.unit(&fixedHalf) == 0.5),53      Test.that("a rate of one always holds", Randomizer.chance(&Randomizer.fixed(0.999999d), 1d)),54      Test.not("a rate of zero never holds", Randomizer.chance(&Randomizer.fixed(0d), 0d)),55      Test.that("a draw below the rate holds", Randomizer.chance(&fixedHalf, 0.500001d)),56      Test.not("a draw at the rate does not hold", Randomizer.chance(&fixedHalf, 0.5d))57    ])58  let ran = Test.run(&checks)59  for failure in Test.failuresOf(&ran) {60    let _reported = Io.writeErrorLine(failure)61  }62  Test.report(&ran)63}64