summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2021-12-05 20:45:59 +0200
committerLars Wirzenius <liw@liw.fi>2021-12-05 20:45:59 +0200
commita4221521b353009727608263a1d169b4abc7033f (patch)
treeb079867fa5d8fee304c5e44d22460bfc24ebf11e
parente9f7b3048f29596f5b5d40791e591e29e85ab5e7 (diff)
downloadobnam-benchmark-a4221521b353009727608263a1d169b4abc7033f.tar.gz
feat: add data and state abstractions
Sponsored-by: author
-rw-r--r--src/bin/obnam-benchmark.rs7
-rw-r--r--src/data.rs35
-rw-r--r--src/lib.rs2
-rw-r--r--src/run.rs3
-rw-r--r--src/state.rs102
-rw-r--r--src/step.rs68
6 files changed, 146 insertions, 71 deletions
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<Self, DataError> {
+ 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<CurrentBenchmark>,
+}
+
+/// 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<Option<OpMeasurements>, 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<OpMeasurements, StateError> {
+ let mut om = OpMeasurements::new(&current.name, Operation::Backup(i));
+ om.push(Measurement::TotalFiles(0));
+ om.push(Measurement::TotalData(0));
+ Ok(om)
+}
+
+fn restore(i: usize, current: &CurrentBenchmark) -> Result<OpMeasurements, StateError> {
+ Ok(OpMeasurements::new(&current.name, Operation::Restore(i)))
+}
+
+struct CurrentBenchmark {
+ name: String,
+ data: Data,
+}
+
+impl CurrentBenchmark {
+ fn new(name: &str) -> Result<Self, DataError> {
+ 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<String>,
- ) -> Result<Option<OpMeasurements>, 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<OpMeasurements, StepError> {
- 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<OpMeasurements, StepError> {
- 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(())
}