netbench-cli/src/report_tree.rs (93 lines of code) (raw):

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 use crate::{report::Report, Result}; use serde_json::json; use std::{ collections::BTreeMap, path::{Path, PathBuf}, }; use structopt::StructOpt; #[derive(Debug, StructOpt)] pub struct ReportTree { input_dir: PathBuf, out_dir: PathBuf, } static INDEX_HTML: &str = include_str!("./report_tree.html"); type ScenarioMap = BTreeMap<String, Report>; impl ReportTree { pub fn run(&self) -> Result<()> { let mut client_scenarios: ScenarioMap = Default::default(); let mut server_scenarios: ScenarioMap = Default::default(); for scenario in self.input_dir.read_dir()? { let scenario = scenario?; let path = scenario.path(); let scenario_name = if let Some(name) = path_name(&path) { name } else { continue; }; // scenario.path() = sample/results/requst_response_incast for driver in scenario.path().read_dir()? { let driver_path = driver?.path(); macro_rules! push_scenario { ($target:ident, $json_result_path:ident, $url_name:literal) => {{ $target .entry(scenario_name.to_string()) .or_insert_with(|| Report { output: Some(self.out_dir.join(scenario_name).join($url_name)), ..Default::default() }) .inputs .push($json_result_path); }}; } // driver_path = sample/results/requst_response_incast/server-tcp for json_result in driver_path.read_dir()? { let json_result_path = json_result?.path(); let json_result_filename = json_result_path .file_name() .expect("expected file path") .to_str() .unwrap(); // only process .json log files if !json_result_filename.ends_with(".json") { continue; } if json_result_filename.contains("server") { push_scenario!(server_scenarios, json_result_path, "servers.json"); } else if json_result_filename.contains("client") { push_scenario!(client_scenarios, json_result_path, "clients.json"); } else { panic!( "result filename: {}, should contain either 'client' or 'server'", json_result_filename ) } } } } std::fs::create_dir_all(&self.out_dir)?; let index = { let template = handlebars::Handlebars::new(); template.render_template( INDEX_HTML, &json!({ "clients": render_scenarios(client_scenarios)?, "servers": render_scenarios(server_scenarios)?, }), )? }; std::fs::write(self.out_dir.join("index.html"), index)?; Ok(()) } } fn render_scenarios(scenarios: ScenarioMap) -> Result<Vec<String>> { let mut names = vec![]; for (name, report) in scenarios { names.push(name); report.run()?; } Ok(names) } fn path_name(path: &Path) -> Option<&str> { let stem = path.file_stem()?.to_str()?; // filter out any hidden files if stem.starts_with('.') { return None; } Some(stem) }