Skip to content

Commit

Permalink
[rust] Include mixed output (INFO, WARN, DEBUG, etc. to stderr and mi…
Browse files Browse the repository at this point in the history
…nimal JSON to stdout)
  • Loading branch information
bonigarcia committed Jan 9, 2024
1 parent 4b6af2e commit 14ed560
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 20 deletions.
66 changes: 51 additions & 15 deletions rust/src/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
use crate::config::BooleanKey;
use crate::metadata::now_unix_timestamp;
use env_logger::fmt::Color;
use env_logger::Target::Stdout;
use env_logger::Target::{Stderr, Stdout};
use env_logger::DEFAULT_FILTER_ENV;
use log::Level;
use log::LevelFilter::{Debug, Info, Trace};
Expand All @@ -27,7 +27,6 @@ use std::cell::RefCell;
use std::env;
use std::fmt::Display;
use std::io::Write;
use std::ops::Deref;
use Color::{Blue, Cyan, Green, Red, Yellow};

pub const DRIVER_PATH: &str = "Driver path: ";
Expand All @@ -39,6 +38,7 @@ enum OutputType {
Logger,
Json,
Shell,
Mixed,
}

#[derive(Default)]
Expand All @@ -47,6 +47,7 @@ pub struct Logger {
trace: bool,
output: OutputType,
json: RefCell<JsonOutput>,
minimal_json: RefCell<MinimalJson>,
}

#[derive(Default, Serialize, Deserialize)]
Expand All @@ -70,6 +71,12 @@ pub struct JsonOutput {
pub result: Result,
}

#[derive(Default, Serialize, Deserialize)]
pub struct MinimalJson {
pub driver_path: String,
pub browser_path: String,
}

impl Logger {
pub fn new() -> Self {
let debug = BooleanKey("debug", false).get_value();
Expand All @@ -83,11 +90,13 @@ impl Logger {
output_type = OutputType::Json;
} else if output.eq_ignore_ascii_case("shell") {
output_type = OutputType::Shell;
} else if output.eq_ignore_ascii_case("mixed") {
output_type = OutputType::Mixed;
} else {
output_type = OutputType::Logger;
}
match output_type {
OutputType::Logger => {
OutputType::Logger | OutputType::Mixed => {
if env::var(DEFAULT_FILTER_ENV).unwrap_or_default().is_empty() {
let mut filter = match debug {
true => Debug,
Expand All @@ -96,9 +105,14 @@ impl Logger {
if trace {
filter = Trace
}
let target = if output_type == OutputType::Logger {
Stdout
} else {
Stderr
};
env_logger::Builder::new()
.filter_module(env!("CARGO_CRATE_NAME"), filter)
.target(Stdout)
.target(target)
.format(|buf, record| {
let mut level_style = buf.style();
match record.level() {
Expand Down Expand Up @@ -141,6 +155,7 @@ impl Logger {
browser_path: "".to_string(),
},
}),
minimal_json: RefCell::new(Default::default()),
}
}

Expand Down Expand Up @@ -178,12 +193,11 @@ impl Logger {
}
if level == Level::Info || level <= Level::Error {
if message.starts_with(DRIVER_PATH) {
let driver_path = message.replace(DRIVER_PATH, "");
self.json.borrow_mut().result.driver_path = driver_path.to_owned();
self.json.borrow_mut().result.message = driver_path;
self.json.borrow_mut().result.driver_path =
self.clean_driver_path(&message);
} else if message.starts_with(BROWSER_PATH) {
let browser_path = message.replace(BROWSER_PATH, "");
self.json.borrow_mut().result.browser_path = browser_path;
self.json.borrow_mut().result.browser_path =
self.clean_browser_path(&message);
} else {
self.json.borrow_mut().result.message = message;
}
Expand All @@ -197,11 +211,28 @@ impl Logger {
}
}
_ => {
if self.output == OutputType::Mixed && level == Level::Info {
if message.starts_with(DRIVER_PATH) {
self.minimal_json.borrow_mut().driver_path =
self.clean_driver_path(&message);
} else if message.starts_with(BROWSER_PATH) {
self.minimal_json.borrow_mut().browser_path =
self.clean_browser_path(&message);
}
}
log::log!(level, "{}", message);
}
}
}

fn clean_driver_path(&self, message: &str) -> String {
message.replace(DRIVER_PATH, "")
}

fn clean_browser_path(&self, message: &str) -> String {
message.replace(BROWSER_PATH, "")
}

fn create_json_log(&self, message: String, level: Level) -> Logs {
Logs {
level: level.to_string().to_uppercase(),
Expand All @@ -210,17 +241,22 @@ impl Logger {
}
}

fn get_json_blog<T>(&self, json_output: &T) -> String
where
T: Serialize,
{
serde_json::to_string_pretty(json_output).unwrap()
}

pub fn set_code(&self, code: i32) {
self.json.borrow_mut().result.code = code;
}

pub fn flush(&self) {
let json_output = &self.json.borrow();
let json = json_output.deref();
if !json.logs.is_empty() {
print!("{}", serde_json::to_string_pretty(json).unwrap());
} else if self.output == OutputType::Json {
panic!("JSON output has been specified, but no entries have been collected")
if self.output == OutputType::Json {
print!("{}", self.get_json_blog(&self.json));
} else if self.output == OutputType::Mixed {
print!("{}", self.get_json_blog(&self.minimal_json));
}
}
}
3 changes: 2 additions & 1 deletion rust/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ struct Cli {
#[clap(long, value_parser)]
browser_mirror_url: Option<String>,

/// Output type: LOGGER (using INFO, WARN, etc.), JSON (custom JSON notation), or SHELL (Unix-like)
/// Output type: LOGGER (using INFO, WARN, etc.), JSON (custom JSON notation), SHELL (Unix-like),
/// or MIXED (INFO, WARN, DEBUG, etc. to stderr and minimal JSON to stdout)
#[clap(long, value_parser, default_value = "LOGGER")]
output: String,

Expand Down
4 changes: 2 additions & 2 deletions rust/tests/grid_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ fn grid_latest_test() {
let output_code = json.result.code;
assert_eq!(output_code, 0);

let jar = Path::new(&json.result.message);
let jar = Path::new(&json.result.driver_path);
assert!(jar.exists());

let jar_name = jar.file_name().unwrap().to_str().unwrap();
Expand All @@ -66,7 +66,7 @@ fn grid_version_test(#[case] grid_version: &str) {
println!("{}", output);

let json: JsonOutput = serde_json::from_str(output).unwrap();
let jar = Path::new(&json.result.message);
let jar = Path::new(&json.result.driver_path);
let jar_name = jar.file_name().unwrap().to_str().unwrap();
assert!(jar_name.contains(grid_version));
}
Expand Down
26 changes: 24 additions & 2 deletions rust/tests/output_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
// under the License.

use assert_cmd::Command;
use selenium_manager::logger::{JsonOutput, DRIVER_PATH};
use selenium_manager::logger::{JsonOutput, MinimalJson, DRIVER_PATH};
use std::path::Path;
use std::str;

Expand All @@ -38,7 +38,7 @@ fn json_output_test() {
let output_code = json.result.code;
assert_eq!(output_code, 0);

let driver = Path::new(&json.result.message);
let driver = Path::new(&json.result.driver_path);
assert!(driver.exists());
}

Expand All @@ -55,3 +55,25 @@ fn shell_output_test() {
println!("{}", output);
assert!(output.contains(DRIVER_PATH));
}

#[test]
fn mixed_output_test() {
let mut cmd = Command::new(env!("CARGO_BIN_EXE_selenium-manager"));
cmd.args(["--browser", "chrome", "--output", "mixed"])
.assert()
.success()
.code(0);

let stdout = &cmd.unwrap().stdout;
let output = str::from_utf8(stdout).unwrap();
println!("stdout: {}", output);

let json: MinimalJson = serde_json::from_str(output).unwrap();
let driver = Path::new(&json.driver_path);
assert!(driver.exists());

let stderr = &cmd.unwrap().stderr;
let err_output = str::from_utf8(stderr).unwrap();
println!("stderr: {}", err_output);
assert!(!err_output.is_empty());
}

0 comments on commit 14ed560

Please sign in to comment.