Skip to content

Conversation

@ZocoLini
Copy link
Collaborator

@ZocoLini ZocoLini commented Jan 17, 2026

Summary by CodeRabbit

  • Tests
    • Consolidated and reorganized storage-layer tests: expanded batch header scenarios, persistence/reopen checks, reverse-index and clear validations, and lock lifecycle coverage. Streamlined scaffolding and increased use of temporary storage setups to improve reliability and maintainability.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 17, 2026

📝 Walkthrough

Walkthrough

Consolidates and expands storage tests by moving and refactoring many integration tests into unit tests inside dash-spv/src/storage/mod.rs and deleting multiple legacy integration test files; no public API signatures were changed.

Changes

Cohort / File(s) Summary
Storage module tests (updated)
dash-spv/src/storage/mod.rs
Reworked and expanded test module: batch-based header store/load scenarios (including empty and partial batches), tip-height progression checks, range retrievals, reverse index (hash→height) lookups and persistence, checkpoint indexing tests, lock-file lifecycle tests, plus persistence/reopen verification. Tests now use tempdir/Path refs.
Removed: large integration suites
dash-spv/tests/storage_consistency_test.rs, dash-spv/tests/segmented_storage_test.rs
Deleted comprehensive integration suites covering tip/header consistency, segment boundary and eviction races, concurrent access stress tests, background save behaviors, and many reproduction/debug scenarios.
Removed: assorted integration tests
dash-spv/tests/header_sync_test.rs, dash-spv/tests/reverse_index_test.rs, dash-spv/tests/segmented_storage_debug.rs, dash-spv/tests/simple_segmented_test.rs, dash-spv/tests/storage_test.rs
Deleted multiple smaller integration test files; header_sync_test.rs substantially reduced to a few client-integration and prepare_sync tests while many sync tests were removed. Reverse-index and other storage tests were moved into the storage module or removed.
Test utilities / setup changes
...
Tests migrated to use with_temp_dir/tempdir patterns and pass &Path where previously PathBuf was used; no exported API signature changes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰 I hopped through headers, batch by batch,
I stored, I loaded, found every match.
Locks popped up and then they fled,
Checkpoints saved where I softly tread.
A tidy burrow — tests well-fed 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: test reorganization moving integration tests from separate files into unit tests in mod.rs, and removal of duplicate test coverage across multiple deleted test files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
dash-spv/tests/header_sync_test.rs (1)

31-35: TempDir is dropped immediately, potentially deleting the directory before the test completes.

The TempDir is created inline and not bound to a variable, so it's dropped immediately after .path() returns. When TempDir drops, it deletes the temporary directory. The DiskStorageManager will then be operating on a deleted path.

Proposed fix
+    // Create storage manager
+    let temp_dir = TempDir::new().expect("Failed to create tmp dir");
     let storage_manager =
-        DiskStorageManager::new(TempDir::new().expect("Failed to create tmp dir").path())
+        DiskStorageManager::new(temp_dir.path())
             .await
             .expect("Failed to create tmp storage");
dash-spv/src/storage/mod.rs (1)

142-148: TempDir is dropped when function returns, deleting the directory.

The TempDir is created locally and dropped when with_temp_dir() returns. This deletes the temporary directory while DiskStorageManager is still expected to use it. The fact that new() calls create_dir_all recreates the path, but the temp directory cleanup semantics are lost and this is fragile.

Consider returning a tuple or wrapping both in a struct so the TempDir lifetime is tied to the storage lifetime.

Proposed fix - return both TempDir and storage
     #[cfg(test)]
-    pub async fn with_temp_dir() -> StorageResult<Self> {
+    pub async fn with_temp_dir() -> StorageResult<(tempfile::TempDir, Self)> {
         use tempfile::TempDir;
 
         let temp_dir = TempDir::new()?;
-        Self::new(temp_dir.path()).await
+        let storage = Self::new(temp_dir.path()).await?;
+        Ok((temp_dir, storage))
     }

Then update callers:

-    let mut storage =
-        DiskStorageManager::with_temp_dir().await.expect("Failed to create tmp storage");
+    let (_temp_dir, mut storage) =
+        DiskStorageManager::with_temp_dir().await.expect("Failed to create tmp storage");
🧹 Nitpick comments (1)
dash-spv/src/storage/mod.rs (1)

525-525: Unnecessary double reference.

temp_dir.path() already returns &Path, so &temp_dir.path() creates &&Path. While this works due to auto-deref, it's inconsistent with line 506 which correctly uses temp_dir.path().

Suggested fix
-            let storage = DiskStorageManager::new(&temp_dir.path()).await.unwrap();
+            let storage = DiskStorageManager::new(temp_dir.path()).await.unwrap();

@ZocoLini ZocoLini force-pushed the refactor/storage-tests branch from 192fb56 to 743988d Compare January 17, 2026 20:05
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@dash-spv/src/storage/mod.rs`:
- Around line 434-443: The test drops DiskStorageManager while its background
worker may still be running; ensure you call storage.shutdown().await before
drop(storage) to stop the worker and avoid post-test writes. Update the
instances around DiskStorageManager::new(...) and subsequent drop(storage) to
invoke the async shutdown() on the storage handle (e.g., call
storage.shutdown().await) prior to dropping it; apply the same change to the
other similar blocks referenced (around the other occurrences ~lines 523-535 and
575-577).
- Around line 540-552: DiskStorageManager::with_temp_dir() currently drops the
TempDir immediately, risking deletion of the backing directory while storage is
still used; fix the test by creating and retaining an explicit TempDir (e.g.,
via tempfile::TempDir) and passing its path into DiskStorageManager (or into
DiskStorageManager::new) so the TempDir lives for the lifetime of storage;
update the test around DiskStorageManager::with_temp_dir(),
BlockHeader::dummy_batch, storage.store_headers,
storage.get_header_height_by_hash, and storage.clear to hold the TempDir
variable until after storage.clear() completes.

Comment on lines +434 to 443
storage.shutdown().await;
drop(storage);
let storage =
DiskStorageManager::new(temp_dir.path()).await.expect("Unable to open storage");

let loaded_headers = storage.load_headers(49_999..50_002).await.unwrap();
assert_eq!(loaded_headers.len(), 3);
assert_eq!(&loaded_headers, &headers[49_999..50_002]);

Ok(())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Stop the background worker before dropping storage instances.

Dropping DiskStorageManager without shutdown() leaves the background task running, which can keep writing to a temp path after the test finishes and cause flaky cleanup. Consider shutting down before drop, even in tests.

🔧 Suggested fix
@@
-        let storage =
-            DiskStorageManager::new(temp_dir.path()).await.expect("Unable to open storage");
+        let mut storage =
+            DiskStorageManager::new(temp_dir.path()).await.expect("Unable to open storage");
@@
         let loaded_headers = storage.load_headers(49_999..50_002).await.unwrap();
         assert_eq!(loaded_headers.len(), 3);
         assert_eq!(&loaded_headers, &headers[49_999..50_002]);
+        storage.shutdown().await;
@@
-            let storage = DiskStorageManager::new(&temp_dir.path()).await.unwrap();
+            let mut storage = DiskStorageManager::new(temp_dir.path()).await.unwrap();
@@
             for i in 0..10 {
                 let stored_header = storage.get_header(i).await.unwrap().unwrap();
                 let hash = stored_header.block_hash();
                 let height = storage.get_header_height_by_hash(&hash).await.unwrap();
                 assert_eq!(height, Some(i), "Height mismatch after reload for header {}", i);
             }
+            storage.shutdown().await;
@@
-        drop(storage1);
+        storage1.shutdown().await;
+        drop(storage1);

Also applies to: 523-535, 575-577

🤖 Prompt for AI Agents
In `@dash-spv/src/storage/mod.rs` around lines 434 - 443, The test drops
DiskStorageManager while its background worker may still be running; ensure you
call storage.shutdown().await before drop(storage) to stop the worker and avoid
post-test writes. Update the instances around DiskStorageManager::new(...) and
subsequent drop(storage) to invoke the async shutdown() on the storage handle
(e.g., call storage.shutdown().await) prior to dropping it; apply the same
change to the other similar blocks referenced (around the other occurrences
~lines 523-535 and 575-577).

Comment on lines +540 to +552
let mut storage =
DiskStorageManager::with_temp_dir().await.expect("Failed to create tmp storage");

// Store some headers
let header = BlockHeader::dummy_batch(0..1);
storage.store_headers(&header).await.unwrap();

let hash = header[0].block_hash();
assert!(storage.get_header_height_by_hash(&hash).await.unwrap().is_some());

// Clear storage
storage.clear().await.unwrap();

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Keep the TempDir alive for the storage lifetime.

DiskStorageManager::with_temp_dir() drops the TempDir immediately, which can delete the backing directory while the storage is still active. Use an explicit TempDir in the test to keep the directory alive.

🔧 Suggested fix
@@
-        let mut storage =
-            DiskStorageManager::with_temp_dir().await.expect("Failed to create tmp storage");
+        let temp_dir = TempDir::new().expect("Failed to create temp directory");
+        let mut storage =
+            DiskStorageManager::new(temp_dir.path()).await.expect("Failed to create tmp storage");
@@
         // Verify index is cleared
         assert!(storage.get_header_height_by_hash(&hash).await.unwrap().is_none());
+        storage.shutdown().await;
🤖 Prompt for AI Agents
In `@dash-spv/src/storage/mod.rs` around lines 540 - 552,
DiskStorageManager::with_temp_dir() currently drops the TempDir immediately,
risking deletion of the backing directory while storage is still used; fix the
test by creating and retaining an explicit TempDir (e.g., via tempfile::TempDir)
and passing its path into DiskStorageManager (or into DiskStorageManager::new)
so the TempDir lives for the lifetime of storage; update the test around
DiskStorageManager::with_temp_dir(), BlockHeader::dummy_batch,
storage.store_headers, storage.get_header_height_by_hash, and storage.clear to
hold the TempDir variable until after storage.clear() completes.

@xdustinface xdustinface merged commit d58987f into v0.42-dev Jan 18, 2026
53 checks passed
@xdustinface xdustinface deleted the refactor/storage-tests branch January 18, 2026 20:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants