Skip to content

Commit

Permalink
Display 1-dimensional table in benchie show (closes #16) (#24)
Browse files Browse the repository at this point in the history
* Display 1-dimensional table in benchie show (closes #16)

* Split benchie show tests into smaller chunks (#24)
  • Loading branch information
mwidmoser committed May 6, 2022
1 parent f344f91 commit 6208a86
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 11 deletions.
88 changes: 82 additions & 6 deletions src/cli.rs
Expand Up @@ -7,8 +7,14 @@ pub mod sub_commands {
}

pub enum CliCommand {
Benchmark { command: Vec<String> },
Show,
Benchmark {
command: Vec<String>,
},
Show {
row: Option<String>,
col: Option<String>,
metric: Option<String>,
},
}

pub fn parse_arguments(args: &[OsString]) -> Result<CliCommand> {
Expand All @@ -26,7 +32,25 @@ pub fn parse_arguments(args: &[OsString]) -> Result<CliCommand> {
.subcommand(
Command::new(sub_commands::SHOW)
.about("Shows benchmarking results")
.arg(arg!([NAME])),
.arg(
arg!(--row <ROW> "The row to display")
.short('r')
.required(false)
.requires("metric"),
)
.arg(
arg!(--col <COLUMN> "The column to display")
.short('c')
.required(false)
.requires("row")
.requires("metric"),
)
.arg(
arg!(<METRIC> "The metric to display")
.required(false)
.id("metric")
.requires("row"),
),
)
.try_get_matches_from(args)?;

Expand All @@ -36,7 +60,11 @@ pub fn parse_arguments(args: &[OsString]) -> Result<CliCommand> {
CliCommand::Benchmark { command }
} else {
match matches.subcommand() {
Some(("show", _)) => CliCommand::Show,
Some(("show", sub_commands)) => CliCommand::Show {
row: sub_commands.value_of("row").map(str::to_string),
col: sub_commands.value_of("col").map(str::to_string),
metric: sub_commands.value_of("metric").map(str::to_string),
},
m => panic!("unknown subcommand {:?}", m),
}
})
Expand Down Expand Up @@ -88,11 +116,59 @@ mod test {

#[test]
fn test_show_subcommand() {
let command = parse_arguments(&[os("benchie"), os("show")]);
let cmd_default_show = parse_arguments(&[os("benchie"), os("show")]);

assert!(
matches!(command, Ok(CliCommand::Show)),
matches!(
cmd_default_show,
Ok(CliCommand::Show {
row: None,
col: None,
metric: None
})
),
"should succeed to parse show subcommand"
);
}

#[test]
fn show_1d_table_should_have_row_and_metric() {
match parse_arguments(&[
os("benchie"),
os("show"),
os("--row"),
os("test_row"),
os("test_metric"),
]) {
Ok(CliCommand::Show {
row,
col: _,
metric,
}) => {
assert_eq!(row.unwrap(), "test_row");
assert_eq!(metric.unwrap(), "test_metric");
}
_ => panic!("show argument with given row and metric should work"),
}
}

#[test]
fn show_2d_table_should_have_row_col_and_metric() {
match parse_arguments(&[
os("benchie"),
os("show"),
os("--row"),
os("test_row"),
os("--col"),
os("test_column"),
os("test_metric"),
]) {
Ok(CliCommand::Show { row, col, metric }) => {
assert_eq!(row.unwrap(), "test_row");
assert_eq!(col.unwrap(), "test_column");
assert_eq!(metric.unwrap(), "test_metric");
}
_ => panic!("show argument with given row, column, and metric should work"),
}
}
}
2 changes: 1 addition & 1 deletion src/lib.rs
Expand Up @@ -8,5 +8,5 @@ mod table;
pub use benchmark::{benchmark, execute_and_measure, ExecutionResult};
pub use crash_report::initialize_crash_reporter;
pub use git::{read_git_info, GitError, GitInfo};
pub use show::show;
pub use show::{show, show_1d_table, show_2d_table};
pub use storage::{append_benchmark, load_all_benchmarks, Benchmark};
8 changes: 6 additions & 2 deletions src/main.rs
@@ -1,7 +1,7 @@
use crate::cli::CliCommand;
use anyhow::Result;
use benchie::show;
use benchie::{benchmark, initialize_crash_reporter};
use benchie::{show, show_1d_table, show_2d_table};
use std::env;

mod cli;
Expand All @@ -13,6 +13,10 @@ fn main() -> Result<()> {

match cli::parse_arguments(&raw_args)? {
CliCommand::Benchmark { command } => benchmark(&command),
CliCommand::Show => show(),
CliCommand::Show { row, col, metric } => match (row, col, metric) {
(Some(row), Some(col), Some(metric)) => show_2d_table(row, col, metric),
(Some(row), _, Some(metric)) => show_1d_table(row, metric),
_ => show(),
},
}
}
54 changes: 53 additions & 1 deletion src/show.rs
@@ -1,5 +1,57 @@
use crate::load_all_benchmarks;
use anyhow::Result;
use cli_table::{format::Justify, Cell, Style, Table};

pub fn show() -> Result<()> {
todo!("fix this")
todo!("implement default show")
}

pub fn show_1d_table(row: String, metric: String) -> Result<()> {
let benchmarks = load_all_benchmarks()?;

let mut table = vec![];
let mut empty_matches = 0;

for benchmark in benchmarks.iter() {
let row_value = benchmark.data.get(&row);
let metric_value = benchmark.data.get(&metric);

match (row_value, metric_value) {
(Some(row_value), Some(metric_value)) => {
let row_value = format!("{}", row_value);
let metric_value = format!("{}", metric_value);

// add row to table
table.push(vec![
row_value.cell(),
metric_value.cell().justify(Justify::Right),
]);
}
_ => empty_matches += 1,
}
}

// convert table to TableStruct and set title
let table = table
.table()
.title(vec![
row.clone().cell().bold(true),
metric.clone().cell().bold(true),
])
.bold(true);

println!("{}", table.display()?);

if empty_matches > 0 {
println!(
"\"{}\" together with \"{}\" was {}x not present in your benchmarks",
row, metric, empty_matches
);
}

Ok(())
}

pub fn show_2d_table(_row: String, _col: String, _metric: String) -> Result<()> {
todo!("implement 2d table")
}
15 changes: 14 additions & 1 deletion src/storage.rs
Expand Up @@ -5,9 +5,9 @@ use chrono::prelude::*;
use serde::{Deserialize, Serialize};
use serde_json::json;
use std::collections::HashMap;
use std::fs;
use std::path::Path;
use std::time::Duration;
use std::{fmt, fs};

#[derive(Serialize, Deserialize, Debug, Clone)]
struct Data {
Expand Down Expand Up @@ -39,6 +39,19 @@ impl PartialEq for Value {
}
}

impl fmt::Display for Value {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Value::Timestamp(v) => write!(f, "{}", v),
Value::Duration(v) => write!(f, "{}", format_args!("{:?}", v)),
Value::String(v) => write!(f, "{}", v),
Value::Float(v) => write!(f, "{}", v),
Value::Integer(v) => write!(f, "{}", v),
Value::Bool(v) => write!(f, "{}", v),
}
}
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Benchmark {
pub data: HashMap<String, Value>,
Expand Down

0 comments on commit 6208a86

Please sign in to comment.