From a4221521b353009727608263a1d169b4abc7033f Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sun, 5 Dec 2021 20:45:59 +0200 Subject: feat: add data and state abstractions Sponsored-by: author --- src/bin/obnam-benchmark.rs | 7 ++-- src/data.rs | 35 ++++++++++++++++ src/lib.rs | 2 + src/run.rs | 3 ++ src/state.rs | 102 +++++++++++++++++++++++++++++++++++++++++++++ src/step.rs | 68 ------------------------------ 6 files changed, 146 insertions(+), 71 deletions(-) create mode 100644 src/data.rs create mode 100644 src/run.rs create mode 100644 src/state.rs diff --git a/src/bin/obnam-benchmark.rs b/src/bin/obnam-benchmark.rs index 9a326ec..418a46e 100644 --- a/src/bin/obnam-benchmark.rs +++ b/src/bin/obnam-benchmark.rs @@ -1,5 +1,6 @@ -use obnam_benchmark::specification::Specification; use obnam_benchmark::result::Result; +use obnam_benchmark::specification::Specification; +use obnam_benchmark::state::State; use std::fs::File; use std::path::PathBuf; use std::process::exit; @@ -52,10 +53,10 @@ struct Run { impl Run { fn run(&self) -> anyhow::Result<()> { let spec = Specification::from_file(&self.spec)?; + let mut state = State::new(); let mut result = Result::default(); - let mut current_benchmark = None; for step in spec.steps() { - if let Some(m) = step.execute(&mut current_benchmark)? { + if let Some(m) = state.execute(&step)? { result.push(m); } } diff --git a/src/data.rs b/src/data.rs new file mode 100644 index 0000000..aaaebc9 --- /dev/null +++ b/src/data.rs @@ -0,0 +1,35 @@ +use crate::specification::{Create, FileCount}; + +/// Test data management for Obnam benchmarks. +/// +/// Each backup in a benchmark backs up some test data created for +/// that backup. That data is later cleaned up. Is all handled by this +/// structure. +#[derive(Debug)] +pub struct Data {} + +/// Possible errors from managing data. +#[derive(Debug, thiserror::Error)] +pub enum DataError { +} + +impl Data { + pub(crate) fn new() -> Result { + Ok(Self {}) + } + + pub(crate) fn create(&self, create: &Create) -> Result<(), DataError> { + println!("create {:?}", create); + Ok(()) + } + + pub(crate) fn rename(&self, count: &FileCount) -> Result<(), DataError> { + println!("rename {:?}", count); + Ok(()) + } + + pub(crate) fn delete(&self, count: &FileCount) -> Result<(), DataError> { + println!("delete {:?}", count); + Ok(()) + } +} diff --git a/src/lib.rs b/src/lib.rs index 40a8619..0f05dd8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,6 +28,8 @@ //! This crate only collects data from a set of benchmarks. It does //! not analyze the data. The data can be stored for later analysis. +pub mod data; pub mod result; pub mod specification; +pub mod state; pub mod step; diff --git a/src/run.rs b/src/run.rs new file mode 100644 index 0000000..94261ff --- /dev/null +++ b/src/run.rs @@ -0,0 +1,3 @@ +/// Runtime state for running Obnam benchmarks. +pub struct RuntimeState { +} diff --git a/src/state.rs b/src/state.rs new file mode 100644 index 0000000..bce5115 --- /dev/null +++ b/src/state.rs @@ -0,0 +1,102 @@ +use crate::data::{Data, DataError}; +use crate::result::{Measurement, OpMeasurements, Operation}; +use crate::step::Step; +use std::time::Instant; + +/// Runtime state for running Obnam benchmarks. +pub struct State { + current_benchmark: Option, +} + +/// Possible errors from changing benchmark state. +#[derive(Debug, thiserror::Error)] +pub enum StateError { + /// A step is executed in the wrong order. + #[error("Internal error: step expected inside a benchmark")] + OutOfStep, + + /// Error managing test data. + #[error(transparent)] + Data(#[from] DataError), +} + +impl State { + pub fn new() -> Self { + Self { + current_benchmark: None, + } + } + + fn current(&self) -> Result<&CurrentBenchmark, StateError> { + if let Some(x) = &self.current_benchmark { + Ok(x) + } else { + Err(StateError::OutOfStep) + } + } + + pub fn execute(&mut self, step: &Step) -> Result, StateError> { + let now = Instant::now(); + let om = match step { + Step::Start(name) => { + self.current_benchmark = Some(CurrentBenchmark::new(name)?); + None + } + Step::Stop(_) => { + self.current_benchmark = None; + None + } + Step::Create(x) => { + self.current()?.data.create(x)?; + None + } + Step::Rename(x) => { + self.current()?.data.rename(x)?; + None + } + Step::Delete(x) => { + self.current()?.data.delete(x)?; + None + } + Step::Backup(x) => Some(backup(*x, self.current()?)?), + Step::Restore(x) => Some(restore(*x, self.current()?)?), + }; + + println!("{:?}", step); + let t = std::time::Duration::from_millis(10); + std::thread::sleep(t); + + if let Some(mut om) = om { + let ms = now.elapsed().as_millis(); + om.push(Measurement::DurationMs(ms)); + Ok(Some(om)) + } else { + Ok(None) + } + } +} + +fn backup(i: usize, current: &CurrentBenchmark) -> Result { + let mut om = OpMeasurements::new(¤t.name, Operation::Backup(i)); + om.push(Measurement::TotalFiles(0)); + om.push(Measurement::TotalData(0)); + Ok(om) +} + +fn restore(i: usize, current: &CurrentBenchmark) -> Result { + Ok(OpMeasurements::new(¤t.name, Operation::Restore(i))) +} + +struct CurrentBenchmark { + name: String, + data: Data, +} + +impl CurrentBenchmark { + fn new(name: &str) -> Result { + Ok(Self { + name: name.to_string(), + data: Data::new()?, + }) + } +} diff --git a/src/step.rs b/src/step.rs index 9755f70..dee07d3 100644 --- a/src/step.rs +++ b/src/step.rs @@ -1,6 +1,4 @@ -use crate::result::{Measurement, OpMeasurements, Operation}; use crate::specification::{Change, Create, FileCount}; -use std::time::Instant; /// A step in the execution of a benchmark. #[derive(Debug)] @@ -49,70 +47,4 @@ impl Step { Change::Delete(x) => Self::Delete(x.clone()), } } - - pub fn execute( - &self, - current: &mut Option, - ) -> Result, StepError> { - let now = Instant::now(); - let om = match self { - Self::Start(name) => { - *current = Some(name.to_string()); - None - } - Self::Stop(_) => { - *current = None; - None - } - Self::Create(x) => { - create_files(x)?; - None - } - Self::Rename(x) => { - rename_files(x)?; - None - } - Self::Delete(x) => { - delete_files(x)?; - None - } - Self::Backup(x) => Some(backup(*x, current.as_ref().unwrap())?), - Self::Restore(x) => Some(restore(*x, current.as_ref().unwrap())?), - }; - - println!("{:?}", self); - let t = std::time::Duration::from_millis(10); - std::thread::sleep(t); - - if let Some(mut om) = om { - let ms = now.elapsed().as_millis(); - om.push(Measurement::DurationMs(ms)); - Ok(Some(om)) - } else { - Ok(None) - } - } -} - -fn backup(i: usize, current: &str) -> Result { - let mut om = OpMeasurements::new(current, Operation::Backup(i)); - om.push(Measurement::TotalFiles(0)); - om.push(Measurement::TotalData(0)); - Ok(om) -} - -fn restore(i: usize, current: &str) -> Result { - Ok(OpMeasurements::new(current, Operation::Restore(i))) -} - -fn create_files(_: &Create) -> Result<(), StepError> { - Ok(()) -} - -fn rename_files(_: &FileCount) -> Result<(), StepError> { - Ok(()) -} - -fn delete_files(_: &FileCount) -> Result<(), StepError> { - Ok(()) } -- cgit v1.2.1