commit 5cdaeddc0e38b54aa86c41be11b403a6f8f283e3
parent fa4dc716db149b1fee41c20a2bd719dbfbb164d6
Author: Silas Brack <silasbrack@gmail.com>
Date: Sun, 8 Mar 2026 13:31:35 +0100
Clean up tests
Diffstat:
| M | src/db.rs | | | 34 | +++------------------------------- |
| M | src/rebuild.rs | | | 58 | +++++----------------------------------------------------- |
| M | src/server.rs | | | 89 | ++++--------------------------------------------------------------------------- |
3 files changed, 12 insertions(+), 169 deletions(-)
diff --git a/src/db.rs b/src/db.rs
@@ -206,42 +206,14 @@ mod tests {
use super::*;
#[test]
- fn test_prefix_upper_bound_simple() {
- assert_eq!(prefix_upper_bound("abc"), Some("abd".to_string()));
- assert_eq!(prefix_upper_bound("a"), Some("b".to_string()));
- assert_eq!(prefix_upper_bound("foo/bar"), Some("foo/bas".to_string()));
- }
-
- #[test]
- fn test_prefix_upper_bound_paths() {
- // '/' is 0x2F, +1 = '0' (0x30)
- assert_eq!(prefix_upper_bound("users/"), Some("users0".to_string()));
- // '_' is 0x5F, +1 = '`' (0x60)
- assert_eq!(prefix_upper_bound("img_"), Some("img`".to_string()));
- }
-
- #[test]
- fn test_prefix_upper_bound_empty() {
- assert_eq!(prefix_upper_bound(""), None);
- }
-
- #[test]
- fn test_prefix_upper_bound_single_char() {
- assert_eq!(prefix_upper_bound("z"), Some("{".to_string())); // 'z' + 1 = '{'
- assert_eq!(prefix_upper_bound("9"), Some(":".to_string())); // '9' + 1 = ':'
- }
-
- #[test]
fn test_prefix_upper_bound_range_correctness() {
- // Verify the bound works for range queries:
- // All strings starting with "foo" should be >= "foo" and < "fop"
+ // The only test that matters: does the bound actually work for range queries?
+ // All strings starting with "foo" should be >= "foo" and < upper_bound("foo")
let prefix = "foo";
let upper = prefix_upper_bound(prefix).unwrap();
- assert_eq!(upper, "fop");
-
let upper = upper.as_str();
- // These should be in range [foo, fop)
+ // These should be in range [prefix, upper)
assert!("foo" >= prefix && "foo" < upper);
assert!("foo/bar" >= prefix && "foo/bar" < upper);
assert!("foobar" >= prefix && "foobar" < upper);
diff --git a/src/rebuild.rs b/src/rebuild.rs
@@ -107,66 +107,18 @@ mod tests {
use super::*;
#[test]
- fn test_merge_empty_scans() {
- let scans: Vec<(String, Vec<(String, i64)>)> = vec![];
- let index = merge_volume_scans(&scans);
- assert!(index.is_empty());
- }
-
- #[test]
- fn test_merge_single_volume() {
- let scans = vec![(
- "http://vol1".to_string(),
- vec![
- ("key1".to_string(), 100),
- ("key2".to_string(), 200),
- ],
- )];
- let index = merge_volume_scans(&scans);
- assert_eq!(index.len(), 2);
- assert_eq!(index.get("key1"), Some(&(vec!["http://vol1".to_string()], 100)));
- assert_eq!(index.get("key2"), Some(&(vec!["http://vol1".to_string()], 200)));
- }
-
- #[test]
- fn test_merge_key_on_multiple_volumes() {
- let scans = vec![
- ("http://vol1".to_string(), vec![("shared".to_string(), 100)]),
- ("http://vol2".to_string(), vec![("shared".to_string(), 100)]),
- ("http://vol3".to_string(), vec![("shared".to_string(), 100)]),
- ];
- let index = merge_volume_scans(&scans);
- assert_eq!(index.len(), 1);
- let (volumes, size) = index.get("shared").unwrap();
- assert_eq!(volumes.len(), 3);
- assert!(volumes.contains(&"http://vol1".to_string()));
- assert!(volumes.contains(&"http://vol2".to_string()));
- assert!(volumes.contains(&"http://vol3".to_string()));
- assert_eq!(*size, 100);
- }
-
- #[test]
fn test_merge_takes_max_size() {
- // Same key with different sizes on different volumes (corruption or update race)
+ // Edge case: same key with different sizes across volumes
+ // (can happen due to incomplete writes or corruption)
+ // We take the max size as the authoritative value
let scans = vec![
("http://vol1".to_string(), vec![("key".to_string(), 50)]),
("http://vol2".to_string(), vec![("key".to_string(), 200)]),
("http://vol3".to_string(), vec![("key".to_string(), 100)]),
];
let index = merge_volume_scans(&scans);
- let (_, size) = index.get("key").unwrap();
+ let (volumes, size) = index.get("key").unwrap();
+ assert_eq!(volumes.len(), 3);
assert_eq!(*size, 200, "should take maximum size across volumes");
}
-
- #[test]
- fn test_merge_disjoint_keys() {
- let scans = vec![
- ("http://vol1".to_string(), vec![("a".to_string(), 10)]),
- ("http://vol2".to_string(), vec![("b".to_string(), 20)]),
- ];
- let index = merge_volume_scans(&scans);
- assert_eq!(index.len(), 2);
- assert_eq!(index.get("a").unwrap().0, vec!["http://vol1".to_string()]);
- assert_eq!(index.get("b").unwrap().0, vec!["http://vol2".to_string()]);
- }
}
diff --git a/src/server.rs b/src/server.rs
@@ -243,88 +243,7 @@ pub async fn list_keys(
Ok((StatusCode::OK, keys.join("\n")).into_response())
}
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn test_volumes_for_key_sufficient() {
- let volumes: Vec<String> = (1..=3).map(|i| format!("http://vol{i}")).collect();
- let selected = crate::hasher::volumes_for_key("test-key", &volumes, 2);
- assert_eq!(selected.len(), 2);
- }
-
- #[test]
- fn test_volumes_for_key_insufficient() {
- let volumes: Vec<String> = vec!["http://vol1".into()];
- let selected = crate::hasher::volumes_for_key("test-key", &volumes, 2);
- assert_eq!(selected.len(), 1);
- }
-
- #[test]
- fn test_first_healthy_volume_finds_first() {
- let volumes = vec!["http://vol1".into(), "http://vol2".into(), "http://vol3".into()];
- let results = vec![true, true, true];
- assert_eq!(
- first_healthy_volume("key", &volumes, &results),
- ProbeResult::Found("http://vol1/key".into())
- );
- }
-
- #[test]
- fn test_first_healthy_volume_skips_unhealthy() {
- let volumes = vec!["http://vol1".into(), "http://vol2".into(), "http://vol3".into()];
- let results = vec![false, false, true];
- assert_eq!(
- first_healthy_volume("key", &volumes, &results),
- ProbeResult::Found("http://vol3/key".into())
- );
- }
-
- #[test]
- fn test_first_healthy_volume_all_failed() {
- let volumes = vec!["http://vol1".into(), "http://vol2".into()];
- let results = vec![false, false];
- assert_eq!(
- first_healthy_volume("key", &volumes, &results),
- ProbeResult::AllFailed
- );
- }
-
- #[test]
- fn test_first_healthy_volume_early_exit() {
- // Simulates early exit: only first two volumes were probed
- let volumes = vec!["http://vol1".into(), "http://vol2".into(), "http://vol3".into()];
- let results = vec![false, true]; // Only 2 results because we stopped early
- assert_eq!(
- first_healthy_volume("key", &volumes, &results),
- ProbeResult::Found("http://vol2/key".into())
- );
- }
-
- #[test]
- fn test_shuffle_volumes_deterministic_with_seed() {
- let volumes: Vec<String> = (1..=5).map(|i| format!("http://vol{i}")).collect();
- let a = shuffle_volumes(volumes.clone(), 42);
- let b = shuffle_volumes(volumes.clone(), 42);
- assert_eq!(a, b, "same seed should produce same order");
- }
-
- #[test]
- fn test_shuffle_volumes_different_seeds() {
- let volumes: Vec<String> = (1..=10).map(|i| format!("http://vol{i}")).collect();
- let a = shuffle_volumes(volumes.clone(), 1);
- let b = shuffle_volumes(volumes.clone(), 2);
- assert_ne!(a, b, "different seeds should produce different orders");
- }
-
- #[test]
- fn test_shuffle_volumes_preserves_elements() {
- let volumes: Vec<String> = (1..=5).map(|i| format!("http://vol{i}")).collect();
- let mut shuffled = shuffle_volumes(volumes.clone(), 123);
- shuffled.sort();
- let mut original = volumes;
- original.sort();
- assert_eq!(shuffled, original);
- }
-}
+// Note: first_healthy_volume and shuffle_volumes are trivial functions
+// (essentially .find() and .shuffle()). Testing them would just test
+// that standard library functions work. The real test is integration:
+// does failover work with actual down volumes?