pub struct InMemoryCloudHome { /* private fields */ }Expand description
In-memory CloudHome backed by a HashMap. Clone shares one backing store, so
clones act as separate devices reading and writing the same cloud bucket, and
a test can keep its own handle for direct at-rest assertions while each device
owns a Box<dyn CloudHome> clone.
Beyond the happy path it carries fault-injection knobs
(arm_write_failures,
fail_next_range_reads,
remove) so a host test can drive upload-failure,
read-retry, and missing-blob paths without a bespoke CloudHome impl. The
arming state is shared across clones, like the backing store.
Implementations§
Source§impl InMemoryCloudHome
impl InMemoryCloudHome
pub fn new() -> InMemoryCloudHome
pub fn with_provider_binding( self, binding: ResolvedProviderBinding, ) -> InMemoryCloudHome
Sourcepub fn sort_listings(&self)
pub fn sort_listings(&self)
Return list results in sorted key order instead of the backing map’s
arbitrary order. A real bucket LIST has no defined order, so the pull’s
cross-device apply order is arbitrary; a test that needs a fixed order (to
reproduce an order-dependent bug deterministically) arms this and picks the
order through its device ids.
Sourcepub fn arm_write_failures(&self)
pub fn arm_write_failures(&self)
Arm every subsequent write (put_object and open_multipart) to fail
with a retryable transport error. A test can let a home’s setup writes
land and then arm this before driving the path whose uploads must fail;
it stays armed for the store’s lifetime.
Sourcepub fn fail_next_range_reads(&self, n: usize)
pub fn fail_next_range_reads(&self, n: usize)
Make the next n read_range calls fail with a retryable transport
error before any serves bytes, to exercise a caller’s read-retry path.
Each failed call consumes one; once n are spent, ranges serve
normally.
Sourcepub fn fail_exact_create_before_call(&self, call: usize)
pub fn fail_exact_create_before_call(&self, call: usize)
Reset the exact-create counter and fail before the selected call stores bytes.
Sourcepub fn fail_exact_create_after_call(&self, call: usize)
pub fn fail_exact_create_after_call(&self, call: usize)
Reset the exact-create counter and lose the response after the selected create.
Sourcepub fn corrupt_exact_readback_on_call(&self, call: usize)
pub fn corrupt_exact_readback_on_call(&self, call: usize)
Replace the selected exact object’s bytes before its verification read.
Sourcepub fn pause_after_exact_create_call(
&self,
call: usize,
) -> (Arc<Notify>, Arc<Notify>)
pub fn pause_after_exact_create_call( &self, call: usize, ) -> (Arc<Notify>, Arc<Notify>)
Pause after the selected exact create is physically visible.
Sourcepub fn pause_next_probe(&self) -> (Arc<Notify>, Arc<Notify>)
pub fn pause_next_probe(&self) -> (Arc<Notify>, Arc<Notify>)
Pause the next reachability probe after it starts and before it succeeds.
pub fn exact_create_count(&self) -> usize
pub fn exact_full_read_count(&self) -> usize
pub fn exact_stream_read_count(&self) -> usize
pub fn arm_exact_stream_read_concurrency_probe(&self, width: usize)
pub fn exact_stream_read_max_inflight(&self) -> usize
pub fn exact_delete_count(&self) -> usize
pub fn fail_exact_delete_on_call(&self, call: usize)
pub fn fail_coordination_probe_cleanup(&self)
pub fn head_mutation_count(&self) -> usize
pub fn fail_next_head_mutation_after_visibility(&self)
pub fn replace_after_next_head_mutation(&self, replacement: Vec<u8>)
Sourcepub fn remove(&self, key: &str)
pub fn remove(&self, key: &str)
Drop key’s bytes out of band — as if the object vanished from the
bucket on its own, without a delete (which deletes_seen would
record). Drives missing-blob read failures.
Sourcepub fn keys(&self) -> Vec<String>
pub fn keys(&self) -> Vec<String>
Snapshot of every key currently in the cloud. Useful for assertions that don’t want to hold the lock across an await.
Sourcepub fn get(&self, key: &str) -> Option<Vec<u8>>
pub fn get(&self, key: &str) -> Option<Vec<u8>>
Snapshot of the bytes at key, or None if absent. Cloned so the
caller can hold the result across await points without retaining
the internal lock.
Sourcepub fn deletes_seen(&self) -> Vec<String>
pub fn deletes_seen(&self) -> Vec<String>
Snapshot of every delete that’s been requested, in arrival order.
Sourcepub fn insert_exact_object(
&self,
logical_key: &str,
bytes: Vec<u8>,
) -> ObjectSlot
pub fn insert_exact_object( &self, logical_key: &str, bytes: Vec<u8>, ) -> ObjectSlot
Insert caller-selected bytes at one exact logical slot.
Sourcepub fn remove_exact_object(&self, slot: &ObjectSlot)
pub fn remove_exact_object(&self, slot: &ObjectSlot)
Remove one exact object without recording a protocol delete.
Sourcepub fn replace_exact_object(&self, slot: &ObjectSlot, bytes: Vec<u8>)
pub fn replace_exact_object(&self, slot: &ObjectSlot, bytes: Vec<u8>)
Replace bytes at one exact slot without changing its locator.
Trait Implementations§
Source§impl Clone for InMemoryCloudHome
impl Clone for InMemoryCloudHome
Source§fn clone(&self) -> InMemoryCloudHome
fn clone(&self) -> InMemoryCloudHome
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl CloudHome for InMemoryCloudHome
impl CloudHome for InMemoryCloudHome
fn exact_slot_storage( self: Arc<InMemoryCloudHome>, ) -> Option<Arc<dyn ExactSlotStorage>>
Source§fn probe<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
InMemoryCloudHome: 'async_trait,
fn probe<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
InMemoryCloudHome: 'async_trait,
Source§fn put_object<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
data: Vec<u8>,
) -> Pin<Box<dyn Future<Output = Result<(), CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
InMemoryCloudHome: 'async_trait,
fn put_object<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
data: Vec<u8>,
) -> Pin<Box<dyn Future<Output = Result<(), CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
InMemoryCloudHome: 'async_trait,
key. Used only
for blobs at or below multipart_threshold;
large blobs stream through open_multipart.Source§fn open_multipart<'a, 'life0, 'async_trait>(
&'a self,
key: &'life0 str,
total_len: u64,
) -> Pin<Box<dyn Future<Output = Result<Box<dyn PartSink + 'a>, CloudHomeError>> + Send + 'async_trait>>where
'a: 'async_trait,
'life0: 'async_trait,
InMemoryCloudHome: 'async_trait,
fn open_multipart<'a, 'life0, 'async_trait>(
&'a self,
key: &'life0 str,
total_len: u64,
) -> Pin<Box<dyn Future<Output = Result<Box<dyn PartSink + 'a>, CloudHomeError>> + Send + 'async_trait>>where
'a: 'async_trait,
'life0: 'async_trait,
InMemoryCloudHome: 'async_trait,
total_len bytes, returning
the PartSink the driver pumps ordered parts into.Source§fn multipart_threshold(&self) -> u64
fn multipart_threshold(&self) -> u64
put_object;
larger ones stream via open_multipart.Source§fn read<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
InMemoryCloudHome: 'async_trait,
fn read<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
InMemoryCloudHome: 'async_trait,
Source§fn read_range<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
start: u64,
end: u64,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
InMemoryCloudHome: 'async_trait,
fn read_range<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
start: u64,
end: u64,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
InMemoryCloudHome: 'async_trait,
start is inclusive, end is exclusive.Source§fn list<'life0, 'life1, 'async_trait>(
&'life0 self,
prefix: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<String>, CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
InMemoryCloudHome: 'async_trait,
fn list<'life0, 'life1, 'async_trait>(
&'life0 self,
prefix: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<String>, CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
InMemoryCloudHome: 'async_trait,
Source§fn delete<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(), CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
InMemoryCloudHome: 'async_trait,
fn delete<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(), CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
InMemoryCloudHome: 'async_trait,
Source§fn exists<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
InMemoryCloudHome: 'async_trait,
fn exists<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
InMemoryCloudHome: 'async_trait,
Source§fn set_access<'life0, 'async_trait>(
&'life0 self,
desired: CloudAccessState,
) -> Pin<Box<dyn Future<Output = Result<CloudAccessOutcome, CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
InMemoryCloudHome: 'async_trait,
fn set_access<'life0, 'async_trait>(
&'life0 self,
desired: CloudAccessState,
) -> Pin<Box<dyn Future<Output = Result<CloudAccessOutcome, CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
InMemoryCloudHome: 'async_trait,
Present returns connection information; Absent returns
whether this provider supports withdrawing one member’s credential.Source§fn write<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
key: &'life1 str,
body: BlobBody,
progress: &'life2 (dyn Fn(u64) + Sync + Send + 'life3),
) -> Pin<Box<dyn Future<Output = Result<(), CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Self: 'async_trait,
fn write<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
key: &'life1 str,
body: BlobBody,
progress: &'life2 (dyn Fn(u64) + Sync + Send + 'life3),
) -> Pin<Box<dyn Future<Output = Result<(), CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Self: 'async_trait,
BlobBody to key. Not overridden — the central
[write_blob] driver picks single-request vs multipart and pumps the
parts, reporting cumulative bytes through progress for the per-file bar.Source§impl Default for InMemoryCloudHome
impl Default for InMemoryCloudHome
Source§fn default() -> InMemoryCloudHome
fn default() -> InMemoryCloudHome
Source§impl ExactSlotStorage for InMemoryCloudHome
impl ExactSlotStorage for InMemoryCloudHome
fn provider_binding<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<ResolvedProviderBinding, CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
InMemoryCloudHome: 'async_trait,
fn allocate_slot<'life0, 'life1, 'async_trait>(
&'life0 self,
logical_key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<ObjectSlot, CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
InMemoryCloudHome: 'async_trait,
fn create_at<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
slot: &'life1 ObjectSlot,
body: BlobBody,
progress: &'life2 (dyn Fn(u64) + Sync + Send + 'life3),
) -> Pin<Box<dyn Future<Output = Result<(), CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
InMemoryCloudHome: 'async_trait,
fn read_at<'life0, 'life1, 'async_trait>(
&'life0 self,
slot: &'life1 ObjectSlot,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
InMemoryCloudHome: 'async_trait,
fn read_range_at<'life0, 'life1, 'async_trait>(
&'life0 self,
slot: &'life1 ObjectSlot,
start: u64,
end: u64,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
InMemoryCloudHome: 'async_trait,
fn read_at_to_file<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
slot: &'life1 ObjectSlot,
destination: &'life2 Path,
) -> Pin<Box<dyn Future<Output = Result<(), CloudFileReadError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
InMemoryCloudHome: 'async_trait,
fn delete_at<'life0, 'life1, 'async_trait>(
&'life0 self,
slot: &'life1 ObjectSlot,
) -> Pin<Box<dyn Future<Output = Result<(), CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
InMemoryCloudHome: 'async_trait,
fn cross_principal_evidence<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<CrossPrincipalProviderEvidence, CloudHomeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Auto Trait Implementations§
impl Freeze for InMemoryCloudHome
impl RefUnwindSafe for InMemoryCloudHome
impl Send for InMemoryCloudHome
impl Sync for InMemoryCloudHome
impl Unpin for InMemoryCloudHome
impl UnsafeUnpin for InMemoryCloudHome
impl UnwindSafe for InMemoryCloudHome
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more