Skip to content

Commit 8f009d7

Browse files
committed
f - Catch async KVStore test panics
Catch invalid-write panics while polling async KVStore futures so the shared store helper still accepts debug assertions from stores that validate inside the returned future. Co-Authored-By: HAL 9000
1 parent c8620d4 commit 8f009d7

1 file changed

Lines changed: 29 additions & 12 deletions

File tree

src/io/test_utils.rs

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// http://opensource.org/licenses/MIT>, at your option. You may not use this file except in
66
// accordance with one or both of these licenses.
77

8+
use std::future::Future;
89
use std::panic::RefUnwindSafe;
910
use std::path::PathBuf;
1011
use std::sync::Arc;
@@ -168,6 +169,31 @@ pub(crate) fn random_storage_path() -> PathBuf {
168169
temp_path
169170
}
170171

172+
async fn catch_future_unwind<F: Future>(future: F) -> std::thread::Result<F::Output> {
173+
let mut future = std::pin::pin!(future);
174+
std::future::poll_fn(|cx| {
175+
match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| future.as_mut().poll(cx))) {
176+
Ok(std::task::Poll::Ready(output)) => std::task::Poll::Ready(Ok(output)),
177+
Ok(std::task::Poll::Pending) => std::task::Poll::Pending,
178+
Err(panic) => std::task::Poll::Ready(Err(panic)),
179+
}
180+
})
181+
.await
182+
}
183+
184+
async fn assert_invalid_write_fails<K: KVStore + RefUnwindSafe>(
185+
kv_store: &K, primary_namespace: &str, secondary_namespace: &str, key: &str, data: Vec<u8>,
186+
) {
187+
let res = std::panic::catch_unwind(|| {
188+
KVStore::write(kv_store, primary_namespace, secondary_namespace, key, data)
189+
});
190+
if let Ok(fut) = res {
191+
if let Ok(write_res) = catch_future_unwind(fut).await {
192+
assert!(write_res.is_err());
193+
}
194+
}
195+
}
196+
171197
pub(crate) async fn do_read_write_remove_list_persist<K: KVStore + RefUnwindSafe>(kv_store: &K) {
172198
let data = vec![42u8; 32];
173199

@@ -183,18 +209,9 @@ pub(crate) async fn do_read_write_remove_list_persist<K: KVStore + RefUnwindSafe
183209
// Test empty primary/secondary namespaces are allowed, but not empty primary namespace and non-empty
184210
// secondary primary_namespace, and not empty key.
185211
KVStore::write(kv_store, "", "", key, data.clone()).await.unwrap();
186-
let res = std::panic::catch_unwind(|| {
187-
KVStore::write(kv_store, "", secondary_namespace, key, data.clone())
188-
});
189-
if let Ok(fut) = res {
190-
assert!(fut.await.is_err());
191-
}
192-
let res = std::panic::catch_unwind(|| {
193-
KVStore::write(kv_store, primary_namespace, secondary_namespace, "", data.clone())
194-
});
195-
if let Ok(fut) = res {
196-
assert!(fut.await.is_err());
197-
}
212+
assert_invalid_write_fails(kv_store, "", secondary_namespace, key, data.clone()).await;
213+
assert_invalid_write_fails(kv_store, primary_namespace, secondary_namespace, "", data.clone())
214+
.await;
198215

199216
let listed_keys =
200217
KVStore::list(kv_store, primary_namespace, secondary_namespace).await.unwrap();

0 commit comments

Comments
 (0)