Skip to content

Commit 53362fc

Browse files
authored
Fold some API tests into the files they test
Fewer test targets => less time linking tests.
1 parent 5027e14 commit 53362fc

File tree

17 files changed

+1473
-1584
lines changed

17 files changed

+1473
-1584
lines changed

src/archive.rs

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,3 +411,195 @@ impl Archive {
411411
Ok(())
412412
}
413413
}
414+
415+
#[cfg(test)]
416+
mod test {
417+
use super::*;
418+
419+
use std::fs;
420+
use std::io::Read;
421+
422+
use assert_fs::prelude::*;
423+
use assert_fs::TempDir;
424+
425+
use crate::monitor::test::TestMonitor;
426+
use crate::test_fixtures::store_two_versions;
427+
use crate::test_fixtures::TreeFixture;
428+
429+
#[tokio::test]
430+
async fn create_then_open_archive() {
431+
let testdir = TempDir::new().unwrap();
432+
let arch_path = testdir.path().join("arch");
433+
let arch = Archive::create_path(&arch_path).await.unwrap();
434+
435+
assert!(arch.list_band_ids().await.unwrap().is_empty());
436+
437+
// We can re-open it.
438+
Archive::open_path(&arch_path).await.unwrap();
439+
assert!(arch.list_band_ids().await.unwrap().is_empty());
440+
assert!(arch.last_complete_band().await.unwrap().is_none());
441+
}
442+
443+
#[tokio::test]
444+
async fn fails_on_non_empty_directory() {
445+
let temp = TempDir::new().unwrap();
446+
447+
temp.child("i am already here").touch().unwrap();
448+
449+
let result = Archive::create_path(temp.path()).await;
450+
assert_eq!(
451+
result.as_ref().unwrap_err().to_string(),
452+
"Directory for new archive is not empty",
453+
"{result:?}"
454+
);
455+
temp.close().unwrap();
456+
}
457+
458+
/// A new archive contains just one header file.
459+
/// The header is readable json containing only a version number.
460+
#[tokio::test]
461+
async fn empty_archive() {
462+
let af = Archive::create_temp().await;
463+
464+
assert!(af.transport().local_path().unwrap().is_dir());
465+
assert!(af
466+
.transport()
467+
.local_path()
468+
.unwrap()
469+
.join("CONSERVE")
470+
.is_file());
471+
assert!(af.transport().local_path().unwrap().join("d").is_dir());
472+
473+
let header_path = af.transport().local_path().unwrap().join("CONSERVE");
474+
let mut header_file = fs::File::open(header_path).unwrap();
475+
let mut contents = String::new();
476+
header_file.read_to_string(&mut contents).unwrap();
477+
assert_eq!(contents, "{\"conserve_archive_version\":\"0.6\"}\n");
478+
479+
assert!(
480+
af.last_band_id().await.unwrap().is_none(),
481+
"Archive should have no bands yet"
482+
);
483+
assert!(
484+
af.last_complete_band().await.unwrap().is_none(),
485+
"Archive should have no bands yet"
486+
);
487+
assert_eq!(
488+
af.referenced_blocks(&af.list_band_ids().await.unwrap(), TestMonitor::arc())
489+
.await
490+
.unwrap()
491+
.len(),
492+
0
493+
);
494+
assert_eq!(af.all_blocks(TestMonitor::arc()).await.unwrap().len(), 0);
495+
}
496+
497+
#[tokio::test]
498+
async fn delete_all_bands() {
499+
let af = Archive::create_temp().await;
500+
store_two_versions(&af).await;
501+
502+
let stats = af
503+
.delete_bands(
504+
&[BandId::new(&[0]), BandId::new(&[1])],
505+
&Default::default(),
506+
TestMonitor::arc(),
507+
)
508+
.await
509+
.expect("delete_bands");
510+
511+
assert_eq!(stats.deleted_block_count, 2);
512+
assert_eq!(stats.deleted_band_count, 2);
513+
}
514+
515+
#[tokio::test]
516+
async fn unreferenced_blocks() {
517+
let archive = Archive::create_temp().await;
518+
let tf = TreeFixture::new();
519+
tf.create_file("hello");
520+
let content_hash: BlockHash =
521+
"9063990e5c5b2184877f92adace7c801a549b00c39cd7549877f06d5dd0d3a6ca6eee42d5\
522+
896bdac64831c8114c55cee664078bd105dc691270c92644ccb2ce7"
523+
.parse()
524+
.unwrap();
525+
526+
let _copy_stats = backup(
527+
&archive,
528+
tf.path(),
529+
&BackupOptions::default(),
530+
TestMonitor::arc(),
531+
)
532+
.await
533+
.expect("backup");
534+
535+
// Delete the band and index
536+
std::fs::remove_dir_all(archive.transport().local_path().unwrap().join("b0000")).unwrap();
537+
let monitor = TestMonitor::arc();
538+
539+
let unreferenced: Vec<BlockHash> =
540+
archive.unreferenced_blocks(monitor.clone()).await.unwrap();
541+
assert_eq!(unreferenced, [content_hash]);
542+
543+
// Delete dry run.
544+
let delete_stats = archive
545+
.delete_bands(
546+
&[],
547+
&DeleteOptions {
548+
dry_run: true,
549+
break_lock: false,
550+
},
551+
monitor.clone(),
552+
)
553+
.await
554+
.unwrap();
555+
assert_eq!(
556+
delete_stats,
557+
DeleteStats {
558+
unreferenced_block_count: 1,
559+
unreferenced_block_bytes: 10,
560+
deletion_errors: 0,
561+
deleted_block_count: 0,
562+
deleted_band_count: 0,
563+
elapsed: delete_stats.elapsed,
564+
}
565+
);
566+
567+
// Delete unreferenced blocks.
568+
let options = DeleteOptions {
569+
dry_run: false,
570+
break_lock: false,
571+
};
572+
let delete_stats = archive
573+
.delete_bands(&[], &options, monitor.clone())
574+
.await
575+
.unwrap();
576+
assert_eq!(
577+
delete_stats,
578+
DeleteStats {
579+
unreferenced_block_count: 1,
580+
unreferenced_block_bytes: 10,
581+
deletion_errors: 0,
582+
deleted_block_count: 1,
583+
deleted_band_count: 0,
584+
elapsed: delete_stats.elapsed,
585+
}
586+
);
587+
588+
// Try again to delete: should find no garbage.
589+
let delete_stats = archive
590+
.delete_bands(&[], &options, monitor.clone())
591+
.await
592+
.unwrap();
593+
assert_eq!(
594+
delete_stats,
595+
DeleteStats {
596+
unreferenced_block_count: 0,
597+
unreferenced_block_bytes: 0,
598+
deletion_errors: 0,
599+
deleted_block_count: 0,
600+
deleted_band_count: 0,
601+
elapsed: delete_stats.elapsed,
602+
}
603+
);
604+
}
605+
}

0 commit comments

Comments
 (0)