Skip to content

Commit

Permalink
Use simplelog to display unit test output. Also creates a LogLevel en…
Browse files Browse the repository at this point in the history
…um type instead of using u8.
  • Loading branch information
jhodapp committed Dec 22, 2023
1 parent 116074c commit 9125f85
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 26 deletions.
68 changes: 64 additions & 4 deletions service/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use clap::builder::TypedValueParser as _;
use clap::Parser;
use std::fmt;

#[derive(Clone, Parser)]
#[derive(Clone, Debug, Parser)]
#[command(author, version, about, long_about = None)]
pub struct Config {
/// Sets the Postgresql database URI to connect to
Expand All @@ -20,9 +22,15 @@ pub struct Config {
#[arg(short, long, default_value_t = 4000)]
pub port: u16,

/// Turn on different tracing levels [0 = Warn, 1 = Info, 2 = Debug, 3 = Trace]
#[arg(short, long, default_value_t = 0)]
pub trace_level: u8,
/// Turn on log level verbosity threshold to control what gets displayed on console output
#[arg(
short,
long,
default_value_t = LogLevel::Warn,
value_parser = clap::builder::PossibleValuesParser::new(["error", "warn", "info", "debug", "trace"])
.map(|s| s.parse::<LogLevel>().unwrap()),
)]
pub log_level: LogLevel,
}

impl Default for Config {
Expand All @@ -45,3 +53,55 @@ impl Config {
self.database_uri.clone().expect("No Database URI Provided")
}
}

#[derive(Clone, Debug, Default)]
#[repr(u8)]
pub enum LogLevel {
Error = 0,
#[default]
Warn,
Info,
Debug,
Trace,
}

impl From<LogLevel> for u8 {
fn from(trace_level: LogLevel) -> u8 {
match trace_level {
LogLevel::Error => 0,
LogLevel::Warn => 1,
LogLevel::Info => 2,
LogLevel::Debug => 3,
LogLevel::Trace => 4,
}
}
}

impl fmt::Display for LogLevel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let level_string = match self {
LogLevel::Error => "error",
LogLevel::Warn => "warn",
LogLevel::Info => "info",
LogLevel::Debug => "debug",
LogLevel::Trace => "trace",
};

level_string.fmt(f)
}
}

impl std::str::FromStr for LogLevel {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"trace" => Ok(Self::Trace),
"debug" => Ok(Self::Debug),
"info" => Ok(Self::Info),
"warn" => Ok(Self::Warn),
"error" => Ok(Self::Error),
_ => Err(format!("Unknown trace level: {s}")),
}
}
}
53 changes: 31 additions & 22 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@
//! and/or teams by providing a single application that facilitates and enhances
//! your coaching practice.
use service::{config::Config, AppState};
use service::{
config::{Config, LogLevel},
AppState,
};

extern crate simplelog;

Expand All @@ -46,12 +49,12 @@ fn get_config() -> Config {
}

fn init_logger(config: &Config) {
let log_level = match config.trace_level {
0 => simplelog::LevelFilter::Warn,
1 => simplelog::LevelFilter::Info,
2 => simplelog::LevelFilter::Debug,
3 => simplelog::LevelFilter::Trace,
_ => simplelog::LevelFilter::Trace,
let log_level = match config.log_level {
LogLevel::Error => simplelog::LevelFilter::Error,
LogLevel::Warn => simplelog::LevelFilter::Warn,
LogLevel::Info => simplelog::LevelFilter::Info,
LogLevel::Debug => simplelog::LevelFilter::Debug,
LogLevel::Trace => simplelog::LevelFilter::Trace,
};

simplelog::TermLogger::init(
Expand All @@ -65,20 +68,25 @@ fn init_logger(config: &Config) {
simplelog::info!("<b>Starting up...</b>.");
}

// This is the parent test "runner" that initiates all other crate
// unit/integration tests.
#[cfg(test)]
mod all_tests {
use std::io::{self, Write};
use service::config::LogLevel;
use std::process::Command;

#[tokio::test]
async fn main() {
let mut config = super::get_config();
config.log_level = LogLevel::Trace;
super::init_logger(&config);

let mut exit_codes = Vec::new();

for crate_name in crates_to_test().iter() {
let mut command = Command::new("cargo");

io::stdout()
.write_fmt(format_args!("Running Tests for {:?} Crate", crate_name))
.unwrap();
simplelog::info!("<b>Running tests for {:?} crate</b>\r\n", crate_name);

// It may be that we need to map each crate with specific commands at some point
// for now calling "--features mock" for each crate.
Expand All @@ -88,22 +96,23 @@ mod all_tests {

let output = command.output().unwrap();

io::stdout()
.write_fmt(format_args!(
"{:?} Test's Output Status: {}",
crate_name, output.status
))
.unwrap();
match output.status.success() {
true => {
simplelog::info!("<b>All {:?} tests completed successfully.\r\n", crate_name)
}
false => simplelog::error!(
"<b>{:?} tests completed with errors ({})</b>\r\n",
crate_name,
output.status
),
}

io::stdout().write_all(&output.stdout).unwrap();
io::stderr().write_all(&output.stderr).unwrap();
simplelog::info!("{}", String::from_utf8_lossy(output.stdout.as_slice()));

exit_codes.push(output.status.code().unwrap());
}
if exit_codes.iter().any(|code| *code != 0i32) {
io::stdout()
.write_fmt(format_args!("Exit Codes From Tests: {:?}", exit_codes))
.unwrap();
simplelog::error!("** One or more crate tests failed.");
// Will fail CI
std::process::exit(1);
}
Expand Down

0 comments on commit 9125f85

Please sign in to comment.