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 ;
89use std:: panic:: RefUnwindSafe ;
910use std:: path:: PathBuf ;
1011use 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+
171197pub ( 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