Next Generation WASM Microkernel Operating System
at main 148 lines 5.3 kB view raw
1// Copyright 2025 Jonas Kruckenberg 2// 3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or 4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or 5// http://opensource.org/licenses/MIT>, at your option. This file may not be 6// copied, modified, or distributed except according to those terms. 7 8use alloc::boxed::Box; 9use core::sync::atomic::Ordering; 10 11use ktest::{Test, TestInfo}; 12 13use super::args::FormatSetting; 14use super::{Conclusion, Outcome}; 15 16pub struct Printer { 17 format: FormatSetting, 18} 19 20impl Printer { 21 pub fn new(format: FormatSetting) -> Self { 22 Self { format } 23 } 24 25 pub(crate) fn print_title(&self, num_tests: u64) { 26 match self.format { 27 FormatSetting::Pretty | FormatSetting::Terse => { 28 let plural_s = if num_tests == 1 { "" } else { "s" }; 29 30 tracing::info!("\nrunning {num_tests} test{plural_s}"); 31 } 32 FormatSetting::Json => tracing::info!( 33 r#"{{ "type": "suite", "event": "started", "test_count": {num_tests} }}"#, 34 ), 35 } 36 } 37 38 pub(crate) fn print_test(&self, info: &TestInfo) { 39 let TestInfo { module, name, .. } = info; 40 match self.format { 41 FormatSetting::Pretty => { 42 tracing::info!("test {module}::{name} ... ",); 43 } 44 FormatSetting::Terse => { 45 // In terse mode, nothing is printed before the job. Only 46 // `print_single_outcome` prints one character. 47 } 48 FormatSetting::Json => { 49 tracing::info!( 50 r#"{{ "type": "test", "event": "started", "name": "{module}::{name}" }}"#, 51 ) 52 } 53 } 54 } 55 56 pub(crate) fn print_single_outcome(&self, info: &TestInfo, outcome: &Outcome) { 57 let TestInfo { module, name, .. } = info; 58 match self.format { 59 FormatSetting::Pretty => { 60 self.print_outcome_pretty(outcome); 61 } 62 FormatSetting::Terse => { 63 let c = match outcome { 64 Outcome::Passed => '.', 65 Outcome::Failed { .. } => 'F', 66 Outcome::Ignored => 'i', 67 }; 68 69 tracing::info!("{c}"); 70 } 71 FormatSetting::Json => { 72 tracing::info!( 73 r#"{{ "type": "test", "name": "{module}::{name}", "event": "{}" }}"#, 74 match outcome { 75 Outcome::Passed => "ok", 76 Outcome::Failed(_) => "failed", 77 Outcome::Ignored => "ignored", 78 } 79 ); 80 } 81 } 82 } 83 84 fn print_outcome_pretty(&self, outcome: &Outcome) { 85 match outcome { 86 Outcome::Passed => tracing::info!("ok"), 87 Outcome::Failed(_) => { 88 tracing::info!("FAILED"); 89 } 90 Outcome::Ignored => tracing::info!("ignored"), 91 } 92 } 93 94 pub(crate) fn print_list(&self, tests: &[Test], ignored: bool) { 95 for test in tests { 96 // libtest prints out: 97 // * all tests without `--ignored` 98 // * just the ignored tests with `--ignored` 99 if ignored && !test.info.ignored { 100 continue; 101 } 102 103 tracing::info!("{}::{}: test", test.info.module, test.info.name,); 104 } 105 } 106 107 pub(crate) fn print_summary(&self, conclusion: &Conclusion) { 108 match self.format { 109 FormatSetting::Pretty | FormatSetting::Terse => { 110 let outcome = if conclusion.has_failed() { 111 Outcome::Failed(Box::new(())) 112 } else { 113 Outcome::Passed 114 }; 115 116 tracing::info!("test result: "); 117 self.print_outcome_pretty(&outcome); 118 tracing::info!( 119 "{} passed; {} failed; {} ignored; {} measured; \ 120 {} filtered out", 121 conclusion.num_passed.load(Ordering::Acquire), 122 conclusion.num_failed.load(Ordering::Acquire), 123 conclusion.num_ignored.load(Ordering::Acquire), 124 conclusion.num_measured.load(Ordering::Acquire), 125 conclusion.num_filtered_out.load(Ordering::Acquire), 126 ); 127 } 128 FormatSetting::Json => { 129 tracing::info!( 130 concat!( 131 r#"{{ "type": "suite", "event": "{}", "passed": {}, "failed": {},"#, 132 r#" "ignored": {}, "measured": {}, "filtered_out": {} }}"#, 133 ), 134 if conclusion.has_failed() { 135 "failed" 136 } else { 137 "ok" 138 }, 139 conclusion.num_passed.load(Ordering::Acquire), 140 conclusion.num_failed.load(Ordering::Acquire), 141 conclusion.num_ignored.load(Ordering::Acquire), 142 conclusion.num_measured.load(Ordering::Acquire), 143 conclusion.num_filtered_out.load(Ordering::Acquire), 144 ) 145 } 146 } 147 } 148}