diff --git a/src/bin/aperf.rs b/src/bin/aperf.rs index 2a957e41..2b73c9a9 100644 --- a/src/bin/aperf.rs +++ b/src/bin/aperf.rs @@ -1,10 +1,12 @@ use anyhow::Result; use aperf_lib::record::{record, Record}; use aperf_lib::report::{report, Report}; -use aperf_lib::PDError; +use aperf_lib::{PDError, APERF_TMP}; use clap::{Parser, Subcommand}; use env_logger::Builder; use log::LevelFilter; +use std::{fs, os::unix::fs::PermissionsExt}; +use tempfile::Builder as TempBuilder; #[derive(Parser)] #[command(author, about, long_about = None)] @@ -18,6 +20,10 @@ struct Cli { /// Show debug messages. Use -vv for more verbose messages. #[clap(short, long, global = true, action = clap::ArgAction::Count)] verbose: u8, + + /// Temporary directory for intermediate files. + #[clap(short, long, value_parser, default_value_t = APERF_TMP.to_string(), global = true)] + tmp_dir: String, } #[derive(Subcommand)] @@ -42,11 +48,17 @@ fn init_logger(verbose: u8) -> Result<()> { fn main() -> Result<()> { let cli = Cli::parse(); + + let tmp_dir = TempBuilder::new().prefix("aperf-tmp-").tempdir_in(&cli.tmp_dir)?; + fs::set_permissions(&tmp_dir, fs::Permissions::from_mode(0o1777))?; + let tmp_dir_path_buf = tmp_dir.path().to_path_buf(); + init_logger(cli.verbose)?; - match &cli.command { - Commands::Record(r) => record(r), - Commands::Report(r) => report(r), + match cli.command { + Commands::Record(r) => record(&r, &tmp_dir_path_buf), + Commands::Report(r) => report(&r, &tmp_dir_path_buf), }?; + fs::remove_dir_all(tmp_dir_path_buf)?; Ok(()) } diff --git a/src/data.rs b/src/data.rs index 39d6feb6..248344df 100644 --- a/src/data.rs +++ b/src/data.rs @@ -119,31 +119,30 @@ impl DataType { self.collector_params.signal = signal; } - pub fn init_data_type(&mut self, param: InitParams) -> Result<()> { + pub fn init_data_type(&mut self, param: &InitParams) -> Result<()> { trace!("Initializing data type..."); let name = format!( "{}_{}.{}", self.file_name, param.time_str, APERF_FILE_FORMAT ); - let full_path = format!("{}/{}", param.dir_name, name); - self.file_name = name; - self.full_path = full_path.clone(); + self.file_name = name.clone(); + self.full_path = format!("{}/{}", param.dir_name, name); self.dir_name = param.dir_name.clone(); self.collector_params.run_name = param.dir_name.clone(); self.collector_params.collection_time = param.period; self.collector_params.elapsed_time = 0; - self.collector_params.data_file_path = PathBuf::from(full_path); - self.collector_params.data_dir = PathBuf::from(param.dir_name); + self.collector_params.data_file_path = PathBuf::from(&self.full_path); + self.collector_params.data_dir = PathBuf::from(param.dir_name.clone()); self.collector_params.profile = param.profile.clone(); - self.collector_params.tmp_dir = PathBuf::from(param.tmp_dir); + self.collector_params.tmp_dir = param.tmp_dir.clone(); self.file_handle = Some( OpenOptions::new() .read(true) .create(true) .append(true) - .open(self.full_path.clone()) + .open(&self.full_path) .expect("Could not create file for data"), ); @@ -152,8 +151,7 @@ impl DataType { pub fn prepare_data_collector(&mut self) -> Result<()> { trace!("Preparing data collector..."); - self.data - .prepare_data_collector(self.collector_params.clone())?; + self.data.prepare_data_collector(&self.collector_params)?; Ok(()) } @@ -172,15 +170,13 @@ impl DataType { pub fn finish_data_collection(&mut self) -> Result<()> { trace!("Finish data collection..."); - self.data - .finish_data_collection(self.collector_params.clone())?; + self.data.finish_data_collection(&self.collector_params)?; Ok(()) } pub fn after_data_collection(&mut self) -> Result<()> { trace!("Running post collection actions..."); - self.data - .after_data_collection(self.collector_params.clone())?; + self.data.after_data_collection(&self.collector_params)?; Ok(()) } } @@ -231,7 +227,7 @@ macro_rules! data { Ok(()) } - fn prepare_data_collector(&mut self, params: CollectorParams) -> Result<()> { + fn prepare_data_collector(&mut self, params: &CollectorParams) -> Result<()> { match self { $( Data::$x(ref mut value) => value.prepare_data_collector(params)?, @@ -240,7 +236,7 @@ macro_rules! data { Ok(()) } - fn finish_data_collection(&mut self, params: CollectorParams) -> Result<()> { + fn finish_data_collection(&mut self, params: &CollectorParams) -> Result<()> { match self { $( Data::$x(ref mut value) => value.finish_data_collection(params)?, @@ -248,7 +244,7 @@ macro_rules! data { } Ok(()) } - fn after_data_collection(&mut self, params: CollectorParams) -> Result<()> { + fn after_data_collection(&mut self, params: &CollectorParams) -> Result<()> { match self { $( Data::$x(ref mut value) => value.after_data_collection(params)?, @@ -342,7 +338,7 @@ macro_rules! noop { } pub trait CollectData { - fn prepare_data_collector(&mut self, _params: CollectorParams) -> Result<()> { + fn prepare_data_collector(&mut self, _params: &CollectorParams) -> Result<()> { noop!(); Ok(()) } @@ -350,11 +346,11 @@ pub trait CollectData { noop!(); Ok(()) } - fn finish_data_collection(&mut self, _params: CollectorParams) -> Result<()> { + fn finish_data_collection(&mut self, _params: &CollectorParams) -> Result<()> { noop!(); Ok(()) } - fn after_data_collection(&mut self, _params: CollectorParams) -> Result<()> { + fn after_data_collection(&mut self, _params: &CollectorParams) -> Result<()> { noop!(); Ok(()) } @@ -390,7 +386,7 @@ mod tests { .create(param.dir_name.clone()) .unwrap(); - dt.init_data_type(param).unwrap(); + dt.init_data_type(¶m).unwrap(); assert!(dt.file_handle.is_some()); fs::remove_file(dt.full_path).unwrap(); @@ -418,7 +414,7 @@ mod tests { .create(param.dir_name.clone()) .unwrap(); - dt.init_data_type(param).unwrap(); + dt.init_data_type(¶m).unwrap(); assert!(Path::new(&dt.full_path).exists()); dt.write_to_file().unwrap(); diff --git a/src/data/flamegraphs.rs b/src/data/flamegraphs.rs index 3fd19c0e..92442e0e 100644 --- a/src/data/flamegraphs.rs +++ b/src/data/flamegraphs.rs @@ -40,14 +40,14 @@ impl FlamegraphRaw { } impl CollectData for FlamegraphRaw { - fn prepare_data_collector(&mut self, _params: CollectorParams) -> Result<()> { + fn prepare_data_collector(&mut self, _params: &CollectorParams) -> Result<()> { match Command::new("perf").args(["--version"]).output() { Err(e) => Err(PDError::DependencyError(format!("'perf' command failed. {}", e)).into()), _ => Ok(()), } } - fn after_data_collection(&mut self, params: CollectorParams) -> Result<()> { + fn after_data_collection(&mut self, params: &CollectorParams) -> Result<()> { let data_dir = PathBuf::from(¶ms.data_dir); let file_pathbuf = data_dir.join(get_file_name( diff --git a/src/data/java_profile.rs b/src/data/java_profile.rs index f87ddecb..bcfab241 100644 --- a/src/data/java_profile.rs +++ b/src/data/java_profile.rs @@ -38,7 +38,7 @@ impl JavaProfileRaw { } } - fn launch_asprof(&self, jids: Vec, params: CollectorParams) -> Result<()> { + fn launch_asprof(&self, jids: Vec, params: &CollectorParams) -> Result<()> { for jid in &jids { match Command::new("asprof") .args([ @@ -137,7 +137,7 @@ impl JavaProfileRaw { } impl CollectData for JavaProfileRaw { - fn prepare_data_collector(&mut self, params: CollectorParams) -> Result<()> { + fn prepare_data_collector(&mut self, params: &CollectorParams) -> Result<()> { let mut jids: Vec = Vec::new(); let pgrep: Vec = self.launch_pgrep()?; for pid in pgrep { @@ -172,7 +172,7 @@ impl CollectData for JavaProfileRaw { } jids.sort(); jids.dedup(); - self.launch_asprof(jids, params.clone()) + self.launch_asprof(jids, params) } fn collect_data(&mut self, params: &CollectorParams) -> Result<()> { @@ -198,10 +198,10 @@ impl CollectData for JavaProfileRaw { } self.update_process_map()?; - self.launch_asprof(jids, params.clone()) + self.launch_asprof(jids, params) } - fn finish_data_collection(&mut self, params: CollectorParams) -> Result<()> { + fn finish_data_collection(&mut self, params: &CollectorParams) -> Result<()> { for child in ASPROF_CHILDREN.lock().unwrap().iter() { signal::kill(Pid::from_raw(child.id() as i32), params.signal)?; } @@ -242,10 +242,6 @@ impl CollectData for JavaProfileRaw { Ok(()) } - - fn after_data_collection(&mut self, _params: CollectorParams) -> Result<()> { - Ok(()) - } } #[derive(Serialize, Deserialize, Debug, Clone)] diff --git a/src/data/perf_profile.rs b/src/data/perf_profile.rs index 45e4256b..962860e1 100644 --- a/src/data/perf_profile.rs +++ b/src/data/perf_profile.rs @@ -9,9 +9,11 @@ use log::{error, trace}; use nix::{sys::signal, unistd::Pid}; use serde::{Deserialize, Serialize}; use std::fs; -use std::io::Write; -use std::process::{Child, Command, Stdio}; -use std::sync::Mutex; +use std::{ + io::Write, + process::{Child, Command, Stdio}, + sync::Mutex, +}; pub static PERF_PROFILE_FILE_NAME: &str = "perf_profile"; pub static PERF_TOP_FUNCTIONS_FILE_NAME: &str = "top_functions"; @@ -34,7 +36,7 @@ impl PerfProfileRaw { } impl CollectData for PerfProfileRaw { - fn prepare_data_collector(&mut self, params: CollectorParams) -> Result<()> { + fn prepare_data_collector(&mut self, params: &CollectorParams) -> Result<()> { match Command::new("perf") .stdout(Stdio::null()) .args([ @@ -73,7 +75,7 @@ impl CollectData for PerfProfileRaw { Ok(()) } - fn finish_data_collection(&mut self, params: CollectorParams) -> Result<()> { + fn finish_data_collection(&mut self, params: &CollectorParams) -> Result<()> { let mut child = PERF_CHILD.lock().unwrap(); match child.as_ref() { None => return Ok(()), diff --git a/src/data/perf_stat.rs b/src/data/perf_stat.rs index bd90cc50..65f7526d 100644 --- a/src/data/perf_stat.rs +++ b/src/data/perf_stat.rs @@ -115,7 +115,7 @@ impl PerfStatRaw { } impl CollectData for PerfStatRaw { - fn prepare_data_collector(&mut self, _params: CollectorParams) -> Result<()> { + fn prepare_data_collector(&mut self, _params: &CollectorParams) -> Result<()> { let num_cpus = match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN as libc::c_int) } { -1 => { warn!("Could not get the number of cpus in the system with sysconf."); @@ -567,7 +567,7 @@ mod tests { let mut perf_stat = PerfStatRaw::new(); let params = CollectorParams::new(); - match perf_stat.prepare_data_collector(params.clone()) { + match perf_stat.prepare_data_collector(¶ms) { Err(e) => { if let Some(os_error) = e.downcast_ref::() { match os_error.kind() { @@ -593,7 +593,7 @@ mod tests { let mut processed_buffer: Vec = Vec::new(); let params = CollectorParams::new(); - match perf_stat.prepare_data_collector(params.clone()) { + match perf_stat.prepare_data_collector(¶ms) { Err(e) => { if let Some(os_error) = e.downcast_ref::() { match os_error.kind() { diff --git a/src/data/processes.rs b/src/data/processes.rs index 7ebbbe95..55f3bd9b 100644 --- a/src/data/processes.rs +++ b/src/data/processes.rs @@ -46,7 +46,7 @@ impl Default for ProcessesRaw { } impl CollectData for ProcessesRaw { - fn prepare_data_collector(&mut self, _params: CollectorParams) -> Result<()> { + fn prepare_data_collector(&mut self, _params: &CollectorParams) -> Result<()> { *TICKS_PER_SECOND.lock().unwrap() = procfs::ticks_per_second()? as u64; Ok(()) } @@ -345,7 +345,7 @@ mod process_test { fn test_collect_data() { let mut processes = ProcessesRaw::new(); let params = CollectorParams::new(); - processes.prepare_data_collector(params.clone()).unwrap(); + processes.prepare_data_collector(¶ms).unwrap(); processes.collect_data(¶ms).unwrap(); assert!(!processes.data.is_empty()); } @@ -358,12 +358,8 @@ mod process_test { let mut processed_buffer: Vec = Vec::::new(); let params = CollectorParams::new(); - processes_zero - .prepare_data_collector(params.clone()) - .unwrap(); - processes_one - .prepare_data_collector(params.clone()) - .unwrap(); + processes_zero.prepare_data_collector(¶ms).unwrap(); + processes_one.prepare_data_collector(¶ms).unwrap(); processes_zero.collect_data(¶ms).unwrap(); processes_one.collect_data(¶ms).unwrap(); diff --git a/src/html_files/aperf_run_stats.ts b/src/html_files/aperf_run_stats.ts index 53980e79..01f3d9c2 100644 --- a/src/html_files/aperf_run_stats.ts +++ b/src/html_files/aperf_run_stats.ts @@ -29,6 +29,7 @@ function getAperfEntry(elem, key, run_data) { y: y_print, type: 'scatter', }; + let limits = key_limits.get(key); var layout = { title: `${key}`, xaxis: { @@ -36,6 +37,7 @@ function getAperfEntry(elem, key, run_data) { }, yaxis: { title: 'Time (us)', + range: [limits.low, limits.high], }, } Plotly.newPlot(TESTER, [aperfstat_collect_data, aperfstat_print_data], layout, { frameMargins: 0 }); diff --git a/src/lib.rs b/src/lib.rs index 416efe20..743fc9ed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,9 +26,13 @@ use thiserror::Error; use timerfd::{SetTimeFlags, TimerFd, TimerState}; pub static APERF_FILE_FORMAT: &str = "bin"; +pub static APERF_TMP: &str = "/tmp"; #[derive(Error, Debug)] pub enum PDError { + #[error("Error initializing logger")] + LoggerInitError, + #[error("Error getting JavaScript file for {}", .0)] VisualizerJSFileGetError(String), @@ -191,7 +195,7 @@ impl PerformanceData { ); for (_name, datatype) in self.collectors.iter_mut() { - datatype.init_data_type(self.init_params.clone())?; + datatype.init_data_type(&self.init_params)?; } Ok(()) } @@ -339,6 +343,11 @@ impl PerformanceData { datatype.after_data_collection()?; } tfd.set_state(TimerState::Disarmed, SetTimeFlags::Default); + Ok(()) + } + + pub fn end(&mut self) -> Result<()> { + // All activities in the record folder should be complete before this. self.create_data_archive()?; Ok(()) } @@ -413,8 +422,8 @@ impl VisualizationData { pub fn init_visualizers( &mut self, dir: String, - tmp_dir: String, - fin_dir: PathBuf, + tmp_dir: &Path, + fin_dir: &Path, ) -> Result { let dir_path = Path::new(&dir); let dir_name = dir_path.file_stem().unwrap().to_str().unwrap().to_string(); @@ -423,13 +432,10 @@ impl VisualizationData { let mut error_count = 0; for (_name, visualizer) in self.visualizers.iter_mut() { - if let Err(e) = visualizer.init_visualizer( - dir.clone(), - dir_name.clone(), - tmp_dir.clone(), - fin_dir.clone(), - ) { - error!("{:#?}", e); + if let Err(e) = + visualizer.init_visualizer(dir.clone(), dir_name.clone(), tmp_dir, fin_dir) + { + debug!("{:#?}", e); visualizer.data_not_available(dir_name.clone())?; error_count += 1; } @@ -524,7 +530,7 @@ pub struct InitParams { pub run_name: String, pub collector_version: String, pub commit_sha_short: String, - pub tmp_dir: String, + pub tmp_dir: PathBuf, } impl InitParams { @@ -561,7 +567,7 @@ impl InitParams { run_name, collector_version, commit_sha_short, - tmp_dir: String::new(), + tmp_dir: PathBuf::from(APERF_TMP), } } } diff --git a/src/record.rs b/src/record.rs index ea9a6497..245bbcf8 100644 --- a/src/record.rs +++ b/src/record.rs @@ -2,10 +2,7 @@ use crate::{data, InitParams, PERFORMANCE_DATA}; use anyhow::Result; use clap::Args; use log::{debug, error, info}; -use std::os::unix::fs::PermissionsExt; -use std::{fs, process}; - -pub static APERF_TMP: &str = "/tmp/aperf_tmp"; +use std::path::Path; #[derive(Args, Debug)] pub struct Record { @@ -48,7 +45,7 @@ fn collect_static_data() -> Result<()> { Ok(()) } -pub fn record(record: &Record) -> Result<()> { +pub fn record(record: &Record, tmp_dir: &Path) -> Result<()> { let mut run_name = String::new(); if record.period == 0 { error!("Collection period cannot be 0."); @@ -65,7 +62,7 @@ pub fn record(record: &Record) -> Result<()> { let mut params = InitParams::new(run_name); params.period = record.period; params.interval = record.interval; - params.tmp_dir = APERF_TMP.to_string(); + params.tmp_dir = tmp_dir.to_path_buf(); match &record.profile_java { Some(j) => { @@ -87,15 +84,6 @@ pub fn record(record: &Record) -> Result<()> { ); } - fs::remove_dir_all(APERF_TMP).ok(); - if let Err(e) = fs::create_dir(APERF_TMP) { - error!("Could not create /tmp/aperf_tmp folder.\n{}: Remove using 'sudo rm -rf /tmp/aperf_tmp'.", e); - process::exit(1); - } - let mut perms: fs::Permissions = fs::metadata(APERF_TMP)?.permissions(); - perms.set_mode(0o777); - fs::set_permissions(APERF_TMP, perms)?; - PERFORMANCE_DATA.lock().unwrap().set_params(params); PERFORMANCE_DATA.lock().unwrap().init_collectors()?; info!("Starting Data collection..."); @@ -103,7 +91,7 @@ pub fn record(record: &Record) -> Result<()> { collect_static_data()?; start_collection_serial()?; info!("Data collection complete."); + PERFORMANCE_DATA.lock().unwrap().end()?; - fs::remove_dir_all(APERF_TMP)?; Ok(()) } diff --git a/src/report.rs b/src/report.rs index c8f2f8c0..50fa1f98 100644 --- a/src/report.rs +++ b/src/report.rs @@ -53,15 +53,13 @@ impl Run { } } -pub static APERF_TMP: &str = "aperf_tmp"; - -pub fn form_and_copy_archive(loc: PathBuf, report_name: &Path) -> Result<()> { +pub fn form_and_copy_archive(loc: PathBuf, report_name: &Path, tmp_dir: &Path) -> Result<()> { if loc.is_dir() { let dir_stem = loc.file_stem().unwrap().to_str().unwrap().to_string(); /* Create a temp archive */ let archive_name = format!("{}.tar.gz", &dir_stem); - let archive_path = format!("{}/{}", APERF_TMP, archive_name); + let archive_path = tmp_dir.join(&archive_name); let archive_dst = report_name.join(format!("data/archive/{}", archive_name)); { let tar_gz = fs::File::create(&archive_path)?; @@ -105,7 +103,7 @@ pub fn get_report_archives(dir: PathBuf) -> Result> { Ok(archives) } -pub fn get_dir(dir: PathBuf) -> Result { +pub fn get_dir(dir: PathBuf, tmp_dir: &PathBuf) -> Result { /* If dir return */ if dir.is_dir() { return Ok(dir); @@ -115,7 +113,7 @@ pub fn get_dir(dir: PathBuf) -> Result { let tar_gz = File::open(&dir)?; let tar = GzDecoder::new(tar_gz); let mut archive = tar::Archive::new(tar); - archive.unpack(APERF_TMP)?; + archive.unpack(tmp_dir)?; let dir_name = dir .file_name() .unwrap() @@ -123,7 +121,7 @@ pub fn get_dir(dir: PathBuf) -> Result { .unwrap() .strip_suffix(".tar.gz") .ok_or(PDError::InvalidArchiveName)?; - let out = PathBuf::from(APERF_TMP).join(dir_name); + let out = tmp_dir.join(dir_name); if !out.exists() { return Err(PDError::ArchiveDirectoryMismatch.into()); } @@ -132,7 +130,7 @@ pub fn get_dir(dir: PathBuf) -> Result { Err(PDError::RecordNotArchiveOrDirectory.into()) } -pub fn report(report: &Report) -> Result<()> { +pub fn report(report: &Report, tmp_dir: &PathBuf) -> Result<()> { let dirs: Vec = report.run.clone(); let mut pathbuf_dirs: Vec = Vec::new(); let mut data_dirs: Vec = Vec::new(); @@ -146,7 +144,7 @@ pub fn report(report: &Report) -> Result<()> { /* Check if dirs contains report */ for dir in pathbuf_dirs { - let path_dir = get_dir(dir.to_path_buf())?; + let path_dir = get_dir(dir.to_path_buf(), tmp_dir)?; if let Some(archive_dir) = is_report_dir(path_dir.clone()) { if report.name.is_none() { return Err(PDError::VisualizerReportFromReportNoNameError.into()); @@ -161,12 +159,9 @@ pub fn report(report: &Report) -> Result<()> { } } - /* Create a tmp dir for aperf to work with */ - fs::create_dir_all(APERF_TMP)?; - /* Get dir paths, stems */ for dir in &data_dirs { - let path = get_dir(dir.to_path_buf())?; + let path = get_dir(dir.to_path_buf(), tmp_dir)?; if dir_stems.contains(&path.file_stem().unwrap().to_str().unwrap().to_string()) { error!("Cannot process two runs with the same name"); return Ok(()); @@ -218,7 +213,7 @@ pub fn report(report: &Report) -> Result<()> { /* Generate/copy the archives of the collected data into aperf_report */ for dir in &data_dirs { - form_and_copy_archive(dir.to_path_buf(), &report_name)?; + form_and_copy_archive(dir.to_path_buf(), &report_name, tmp_dir)?; } /* Generate base HTML, JS files */ let mut ico_file = File::create(report_name.join("images/favicon.ico"))?; @@ -239,13 +234,10 @@ pub fn report(report: &Report) -> Result<()> { write!(configure_js_file, "{}", configure_js)?; let mut visualizer = VISUALIZATION_DATA.lock().unwrap(); + /* Init visualizers */ for dir in dir_paths { - let name = visualizer.init_visualizers( - dir.to_owned(), - APERF_TMP.to_string(), - report_name.clone(), - )?; + let name = visualizer.init_visualizers(dir.to_owned(), tmp_dir, &report_name)?; visualizer.unpack_data(name)?; } @@ -319,6 +311,5 @@ pub fn report(report: &Report) -> Result<()> { .unwrap() .to_string(); tar.append_dir_all(&report_stem, &report_name)?; - fs::remove_dir_all(APERF_TMP)?; Ok(()) } diff --git a/src/visualizer.rs b/src/visualizer.rs index b707836d..b4fb633b 100644 --- a/src/visualizer.rs +++ b/src/visualizer.rs @@ -71,14 +71,14 @@ impl DataVisualizer { &mut self, dir: String, name: String, - tmp_dir: String, - fin_dir: PathBuf, + tmp_dir: &Path, + fin_dir: &Path, ) -> Result<()> { let file = get_file(dir.clone(), self.file_name.clone())?; let full_path = Path::new("/proc/self/fd").join(file.as_raw_fd().to_string()); self.report_params.data_dir = PathBuf::from(dir.clone()); - self.report_params.tmp_dir = PathBuf::from(tmp_dir); - self.report_params.report_dir = fin_dir; + self.report_params.tmp_dir = tmp_dir.to_path_buf(); + self.report_params.report_dir = fin_dir.to_path_buf(); self.report_params.run_name = name.clone(); self.report_params.data_file_path = fs::read_link(full_path).unwrap(); self.file_handle = Some(file); @@ -264,8 +264,8 @@ mod tests { dv.init_visualizer( "tests/test-data/aperf_2023-07-26_18_37_43/".to_string(), "test".to_string(), - String::new(), - PathBuf::new(), + &PathBuf::new(), + &PathBuf::new(), ) .unwrap(); dv.process_raw_data("test".to_string()).unwrap(); diff --git a/tests/test_aperf.rs b/tests/test_aperf.rs index 4b9abd1a..3a2297c3 100644 --- a/tests/test_aperf.rs +++ b/tests/test_aperf.rs @@ -10,11 +10,16 @@ use tempfile::TempDir; fn run_test(test_func: T) where - T: FnOnce(PathBuf) -> Result<()> + panic::UnwindSafe, + T: FnOnce(PathBuf, PathBuf) -> Result<()> + panic::UnwindSafe, { let tempdir = TempDir::with_prefix("aperf").unwrap(); - let result = panic::catch_unwind(|| test_func(tempdir.path().to_path_buf())); + let aperf_tmp = TempDir::with_prefix("tmp_aperf").unwrap(); + + let result = panic::catch_unwind(|| { + test_func(tempdir.path().to_path_buf(), aperf_tmp.path().to_path_buf()) + }); tempdir.close().unwrap(); + aperf_tmp.close().unwrap(); if let Err(e) = result { panic::resume_unwind(e); } @@ -23,7 +28,7 @@ where #[test] #[serial] fn test_record() { - run_test(|tempdir| { + run_test(|tempdir, aperf_tmp| { let run_name = tempdir .join("test_record") .into_os_string() @@ -37,7 +42,7 @@ fn test_record() { profile_java: None, }; - record(&rec).unwrap(); + record(&rec, &aperf_tmp).unwrap(); assert!(Path::new(&run_name).exists()); assert!(Path::new(&(run_name.clone() + ".tar.gz")).exists()); @@ -50,7 +55,7 @@ fn test_record() { #[test] #[serial] fn test_report() { - run_test(|tempdir| { + run_test(|tempdir, aperf_tmp| { let run_name = tempdir .join("record_data") .into_os_string() @@ -64,7 +69,7 @@ fn test_report() { profile_java: None, }; - record(&rec).unwrap(); + record(&rec, &aperf_tmp).unwrap(); let test_report_path = PathBuf::from("test_report"); let report_loc = tempdir @@ -77,7 +82,7 @@ fn test_report() { run: [run_name.clone()].to_vec(), name: Some(report_loc.clone()), }; - report(&rep).unwrap(); + report(&rep, &aperf_tmp).unwrap(); // Check if the directory has the proper structure assert!(report_path.exists());