From 4ae45e6fd17ca83603cb214025a2bf6149b46891 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sun, 5 Dec 2021 18:43:30 +0200 Subject: docs: add doc comments everywhere, adjust publicity of symbols Sponsored-by: author --- src/lib.rs | 30 +++++++++++++++++++++++++++++ src/specification.rs | 53 +++++++++++++++++++++++++++++++++++++++------------- src/step.rs | 33 ++++++++++++++++++++++++++------ 3 files changed, 97 insertions(+), 19 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index dda1212..162ff87 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,32 @@ +//! Run benchmarks for the Obnam backup program. +//! +//! Obnam is a backup system. This crate a way to specifying +//! benchmarks in YAML and running them. A specification file looks +//! like: +//! +//! ```yaml +//! benchmarks: +//! - benchmark: maildir +//! backups: +//! - changes: +//! - create: +//! files: 100 +//! file_size: 0 +//! - changes: +//! - rename: +//! files: 10 +//! - delete: +//! files: 10 +//! - create: +//! files: 10 +//! file_size: 0 +//! ``` +//! +//! A [specification][] is broken down into a sequence of +//! [steps](step). Steps, if executed in order, perform the benchmark. +//! +//! 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 specification; pub mod step; diff --git a/src/specification.rs b/src/specification.rs index e4b20d1..0234601 100644 --- a/src/specification.rs +++ b/src/specification.rs @@ -1,40 +1,67 @@ +/// A specification for a set of benchmarks for Obnam. +/// +/// One specification can contain any number of benchmarks. For each +/// benchmark, any number of backups can be specified. For each +/// benchmark, the specification contains instructions for how to +/// create or change the data being backed up. +/// +/// The specification can be serialized into linear sequence of steps +/// for execution. use crate::step::Step; use serde::{Deserialize, Serialize}; use std::collections::HashSet; use std::fs::File; use std::path::{Path, PathBuf}; +/// A benchmark specification. #[derive(Debug, Serialize, Deserialize)] #[serde(deny_unknown_fields)] pub struct Specification { benchmarks: Vec, } +/// Possible errors from loading a specification from a file. #[derive(Debug, thiserror::Error)] pub enum SpecificationError { + /// Two benchmarks have the same name. #[error("Duplicate benchmark name {0}")] - DuplicateBenchmark(String), + DuplicateBenchmark( + /// The name of the benchmark. + String, + ), + /// I/O error opening the specification file. #[error("Couldn't open {0}: {1}")] - Open(PathBuf, std::io::Error), - + Open( + /// The name of the specification file. + PathBuf, + /// The I/O error. + std::io::Error, + ), + + /// YAML parsing problem in the specification file. #[error("Couldn't read YAML specification from {0}:\n {1}")] - Yaml(PathBuf, serde_yaml::Error), + Yaml( + /// The name of the specification file. + PathBuf, + /// The YAML error. + serde_yaml::Error, + ), } #[derive(Debug, Serialize, Deserialize)] -pub struct Benchmark { +struct Benchmark { benchmark: String, backups: Vec, } #[derive(Debug, Serialize, Deserialize)] -pub struct Backup { +struct Backup { pub changes: Vec, } #[derive(Debug, Serialize, Deserialize)] -pub enum Change { +pub(crate) enum Change { #[serde(rename = "create")] Create(Create), @@ -45,18 +72,21 @@ pub enum Change { Rename(FileCount), } +/// How many files to create, and how big they should be. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Create { files: u64, file_size: u64, } +/// How many files to operate on. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct FileCount { files: u64, } impl Specification { + /// Load a benchmark specification from a named file. pub fn from_file(filename: &Path) -> Result { let f = File::open(filename) .map_err(|err| SpecificationError::Open(filename.to_path_buf(), err))?; @@ -68,7 +98,7 @@ impl Specification { fn check(&self) -> Result<(), SpecificationError> { let mut names = HashSet::new(); - for name in self.benchmarks().map(|b| b.name()) { + for name in self.benchmarks.iter().map(|b| b.name()) { let name = name.to_string(); if names.contains(&name) { return Err(SpecificationError::DuplicateBenchmark(name)); @@ -78,13 +108,10 @@ impl Specification { Ok(()) } - pub fn benchmarks(&self) -> impl Iterator { - self.benchmarks.iter() - } - + /// Serialize the specification into a sequence of steps to execute it. pub fn steps(&self) -> Vec { let mut steps = vec![]; - for b in self.benchmarks() { + for b in self.benchmarks.iter() { steps.push(Step::Start(b.name().to_string())); for (i, backup) in b.backups().enumerate() { for change in backup.changes() { diff --git a/src/step.rs b/src/step.rs index a3a208a..35bb13b 100644 --- a/src/step.rs +++ b/src/step.rs @@ -1,25 +1,46 @@ use crate::specification::{Change, Create, FileCount}; +/// A step in the execution of a benchmark. #[derive(Debug)] pub enum Step { - Start(String), - Stop(String), - MeasureChunks, + /// Start a benchmark. + Start( + /// Unique name of the benchmark. + String, + ), + /// Finish a benchmark with a given name. + Stop( + /// Unique name of the benchmark. + String, + ), + /// Create test data files. Create(Create), + /// Rename test data files. Rename(FileCount), + /// Delete test data files. Delete(FileCount), - Backup(usize), - Restore(usize), + /// Make the nth backup in the benchmark. + Backup( + /// n + usize, + ), + /// Restore the nth backup in the benchmark. + Restore( + /// n + usize, + ), } +/// Possible errors from executing a benchmark step. #[derive(Debug, thiserror::Error)] pub enum StepError { + /// Generic I/O error. #[error(transparent)] Io(std::io::Error), } impl Step { - pub fn from(change: &Change) -> Self { + pub(crate) fn from(change: &Change) -> Self { match change { Change::Create(x) => Self::Create(x.clone()), Change::Rename(x) => Self::Rename(x.clone()), -- cgit v1.2.1