summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2022-01-04 19:14:18 +0200
committerLars Wirzenius <liw@liw.fi>2022-01-05 10:38:49 +0200
commitf368595170ccfe9689b7ce2da9e26454d9bd4edb (patch)
treee16886fb2e0e443d6bb02b99375c66d8f40cd96b
parent64a11eca7f3cf75d735436366d8489ab93964dbf (diff)
downloadobnam-benchmark-f368595170ccfe9689b7ce2da9e26454d9bd4edb.tar.gz
feat: implement step to restore data
Sponsored-by: author
-rw-r--r--obnam-benchmark.md33
-rw-r--r--src/specification.rs11
-rw-r--r--src/suite.rs42
-rw-r--r--src/summain.rs3
4 files changed, 82 insertions, 7 deletions
diff --git a/obnam-benchmark.md b/obnam-benchmark.md
index 4440b57..5fc3164 100644
--- a/obnam-benchmark.md
+++ b/obnam-benchmark.md
@@ -157,3 +157,36 @@ benchmarks:
backups:
- changes: []
```
+
+
+## Benchmark with several backups
+
+_Requirement: The benchmark tool can benchmarks with more than one
+backup._
+
+We verify this by running a benchmark with three backup generations.
+
+~~~scenario
+given an installed Rust program obnam-benchmark
+given file three.yaml
+when I run obnam-benchmark run three.yaml --output three.json
+then file three.json is valid JSON
+~~~
+
+```{#three.yaml .yaml .file .numberLines}
+benchmarks:
+- benchmark: three
+ backups:
+ - changes:
+ - create:
+ files: 1
+ file_size: 1024
+ - changes:
+ - create:
+ files: 2
+ file_size: 2048
+ - changes:
+ - create:
+ files: 4
+ file_size: 4096
+```
diff --git a/src/specification.rs b/src/specification.rs
index 9e315f7..4eeb430 100644
--- a/src/specification.rs
+++ b/src/specification.rs
@@ -113,10 +113,11 @@ impl Specification {
/// Serialize the specification into a sequence of steps to execute it.
pub fn steps(&self) -> Vec<Step> {
let mut steps = vec![];
- let num_benchmarks = self.benchmarks.len();
- let after_base = num_benchmarks;
- let restore_base = after_base + num_benchmarks;
for b in self.benchmarks.iter() {
+ let n = b.backups.len();
+ let after_base = n;
+ let restore_base = 2 * n;
+
steps.push(Step::Start(b.benchmark.to_string()));
for (i, backup) in b.backups.iter().enumerate() {
for change in backup.changes.iter() {
@@ -131,8 +132,8 @@ impl Specification {
for (i, _) in b.backups.iter().enumerate() {
steps.push(Step::Restore(i));
let restored = restore_base + i;
- // steps.push(Step::ManifestRestored(restored));
- // steps.push(Step::CompareManifests(i, restored));
+ steps.push(Step::ManifestRestored(restored));
+ steps.push(Step::CompareManifests(i, restored));
}
steps.push(Step::Stop(b.benchmark.to_string()));
}
diff --git a/src/suite.rs b/src/suite.rs
index b4e8abb..224238a 100644
--- a/src/suite.rs
+++ b/src/suite.rs
@@ -42,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),
@@ -148,6 +152,8 @@ struct Benchmark {
client: ObnamClient,
server: ObnamServer,
live: TempDir,
+ restored: TempDir,
+ gen_ids: HashMap<usize, String>,
manifests: HashMap<usize, String>,
}
@@ -155,12 +161,15 @@ 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(),
})
}
@@ -173,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
@@ -218,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));
@@ -227,6 +249,15 @@ 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))
}
@@ -245,7 +276,16 @@ impl Benchmark {
if self.manifests.contains_key(&id) {
return Err(SuiteError::ManifestExists(id));
}
- self.manifests.insert(id, "dummy".to_string());
+ 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))
}
diff --git a/src/summain.rs b/src/summain.rs
index ea6044a..ce9cf0f 100644
--- a/src/summain.rs
+++ b/src/summain.rs
@@ -9,7 +9,8 @@ pub enum SummainError {
pub fn summain(root: &Path) -> Result<String, SummainError> {
let output = Command::new("summain")
- .arg(root)
+ .arg(".")
+ .current_dir(root)
.output()
.map_err(SummainError::Run)?;
if output.status.code() != Some(0) {