@@ -189,14 +189,18 @@ pub async fn run_gc(store: Store, config: GcConfig) {
189189
190190#[ cfg( test) ]
191191mod tests {
192- use std:: path:: Path ;
192+ use std:: {
193+ io:: { self } ,
194+ path:: Path ,
195+ } ;
193196
194- use bao_tree:: ChunkNum ;
197+ use bao_tree:: { io:: EncodeError , ChunkNum } ;
198+ use range_collections:: RangeSet2 ;
195199 use testresult:: TestResult ;
196200
197201 use super :: * ;
198202 use crate :: {
199- api:: { blobs:: AddBytesOptions , Store } ,
203+ api:: { blobs:: AddBytesOptions , ExportBaoError , RequestError , Store } ,
200204 hashseq:: HashSeq ,
201205 store:: fs:: { options:: PathOptions , tests:: create_n0_bao} ,
202206 BlobFormat ,
@@ -326,4 +330,83 @@ mod tests {
326330 gc_smoke ( & store) . await ?;
327331 Ok ( ( ) )
328332 }
333+
334+ #[ tokio:: test]
335+ async fn gc_check_deletion_fs ( ) -> TestResult {
336+ tracing_subscriber:: fmt:: try_init ( ) . ok ( ) ;
337+ let testdir = tempfile:: tempdir ( ) ?;
338+ let db_path = testdir. path ( ) . join ( "db" ) ;
339+ let store = crate :: store:: fs:: FsStore :: load ( & db_path) . await ?;
340+ gc_check_deletion ( & store) . await
341+ }
342+
343+ #[ tokio:: test]
344+ async fn gc_check_deletion_mem ( ) -> TestResult {
345+ tracing_subscriber:: fmt:: try_init ( ) . ok ( ) ;
346+ let store = crate :: store:: mem:: MemStore :: default ( ) ;
347+ gc_check_deletion ( & store) . await
348+ }
349+
350+ async fn gc_check_deletion ( store : & Store ) -> TestResult {
351+ let temp_tag = store. add_bytes ( b"foo" . to_vec ( ) ) . temp_tag ( ) . await ?;
352+ let hash = * temp_tag. hash ( ) ;
353+ assert_eq ! ( store. get_bytes( hash) . await ?. as_ref( ) , b"foo" ) ;
354+ drop ( temp_tag) ;
355+ let mut live = HashSet :: new ( ) ;
356+ gc_run_once ( & store, & mut live) . await ?;
357+
358+ // check that `get_bytes` returns an error.
359+ let res = store. get_bytes ( hash) . await ;
360+ assert ! ( res. is_err( ) ) ;
361+ assert ! ( matches!(
362+ res,
363+ Err ( ExportBaoError :: ExportBaoInner {
364+ source: EncodeError :: Io ( cause) ,
365+ ..
366+ } ) if cause. kind( ) == io:: ErrorKind :: NotFound
367+ ) ) ;
368+
369+ // check that `export_ranges` returns an error.
370+ let res = store
371+ . export_ranges ( hash, RangeSet2 :: all ( ) )
372+ . concatenate ( )
373+ . await ;
374+ assert ! ( res. is_err( ) ) ;
375+ assert ! ( matches!(
376+ res,
377+ Err ( RequestError :: Inner {
378+ source: crate :: api:: Error :: Io ( cause) ,
379+ ..
380+ } ) if cause. kind( ) == io:: ErrorKind :: NotFound
381+ ) ) ;
382+
383+ // check that `export_bao` returns an error.
384+ let res = store
385+ . export_bao ( hash, ChunkRanges :: all ( ) )
386+ . bao_to_vec ( )
387+ . await ;
388+ assert ! ( res. is_err( ) ) ;
389+ println ! ( "export_bao res {res:?}" ) ;
390+ assert ! ( matches!(
391+ res,
392+ Err ( RequestError :: Inner {
393+ source: crate :: api:: Error :: Io ( cause) ,
394+ ..
395+ } ) if cause. kind( ) == io:: ErrorKind :: NotFound
396+ ) ) ;
397+
398+ // check that `export` returns an error.
399+ let target = tempfile:: NamedTempFile :: new ( ) ?;
400+ let path = target. path ( ) ;
401+ let res = store. export ( hash, path) . await ;
402+ assert ! ( res. is_err( ) ) ;
403+ assert ! ( matches!(
404+ res,
405+ Err ( RequestError :: Inner {
406+ source: crate :: api:: Error :: Io ( cause) ,
407+ ..
408+ } ) if cause. kind( ) == io:: ErrorKind :: NotFound
409+ ) ) ;
410+ Ok ( ( ) )
411+ }
329412}
0 commit comments