
CircuitTest.pudu
Pudu72 lines5.2 KB
1/** @Test.Domain.Circuit.Suite — health windows and circuit transitions */2module PuduLangResilience.Domain.CircuitTest34import Std.Io as Io5import Std.Test as Test6import PuduLangResilience.Domain.Circuit as Circuit7import PuduLangResilience.Domain.Health as Health8910fn main() -> Int {11 let health = Health.create(1000)12 let recorded = Health.record(&Health.record(&Health.record(&health, 0, true), 50, false), 150, true)13 let later = Health.record(&recorded, 1060, false)14 let single = Health.create(100)15 let thresholds = Circuit.Thresholds{failureRatio: 0.5d, minimumThroughput: 2}16 let start = Circuit.closed(1000)17 let once = Circuit.failed(&start, 0, "a", &thresholds)18 let twice = Circuit.failed(&once[0], 10, "b", &thresholds)19 let opened = Circuit.open(&twice[0], 10, 500)20 let early = Circuit.admit(&opened, 300, 500)21 let probing = Circuit.admit(&opened, 510, 500)22 let second = Circuit.admit(&probing[0], 520, 500)23 let probeFailed = Circuit.failed(&probing[0], 530, "c", &thresholds)24 let probeSucceeded = Circuit.succeeded(&probing[0], 530)25 let isolated = Circuit.isolate(&start)26 let lenient = Circuit.Thresholds{failureRatio: 0.6d, minimumThroughput: 2}27 let afterSuccess = Circuit.succeeded(&start, 0)[0]28 let mixed = Circuit.failed(&afterSuccess, 1, "e", &lenient)29 let failedWhileOpen = Circuit.failed(&opened, 20, "f", &thresholds)30 let checks = Test.suite("Domain.Circuit", &[31 Test.not("successes lower the failure share", mixed[1]),32 Test.equals("a success is counted as one", &Health.info(&mixed[0].health, 1), &Health.Info{throughput: 2, failures: 1}),33 Test.equals("a failure while open is counted", &Health.info(&failedWhileOpen[0].health, 20).failures, &3),34 Test.equals("a period of exactly ten resolutions is split", &Health.create(200).windowLength, &20),35 Test.equals("an outcome exactly one period old is not counted", &Health.info(&Health.record(&health, 0, true), 1000).throughput, &0),36 Test.equals("an outcome a whole window later starts a window", &Health.record(&Health.record(&health, 0, true), 100, true).windows.length(), &2),37 Test.equals("a window exactly one period old is dropped", &Health.record(&Health.record(&health, 0, true), 1000, true).windows.length(), &1),38 Test.equals("a zero period keeps windows of one millisecond", &Health.create(0).windowLength, &1),39 Test.equals("a period of a second is split into tenths", &health.windowLength, &100),40 Test.equals("a period shorter than ten resolutions keeps one window", &single.windowLength, &100),41 Test.equals("outcomes in the period are totalled", &Health.info(&recorded, 150), &Health.Info{throughput: 3, failures: 2}),42 Test.equals("outcomes past the period are dropped", &Health.info(&later, 1060), &Health.Info{throughput: 2, failures: 1}),43 Test.equals("an outcome in the same window joins it", &Health.record(&health, 0, true).windows.length(), &1),44 Test.equals("the failure rate is exact", &Health.failureRate(&Health.Info{throughput: 3, failures: 1}), &0.333333d),45 Test.equals("no throughput is no failure rate", &Health.failureRate(&Health.Info{throughput: 0, failures: 0}), &0d),46 Test.not("the minimum throughput must be reached", Health.shouldBreak(&Health.Info{throughput: 1, failures: 1}, 0.5d, 2)),47 Test.that("the ratio is inclusive", Health.shouldBreak(&Health.Info{throughput: 4, failures: 2}, 0.5d, 2)),48 Test.not("a lower share does not break", Health.shouldBreak(&Health.Info{throughput: 5, failures: 2}, 0.5d, 2)),49 Test.equals("a reset empties the windows", &Health.reset(&recorded).windows, &[]),50 Test.not("one failure below the throughput keeps the circuit closed", once[1]),51 Test.that("the failure meeting the thresholds opens the circuit", twice[1]),52 Test.equals("an open circuit blocks until its deadline", &early[1], &Circuit.Blocked(210)),53 Test.equals("the first execution past the deadline is the probe", &probing[1], &Circuit.Probe),54 Test.equals("a probe counts one half-open attempt", &probing[0].halfOpenAttempts, &1),55 Test.equals("a half-open circuit blocks everything but the probe", &second[1], &Circuit.Blocked(490)),56 Test.that("a failed probe opens again", probeFailed[1]),57 Test.equals("a failed probe is not counted", &Health.info(&probeFailed[0].health, 530).throughput, &2),58 Test.that("a successful probe closes the circuit", probeSucceeded[1] && probeSucceeded[0].phase == Circuit.Closed),59 Test.equals("closing clears the counts and attempts", &(probeSucceeded[0].health.windows, probeSucceeded[0].halfOpenAttempts), &([], 0)),60 Test.equals("an isolated circuit refuses", &Circuit.admit(&isolated, 99999, 500)[1], &Circuit.Refused),61 Test.not("an isolated circuit does not open again on failure", Circuit.failed(&isolated, 0, "d", &thresholds)[1]),62 Test.not("a success in a closed circuit closes nothing", Circuit.succeeded(&start, 0)[1]),63 Test.equals("a negative duration opens until now", &Circuit.open(&start, 40, -5).blockedUntil, &40),64 Test.equals("retry-after is never negative", &Circuit.retryAfter(&opened, 9999), &0)65 ])66 let ran = Test.run(&checks)67 for failure in Test.failuresOf(&ran) {68 let _reported = Io.writeErrorLine(failure)69 }70 Test.report(&ran)71}72