Skip to content

fix: update tests/examples for upstream API changes and fix sync loop busy-loop#3057

Merged
jamiepine merged 2 commits into
spacedriveapp:mainfrom
slvnlrt:fix/test-compilation-errors
Apr 19, 2026
Merged

fix: update tests/examples for upstream API changes and fix sync loop busy-loop#3057
jamiepine merged 2 commits into
spacedriveapp:mainfrom
slvnlrt:fix/test-compilation-errors

Conversation

@slvnlrt

@slvnlrt slvnlrt commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Align error types in all examples and tests to match Core::new() / Core::shutdown() signatures (Box<dyn Error + Send + Sync>)
  • Update entry::ActiveModel field device_id to volume_id and add missing volume_id to location::ActiveModel in library_demo.rs
  • Add missing proxy_pairing and spacebot fields to AppConfig initializers in sync tests
  • Fix VolumeFingerprint tests to use new constructors (from_primary_volume, from_external_volume, from_network_volume)
  • Fix SecretKey::generate() in relay pairing test to use from_bytes pattern (rand_core 0.9 compatibility)
  • Fix SdPath::Physical.path type (PathBuf, not String) and thumbnail_url parameter type in sd-client example
  • Add ProxyPairingConfig re-export from config/mod.rs
  • Fix DeviceInfo and NetworkFingerprint struct fields in proxy pairing protocol test
  • Fix init_sync_service calls to unwrap Option<Arc<NetworkingService>>
  • Fix busy-loop in sync loop: continue in the Ready state skipped the sleep when is_realtime_active() was true, causing CPU-saturating spin. Replaced with if/else to fall through to sleep.

Root Cause

The core library (cargo build --lib -p sd-core) compiles fine, but API changes weren't propagated to examples and tests. Key changes: Core::new()/shutdown() error type gained Send + Sync, entry::Model renamed device_id to volume_id, VolumeFingerprint::new() removed in favor of purpose-specific constructors, AppConfig gained proxy_pairing and spacebot fields, and iroh upgraded rand_core breaking SecretKey::generate() with ThreadRng.

Additionally, a production bug in run_sync_loop() caused a busy-loop when real-time sync was active: continue skipped the sleep at the bottom of the loop.

Changes

  • 28 files changed across core/examples/, core/tests/, core/src/config/, core/src/service/sync/, and crates/sd-client/examples/
  • All fixes align callers with current API signatures, no hacks or workarounds

Align error types, struct fields, and constructor calls in 27 test/example
files to match current Core API:

- Box<dyn Error> -> Box<dyn Error + Send + Sync> to match Core::new()/shutdown()
- entry::ActiveModel device_id -> volume_id (field rename)
- location::ActiveModel add volume_id field (new nullable field)
- AppConfig add proxy_pairing and spacebot fields (config v5/v6)
- Re-export ProxyPairingConfig from config module
- VolumeFingerprint::new() -> from_primary/external/network_volume()
- DeviceInfo add device_type field, NetworkFingerprint public_key -> public_key_hash
- SecretKey::generate(thread_rng) -> from_bytes (rand_core version mismatch)
- SdPath::Physical.path String -> PathBuf, thumbnail_url &Uuid -> &str
- init_sync_service unwrap networking Option for Arc<dyn NetworkTransport>
@coderabbitai

coderabbitai Bot commented Apr 16, 2026

Copy link
Copy Markdown

Walkthrough

This PR broadens boxed error trait bounds to Send + Sync across examples and tests, re-exports ProxyPairingConfig from the config module, updates some test configurations, tweaks a few test constructions (pairing/relay, volume fingerprint tests), and adjusts Ready-state catch-up control flow in the sync service.

Changes

Cohort / File(s) Summary
Example Programs - Error Trait Bounds
core/examples/create_memory.rs, core/examples/file_type_demo.rs, core/examples/indexing_demo.rs, core/examples/job_logging_test.rs, core/examples/library_demo.rs, core/examples/pause_resume_demo.rs, core/examples/shutdown_demo.rs, core/examples/simple_pause_resume.rs, core/examples/test_migration.rs, core/examples/volume_demo.rs
Updated async main return types to Result<(), Box<dyn std::error::Error + Send + Sync>>. In library_demo.rs also adjusted ActiveModel initializers to set volume_id: Set(None) and removed device_id: Set(Some(...)).
Config Module
core/src/config/mod.rs
Added public re-export of ProxyPairingConfig to the module's pub use list.
Test Files - Error Trait Bounds
core/tests/ephemeral_watcher_test.rs, core/tests/event_system_test.rs, core/tests/file_structure_test.rs, core/tests/fs_watcher_test.rs, core/tests/job_resumption_integration_test.rs, core/tests/job_shutdown_test.rs, core/tests/normalized_cache_fixtures_test.rs, core/tests/phase_snapshot_test.rs, core/tests/resource_events_test.rs
Changed many test and helper signatures to return Box<dyn std::error::Error + Send + Sync> for Tokio/async compatibility; mostly signature bounds changes and some function-formatting adjustments.
Test Setup Configuration
core/tests/file_sync_simple_test.rs, core/tests/file_sync_test.rs
Updated AppConfig initialization to include proxy_pairing and spacebot set to default(); adjusted import path usage for ProxyPairingConfig.
Proxy / Relay / Pairing Tests
core/tests/proxy_pairing_protocol_test.rs, core/tests/relay_pairing_test.rs
proxy_pairing_protocol_test.rs: added device_type: DeviceType::Desktop and switched a fingerprint field to public_key_hash. relay_pairing_test.rs: replaced SecretKey::generate(...) with seed-based SecretKey::from_bytes(...) using rand::RngCore.
Sync Service Control Flow
core/src/service/sync/mod.rs
Adjusted Ready-state catch-up logic to remove an early continue and instead branch so realtime-active peers bypass per-peer catch-up while others proceed; restructured loop/brace flow.
Transitive Sync Tests
core/tests/transitive_sync_backfill_test.rs
Refactored to clone core.services.networking into a local networking with .expect(...) before passing into library.init_sync_service, introducing an explicit runtime expectation.
Volume Fingerprint Tests
core/tests/volume_fingerprint_stability_test.rs
Replaced generic VolumeFingerprint::new() usage with type-specific constructors (from_primary_volume, from_external_volume, from_network_volume); removed capacity-variation tests; adjusted assertions and output text/formatting.
Client Example
crates/sd-client/examples/test_connection.rs
Switched path init to .into() and converted content_id.uuid to String before calling client.thumbnail_url; minor formatting changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Hops through Send and Sync with cheer,
Errors now thread-safe, far and near.
Fingerprints steady, configs align,
Pairing seeds set, tests pass in time,
A rabbit nods — the code feels fine. 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: updating tests/examples for upstream API changes and fixing a sync loop busy-loop issue.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description check ✅ Passed PR description is comprehensive, covering all changes, root causes, and including a production bug fix with clear explanations.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
core/tests/relay_pairing_test.rs (1)

156-161: Use a fixed seed to keep this test reproducible.

The current seed comes from thread_rng(), so test inputs vary per run. A fixed non-zero 32-byte seed makes failures reproducible and keeps behavior stable.

Proposed change
-	use rand::RngCore;
-
-	// Use from_bytes to avoid CryptoRng trait bound mismatch between rand 0.8 and iroh's rand_core
-	let mut seed = [0u8; 32];
-	rand::thread_rng().fill_bytes(&mut seed);
-	let secret_key = SecretKey::from_bytes(&seed);
+	// Use a fixed seed to keep test behavior deterministic.
+	let seed = [7u8; 32];
+	let secret_key = SecretKey::from_bytes(&seed);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@core/tests/relay_pairing_test.rs` around lines 156 - 161, The test uses
rand::thread_rng().fill_bytes(&mut seed) which makes the seed non-deterministic;
replace this with a fixed non-zero 32-byte seed to make the test reproducible
(e.g., set seed = [1u8; 32] or a specific byte array) before calling
SecretKey::from_bytes(&seed), updating the code around the seed variable and the
SecretKey::from_bytes call to use the deterministic seed instead of thread_rng.
core/tests/proxy_pairing_protocol_test.rs (1)

182-185: Derive public_key_hash from the test public key instead of hard-coding it.

Using a literal hash that is unrelated to vouchee_public_key makes the payload fixture internally inconsistent and weakens this test’s realism. Prefer computing public_key_hash from the same key bytes used in vouchee_public_key.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@core/tests/proxy_pairing_protocol_test.rs` around lines 182 - 185, The test
currently hard-codes network_fingerprint.public_key_hash; instead derive it from
the same vouchee_public_key used in the fixture so the payload is consistent.
Replace the literal "abcdef..." with a computed value by hashing/parsing the
vouchee_public_key bytes using the identity module’s helper (use the same
function used in production in sd_core::service::network::utils::identity to
compute a public key hash) and assign that result to
NetworkFingerprint.public_key_hash so network_fingerprint and vouchee_public_key
remain consistent.
core/tests/volume_fingerprint_stability_test.rs (1)

61-63: Use tracing macros instead of println! for logging, but note that test files in this codebase predominantly use println! for test output.

While the coding guidelines recommend using tracing macros for all .rs files (including core/**/*.rs), an analysis of core/tests/ shows that 38 test files use println! compared to 23 using tracing macros. The current approach in volume_fingerprint_stability_test.rs aligns with the predominant test logging convention. If refactored to use tracing, you would need to add imports and ensure a tracing subscriber is initialized for the test context.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@core/tests/volume_fingerprint_stability_test.rs` around lines 61 - 63, The
test currently uses println! for output (calls to fp_vol1.short_id() and
fp_vol2.short_id()); change those println! calls to a tracing macro (e.g.,
tracing::info!) and ensure tracing is initialized in the test (add the tracing
import and initialize a subscriber once for the test context, e.g., via
tracing_subscriber::fmt::init() or a test-wide once setup) so the test logs
appear when run under the tracing system.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@core/tests/proxy_pairing_protocol_test.rs`:
- Around line 182-185: The test currently hard-codes
network_fingerprint.public_key_hash; instead derive it from the same
vouchee_public_key used in the fixture so the payload is consistent. Replace the
literal "abcdef..." with a computed value by hashing/parsing the
vouchee_public_key bytes using the identity module’s helper (use the same
function used in production in sd_core::service::network::utils::identity to
compute a public key hash) and assign that result to
NetworkFingerprint.public_key_hash so network_fingerprint and vouchee_public_key
remain consistent.

In `@core/tests/relay_pairing_test.rs`:
- Around line 156-161: The test uses rand::thread_rng().fill_bytes(&mut seed)
which makes the seed non-deterministic; replace this with a fixed non-zero
32-byte seed to make the test reproducible (e.g., set seed = [1u8; 32] or a
specific byte array) before calling SecretKey::from_bytes(&seed), updating the
code around the seed variable and the SecretKey::from_bytes call to use the
deterministic seed instead of thread_rng.

In `@core/tests/volume_fingerprint_stability_test.rs`:
- Around line 61-63: The test currently uses println! for output (calls to
fp_vol1.short_id() and fp_vol2.short_id()); change those println! calls to a
tracing macro (e.g., tracing::info!) and ensure tracing is initialized in the
test (add the tracing import and initialize a subscriber once for the test
context, e.g., via tracing_subscriber::fmt::init() or a test-wide once setup) so
the test logs appear when run under the tracing system.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 69d03af5-7ce3-4a1b-ae8c-e18372bd4d89

📥 Commits

Reviewing files that changed from the base of the PR and between fb5d4d7 and 1829f36.

📒 Files selected for processing (27)
  • core/examples/create_memory.rs
  • core/examples/file_type_demo.rs
  • core/examples/indexing_demo.rs
  • core/examples/job_logging_test.rs
  • core/examples/library_demo.rs
  • core/examples/pause_resume_demo.rs
  • core/examples/shutdown_demo.rs
  • core/examples/simple_pause_resume.rs
  • core/examples/test_migration.rs
  • core/examples/volume_demo.rs
  • core/src/config/mod.rs
  • core/tests/ephemeral_watcher_test.rs
  • core/tests/event_system_test.rs
  • core/tests/file_structure_test.rs
  • core/tests/file_sync_simple_test.rs
  • core/tests/file_sync_test.rs
  • core/tests/fs_watcher_test.rs
  • core/tests/job_resumption_integration_test.rs
  • core/tests/job_shutdown_test.rs
  • core/tests/normalized_cache_fixtures_test.rs
  • core/tests/phase_snapshot_test.rs
  • core/tests/proxy_pairing_protocol_test.rs
  • core/tests/relay_pairing_test.rs
  • core/tests/resource_events_test.rs
  • core/tests/transitive_sync_backfill_test.rs
  • core/tests/volume_fingerprint_stability_test.rs
  • crates/sd-client/examples/test_connection.rs

The sync loop's Ready state used 'continue' when is_realtime_active()
returned true, which skipped the sleep at the bottom of the loop and
caused a CPU-saturating busy-loop logging 'Skipping catch-up' hundreds
of thousands of times per second. Replace with if/else so the
realtime-active branch falls through to the configurable sleep.
@slvnlrt slvnlrt changed the title fix(core): update tests and examples for upstream API changes fix: update tests/examples for upstream API changes and fix sync loop busy-loop Apr 16, 2026
@jamiepine jamiepine merged commit c63f1b0 into spacedriveapp:main Apr 19, 2026
1 check passed
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.

2 participants