
TimingTest.pudu
Pudu63 lines3.5 KB
1/** @Test.Timing.Suite — timed operations and their outcomes */2module PuduLangLog.TimingTest34import Std.Io as Io5import Std.Sync as Sync6import Std.Test as Test7import PuduLangLog.Configuration as Configuration8import PuduLangLog.Event as Event9import PuduLangLog.Failure as Failure10import PuduLangLog as Log11import PuduLangLog.Sinks.Memory as Memory12import PuduLangLog.Timing as Timing13import PuduLangLog.Value as Value141516fn tens() -> fn() -> Int {17 let next = Sync.counter(-10)18 fn() -> Int {19 match Sync.increment(&next, 10) {20 case Ok(value) => value21 case Err(_) => 022 }23 }24}252627fn main() -> Int {28 let memory = Memory.create()29 let logger = Configuration.create().minimumLevel(Log.Verbose).writeTo(Memory.sink(&memory)).createLogger()30 let charging = Timing.beginWith(&logger, "Charging \{OrderId\}", [Value.int(42)], tens()).enrichWith("Gateway", Value.text("card"))31 charging.complete()32 charging.complete()33 Timing.beginWith(&logger, "Shipping", [], tens()).abandon()34 Timing.beginWith(&logger, "Slow", [], tens()).warnAfter(5).complete()35 Timing.beginWith(&logger, "Quick", [], tens()).warnAfter(50).at(Log.Debug, Log.Error).complete()36 Timing.beginWith(&logger, "Counting", [], tens()).completeWith("Rows", Value.int(7))37 Timing.beginWith(&logger, "Ignored", [], tens()).cancel()38 Timing.beginWith(&logger, "Failing", [], tens()).abandonWith(Failure.of("IoError", "gone"))39 let answer = Timing.run(&logger, "Running", [], fn() -> Int { 5 })40 let failed: Result[Int, Str] = Timing.runResult(&logger, "Trying", [], "ParseError", fn() -> Result[Int, Str] { Err("bad") })41 let succeeded: Result[Int, Str] = Timing.runResult(&logger, "Trying", [], "ParseError", fn() -> Result[Int, Str] { Ok(1) })42 let events = Memory.events(&memory)43 let messages = Memory.messages(&memory)44 let checks = Test.suite("Timing", &[45 Test.equals("a completion names its outcome and time", &messages[0], &"Charging 42 completed in 10.0 ms"),46 Test.equals("an operation completes once", &Memory.withTemplate(&memory, "Charging \{OrderId\} \{Outcome:l\} in \{Elapsed:0.0\} ms").length(), &1),47 Test.equals("completion properties", &(Event.property(&events[0], "Outcome"), Event.property(&events[0], "Elapsed"), Event.property(&events[0], "Gateway")), &(Some(Value.text("completed")), Some(Value.float(10.0)), Some(Value.text("card")))),48 Test.equals("levels of each outcome", &events.map(|event: Log.Event| event.level), &[Log.Information, Log.Warning, Log.Warning, Log.Debug, Log.Information, Log.Warning, Log.Information, Log.Warning, Log.Information]),49 Test.equals("an abandonment names its outcome", &messages[1], &"Shipping abandoned in 10.0 ms"),50 Test.equals("a completion with a result", &Event.property(&events[4], "Rows"), &Some(Value.int(7))),51 Test.that("a cancelled operation writes nothing", Memory.withTemplate(&memory, "Ignored \{Outcome:l\} in \{Elapsed:0.0\} ms").isEmpty()),52 Test.equals("an abandonment can carry a failure", &events[5].failure, &Some(Failure.of("IoError", "gone"))),53 Test.equals("running answers the action's value", &answer, &5),54 Test.equals("an error abandons with the error as failure", &(failed, events[7].failure), &(Err("bad"), Some(Failure.of("ParseError", "bad")))),55 Test.equals("success completes", &(succeeded, Event.property(&events[8], "Outcome")), &(Ok(1), Some(Value.text("completed"))))56 ])57 let ran = Test.run(&checks)58 for failure in Test.failuresOf(&ran) {59 let _reported = Io.writeErrorLine(failure)60 }61 Test.report(&ran)62}63