diff options
Diffstat (limited to 'src/suite.rs')
-rw-r--r-- | src/suite.rs | 120 |
1 files changed, 119 insertions, 1 deletions
diff --git a/src/suite.rs b/src/suite.rs index e900330..224238a 100644 --- a/src/suite.rs +++ b/src/suite.rs @@ -5,7 +5,9 @@ use crate::result::{Measurement, OpMeasurements, Operation}; use crate::server::{ObnamServer, ObnamServerError}; use crate::specification::{Create, FileCount}; use crate::step::Step; -use log::{debug, info}; +use crate::summain::{summain, SummainError}; +use log::{debug, error, info}; +use std::collections::HashMap; use std::fs::File; use std::path::{Path, PathBuf}; use std::time::Instant; @@ -40,6 +42,10 @@ pub enum SuiteError { #[error("Error looking up file metadata: {0}: {1}")] FileMeta(PathBuf, walkdir::Error), + /// Error removing restored data. + #[error("Error removing temporary directory: {0}: {1}")] + RemoveRestored(PathBuf, std::io::Error), + /// Error using an Obnam client. #[error(transparent)] Client(#[from] ObnamClientError), @@ -47,6 +53,22 @@ pub enum SuiteError { /// Error managing an Obnam server. #[error(transparent)] Server(#[from] ObnamServerError), + + /// Suite already has a manifest with a given id. + #[error("Suite already has manifest {0}: this is a bug")] + ManifestExists(usize), + + /// Suite doesn't have a manifest with a given id. + #[error("Suite doesn't have a manifest {0}: this is a bug")] + ManifestMissing(usize), + + /// Manifests are not identical. + #[error("Manifests {0} and {1} are not identical, as expected")] + ManifestsDiffer(usize, usize), + + /// Error running summain. + #[error(transparent)] + Summain(SummainError), } impl Suite { @@ -98,6 +120,21 @@ impl Suite { assert!(self.benchmark.is_some()); self.benchmark.as_mut().unwrap().restore(*x)? } + Step::ManifestLive(id) => { + assert!(self.benchmark.is_some()); + self.benchmark.as_mut().unwrap().manifest_live(*id)? + } + Step::ManifestRestored(id) => { + assert!(self.benchmark.is_some()); + self.benchmark.as_mut().unwrap().manifest_restored(*id)? + } + Step::CompareManifests(first, second) => { + assert!(self.benchmark.is_some()); + self.benchmark + .as_mut() + .unwrap() + .compare_manifests(*first, *second)? + } }; let t = std::time::Duration::from_millis(10); @@ -115,18 +152,25 @@ struct Benchmark { client: ObnamClient, server: ObnamServer, live: TempDir, + restored: TempDir, + gen_ids: HashMap<usize, String>, + manifests: HashMap<usize, String>, } impl Benchmark { fn new(name: &str, manager: &DaemonManager) -> Result<Self, SuiteError> { let server = ObnamServer::new(manager)?; let live = tempdir().map_err(SuiteError::TempDir)?; + let restored = tempdir().map_err(SuiteError::TempDir)?; let client = ObnamClient::new(server.url(), live.path().to_path_buf())?; Ok(Self { name: name.to_string(), client, server, live, + restored, + gen_ids: HashMap::new(), + manifests: HashMap::new(), }) } @@ -138,6 +182,10 @@ impl Benchmark { self.live.path().to_path_buf() } + fn restored(&self) -> PathBuf { + self.restored.path().join("restored") + } + fn start(&mut self) -> Result<OpMeasurements, SuiteError> { info!("starting benchmark {}", self.name()); self.client @@ -183,6 +231,15 @@ impl Benchmark { fn backup(&mut self, n: usize) -> Result<OpMeasurements, SuiteError> { info!("making backup {} in benchmark {}", n, self.name()); self.client.run(&["backup"])?; + let gen_id = self + .client + .run(&["resolve", "latest"])? + .strip_suffix('\n') + .or(Some("")) + .unwrap() + .to_string(); + debug!("backed up generation {}", gen_id); + self.gen_ids.insert(n, gen_id); let mut om = OpMeasurements::new(self.name(), Operation::Backup); let stats = filestats(&self.live())?; om.push(Measurement::TotalFiles(stats.count)); @@ -192,8 +249,69 @@ impl Benchmark { fn restore(&mut self, n: usize) -> Result<OpMeasurements, SuiteError> { info!("restoring backup {} in benchmark {}", n, self.name()); + debug!("first removing all data from restore directory"); + let restored = self.restored(); + if restored.exists() { + std::fs::remove_dir_all(&restored) + .map_err(|err| SuiteError::RemoveRestored(restored, err))?; + } + let gen_id = self.gen_ids.get(&n).unwrap(); + let path = self.restored().display().to_string(); + self.client.run(&["restore", gen_id, &path])?; Ok(OpMeasurements::new(self.name(), Operation::Restore)) } + + fn manifest_live(&mut self, id: usize) -> Result<OpMeasurements, SuiteError> { + info!("make manifest {} of current test data", id); + if self.manifests.contains_key(&id) { + return Err(SuiteError::ManifestExists(id)); + } + let m = summain(self.live.path()).map_err(SuiteError::Summain)?; + self.manifests.insert(id, m); + Ok(OpMeasurements::new(self.name(), Operation::ManifestLive)) + } + + fn manifest_restored(&mut self, id: usize) -> Result<OpMeasurements, SuiteError> { + info!("make manifest {} of latest restored data", id); + if self.manifests.contains_key(&id) { + return Err(SuiteError::ManifestExists(id)); + } + debug!("self.restored()={}", self.restored().display()); + let restored = format!( + "{}{}", + self.restored().display(), + self.live.path().display() + ); + let restored = Path::new(&restored); + debug!("restored directory is {}", restored.display()); + let m = summain(restored).map_err(SuiteError::Summain)?; + self.manifests.insert(id, m); + Ok(OpMeasurements::new(self.name(), Operation::ManifestLive)) + } + + fn compare_manifests( + &mut self, + first: usize, + second: usize, + ) -> Result<OpMeasurements, SuiteError> { + info!("compare manifests {} and {}", first, second); + let m1 = self.manifest(first)?; + let m2 = self.manifest(second)?; + if m1 != m2 { + error!("first manifest:\n{}", m1); + error!("second manifest:\n{}", m2); + return Err(SuiteError::ManifestsDiffer(first, second)); + } + Ok(OpMeasurements::new(self.name(), Operation::ManifestLive)) + } + + fn manifest(&self, id: usize) -> Result<String, SuiteError> { + if let Some(m) = self.manifests.get(&id) { + Ok(m.clone()) + } else { + Err(SuiteError::ManifestMissing(id)) + } + } } #[derive(Debug, Default)] |