diff --git a/seaweed-volume/src/server/grpc_server.rs b/seaweed-volume/src/server/grpc_server.rs index a4158e98c..e0d204fad 100644 --- a/seaweed-volume/src/server/grpc_server.rs +++ b/seaweed-volume/src/server/grpc_server.rs @@ -4192,6 +4192,7 @@ mod tests { let addr = listener.local_addr().unwrap(); listener.set_nonblocking(true).unwrap(); let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel::<()>(); + let (ready_tx, ready_rx) = std::sync::mpsc::channel::<()>(); std::thread::spawn(move || { let runtime = tokio::runtime::Builder::new_current_thread() @@ -4253,6 +4254,7 @@ mod tests { })); let listener = tokio::net::TcpListener::from_std(listener).unwrap(); + let _ = ready_tx.send(()); axum::serve(listener, app) .with_graceful_shutdown(async move { let _ = shutdown_rx.await; @@ -4262,6 +4264,8 @@ mod tests { }); }); + // Wait for the server thread to be ready before returning. + ready_rx.recv().unwrap(); (format!("http://{}", addr), shutdown_tx) } diff --git a/seaweed-volume/src/storage/store.rs b/seaweed-volume/src/storage/store.rs index 98ffd3d04..3c2cc4328 100644 --- a/seaweed-volume/src/storage/store.rs +++ b/seaweed-volume/src/storage/store.rs @@ -1158,7 +1158,13 @@ mod tests { Vec::new(), ) .unwrap(); - store.volume_size_limit.store(1024, Ordering::Relaxed); + // Use a large volume_size_limit so the unused-space difference between + // preallocate=true (0) and preallocate=false (~2 × limit) is big enough + // that integer-division rounding and disk-free fluctuations between the + // two get_disk_stats calls cannot make the quotients equal. + store + .volume_size_limit + .store(100 * 1024 * 1024, Ordering::Relaxed); store .add_volume( VolumeId(61), diff --git a/seaweed-volume/src/storage/volume.rs b/seaweed-volume/src/storage/volume.rs index 28dc761d1..5e4688115 100644 --- a/seaweed-volume/src/storage/volume.rs +++ b/seaweed-volume/src/storage/volume.rs @@ -3225,6 +3225,7 @@ mod tests { let addr = listener.local_addr().unwrap(); listener.set_nonblocking(true).unwrap(); let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel::<()>(); + let (ready_tx, ready_rx) = std::sync::mpsc::channel::<()>(); std::thread::spawn(move || { let runtime = tokio::runtime::Builder::new_current_thread() @@ -3279,6 +3280,7 @@ mod tests { })); let listener = tokio::net::TcpListener::from_std(listener).unwrap(); + let _ = ready_tx.send(()); axum::serve(listener, app) .with_graceful_shutdown(async move { let _ = shutdown_rx.await; @@ -3288,6 +3290,8 @@ mod tests { }); }); + // Wait for the server thread to be ready before returning. + ready_rx.recv().unwrap(); (format!("http://{}", addr), shutdown_tx) } @@ -3833,7 +3837,7 @@ mod tests { let vif = VifVolumeInfo { files: vec![VifRemoteFile { backend_type: "s3".to_string(), - backend_id: "default".to_string(), + backend_id: "vif_rw_test".to_string(), key: "remote-key".to_string(), offset: 0, file_size: v.dat_file_size().unwrap(), @@ -3849,6 +3853,27 @@ mod tests { ) .unwrap(); + // Register a dummy S3 backend so load_remote_dat_file can look it + // up. This test never reads remote data, so a dead endpoint is fine. + // Use a test-specific backend_id to avoid racing with other tests + // that share the global registry. + let tier_config = crate::remote_storage::s3_tier::S3TierConfig { + access_key: "access".to_string(), + secret_key: "secret".to_string(), + region: "us-east-1".to_string(), + bucket: "bucket-a".to_string(), + endpoint: "http://127.0.0.1:1".to_string(), + storage_class: "STANDARD".to_string(), + force_path_style: true, + }; + crate::remote_storage::s3_tier::global_s3_tier_registry() + .write() + .unwrap() + .register( + "s3.vif_rw_test".to_string(), + crate::remote_storage::s3_tier::S3TierBackend::new(&tier_config), + ); + v.dat_file_size().unwrap() };