diff options
author | Lars Wirzenius <liw@liw.fi> | 2021-12-05 15:57:12 +0200 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2021-12-05 15:57:12 +0200 |
commit | 0133bd6fb912d0138841cd8d2a6c878c674e0e81 (patch) | |
tree | 9f527dde73dd77c6a5dc734640b4f6552153f1d9 | |
parent | 55000324bb4d6434fa147ce4c835a2c8cc76b757 (diff) | |
download | obnam-benchmark-0133bd6fb912d0138841cd8d2a6c878c674e0e81.tar.gz |
refactor: use a "step" abstraction for running benchmarks
Sponsored-by: author
-rw-r--r-- | src/bin/obnam-benchmark.rs | 20 | ||||
-rw-r--r-- | src/lib.rs | 63 |
2 files changed, 62 insertions, 21 deletions
diff --git a/src/bin/obnam-benchmark.rs b/src/bin/obnam-benchmark.rs index 8b31a82..b76a7aa 100644 --- a/src/bin/obnam-benchmark.rs +++ b/src/bin/obnam-benchmark.rs @@ -43,25 +43,9 @@ struct Run { impl Run { fn run(&self) -> anyhow::Result<()> { let spec = Specification::from_file(&self.spec)?; - - for benchmark in spec.benchmarks() { - println!("benchmark {}", benchmark.name()); - println!("start obnam server with empty chunks dir"); - println!("create empty test data directory"); - for backup in benchmark.backups() { - println!("make changes to test data"); - for change in backup.changes() { - change.execute()?; - } - println!("run backup, measure time and chunks directory"); - } - for _ in benchmark.backups() { - println!("run restore, measure time") - } - println!("stop obnam server"); - println!("clean up test data directory"); + for step in spec.steps() { + println!("{:?}", step); } - Ok(()) } } @@ -1,6 +1,7 @@ use serde::{Deserialize, Serialize}; use std::fs::File; use std::path::{Path, PathBuf}; +use std::collections::HashSet; #[derive(Debug, Serialize, Deserialize)] #[serde(deny_unknown_fields)] @@ -10,6 +11,9 @@ pub struct Specification { #[derive(Debug, thiserror::Error)] pub enum SpecificationError { + #[error("Duplicate benchmark name {0}")] + DuplicateBenchmark(String), + #[error("Couldn't open {0}: {1}")] Open(PathBuf, std::io::Error), @@ -40,29 +44,72 @@ pub enum Change { Rename(FileCount), } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Create { files: u64, file_size: u64, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct FileCount { files: u64, } +#[derive(Debug)] +pub enum Step { + Start(String), + Stop(String), + MeasureChunks, + Create(Create), + Rename(FileCount), + Delete(FileCount), + Backup(usize), + Restore(usize), +} + impl Specification { pub fn from_file(filename: &Path) -> Result<Self, SpecificationError> { let f = File::open(filename) .map_err(|err| SpecificationError::Open(filename.to_path_buf(), err))?; - let spec = serde_yaml::from_reader(f) + let spec: Specification = serde_yaml::from_reader(f) .map_err(|err| SpecificationError::Yaml(filename.to_path_buf(), err))?; + spec.check()?; Ok(spec) } + fn check(&self) -> Result<(), SpecificationError> { + let mut names = HashSet::new(); + for name in self.benchmarks().map(|b| b.name()) { + let name = name.to_string(); + if names.contains(&name) { + return Err(SpecificationError::DuplicateBenchmark(name)); + } + names.insert(name); + } + Ok(()) + } + pub fn benchmarks(&self) -> impl Iterator<Item = &Benchmark> { self.benchmarks.iter() } + + pub fn steps(&self) -> Vec<Step> { + let mut steps = vec![]; + for b in self.benchmarks() { + steps.push(Step::Start(b.name().to_string())); + for (i, backup) in b.backups().enumerate() { + for change in backup.changes() { + steps.push(Step::from(change)); + } + steps.push(Step::Backup(i)); + } + for (i, _) in b.backups().enumerate() { + steps.push(Step::Restore(i)); + } + steps.push(Step::Stop(b.name().to_string())); + } + steps + } } impl Benchmark { @@ -91,3 +138,13 @@ impl Change { Ok(()) } } + +impl Step { + pub fn from(change: &Change) -> Self { + match change { + Change::Create(x) => Self::Create(x.clone()), + Change::Rename(x) => Self::Rename(x.clone()), + Change::Delete(x) => Self::Delete(x.clone()), + } + } +} |