2019-12-04 16:08:03 +01:00
use std ::path ::PathBuf ;
2021-10-08 11:19:37 +02:00
use anyhow ::Error ;
2021-09-10 09:21:27 +02:00
use pbs_api_types ::PruneOptions ;
2021-09-01 12:32:21 +02:00
use pbs_datastore ::manifest ::MANIFEST_BLOB_NAME ;
2021-09-10 09:21:27 +02:00
use pbs_datastore ::prune ::compute_prune_info ;
2021-09-01 12:32:21 +02:00
use pbs_datastore ::{ BackupDir , BackupInfo } ;
2019-12-04 16:08:03 +01:00
fn get_prune_list (
list : Vec < BackupInfo > ,
2019-12-05 19:01:51 +01:00
return_kept : bool ,
2019-12-06 08:56:27 +01:00
options : & PruneOptions ,
2019-12-04 16:08:03 +01:00
) -> Vec < PathBuf > {
2019-12-06 08:56:27 +01:00
let mut prune_info = compute_prune_info ( list , options ) . unwrap ( ) ;
2019-12-04 16:08:03 +01:00
2019-12-05 13:13:30 +01:00
prune_info . reverse ( ) ;
2019-12-05 19:01:51 +01:00
2019-12-05 13:13:30 +01:00
prune_info
2019-12-04 16:08:03 +01:00
. iter ( )
2021-10-27 13:22:28 +02:00
. filter_map ( | ( info , mark ) | {
if mark . keep ( ) ! = return_kept {
2019-12-05 13:13:30 +01:00
None
} else {
Some ( info . backup_dir . relative_path ( ) )
}
} )
2019-12-04 16:08:03 +01:00
. collect ( )
}
2022-04-10 17:49:26 +02:00
fn create_info ( snapshot : & str , partial : bool ) -> BackupInfo {
2022-04-19 10:38:46 +02:00
let backup_dir = BackupDir ::new_test ( snapshot . parse ( ) . unwrap ( ) ) ;
2019-12-05 16:47:08 +01:00
let mut files = Vec ::new ( ) ;
if ! partial {
files . push ( String ::from ( MANIFEST_BLOB_NAME ) ) ;
}
2019-12-05 19:01:51 +01:00
2022-04-10 17:49:26 +02:00
BackupInfo {
backup_dir ,
files ,
protected : false ,
}
2019-12-05 16:47:08 +01:00
}
2019-12-06 08:56:27 +01:00
2022-04-10 17:49:26 +02:00
fn create_info_protected ( snapshot : & str , partial : bool ) -> BackupInfo {
2021-10-27 13:22:29 +02:00
let mut info = create_info ( snapshot , partial ) ;
info . protected = true ;
info
}
#[ test ]
fn test_prune_protected ( ) -> Result < ( ) , Error > {
let mut orig_list = Vec ::new ( ) ;
2022-04-10 17:49:26 +02:00
orig_list . push ( create_info_protected (
" host/elsa/2019-11-15T09:39:15Z " ,
false ,
) ) ;
2021-10-27 13:22:29 +02:00
orig_list . push ( create_info ( " host/elsa/2019-11-15T10:39:15Z " , false ) ) ;
orig_list . push ( create_info ( " host/elsa/2019-11-15T10:49:15Z " , false ) ) ;
2022-04-10 17:49:26 +02:00
orig_list . push ( create_info_protected (
" host/elsa/2019-11-15T10:59:15Z " ,
false ,
) ) ;
2021-10-27 13:22:29 +02:00
eprintln! ( " {:?} " , orig_list ) ;
let mut options = PruneOptions ::default ( ) ;
options . keep_last = Some ( 1 ) ;
let remove_list = get_prune_list ( orig_list . clone ( ) , false , & options ) ;
2022-04-10 17:49:26 +02:00
let expect : Vec < PathBuf > = vec! [ PathBuf ::from ( " host/elsa/2019-11-15T10:39:15Z " ) ] ;
2021-10-27 13:22:29 +02:00
assert_eq! ( remove_list , expect ) ;
let mut options = PruneOptions ::default ( ) ;
options . keep_hourly = Some ( 1 ) ;
let remove_list = get_prune_list ( orig_list . clone ( ) , false , & options ) ;
2022-04-10 17:49:26 +02:00
let expect : Vec < PathBuf > = vec! [ PathBuf ::from ( " host/elsa/2019-11-15T10:39:15Z " ) ] ;
2021-10-27 13:22:29 +02:00
assert_eq! ( remove_list , expect ) ;
Ok ( ( ) )
}
2019-12-05 19:01:51 +01:00
#[ test ]
2019-12-07 11:23:33 +01:00
fn test_prune_hourly ( ) -> Result < ( ) , Error > {
let mut orig_list = Vec ::new ( ) ;
orig_list . push ( create_info ( " host/elsa/2019-11-15T09:39:15Z " , false ) ) ;
orig_list . push ( create_info ( " host/elsa/2019-11-15T10:49:15Z " , false ) ) ;
orig_list . push ( create_info ( " host/elsa/2019-11-15T10:59:15Z " , false ) ) ;
orig_list . push ( create_info ( " host/elsa/2019-11-15T11:39:15Z " , false ) ) ;
orig_list . push ( create_info ( " host/elsa/2019-11-15T11:49:15Z " , false ) ) ;
orig_list . push ( create_info ( " host/elsa/2019-11-15T11:59:15Z " , false ) ) ;
let list = orig_list . clone ( ) ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_hourly = Some ( 3 ) ;
2019-12-07 11:23:33 +01:00
let remove_list = get_prune_list ( list , false , & options ) ;
let expect : Vec < PathBuf > = vec! [
PathBuf ::from ( " host/elsa/2019-11-15T10:49:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-11-15T11:39:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-11-15T11:49:15Z " ) ,
] ;
assert_eq! ( remove_list , expect ) ;
2021-01-15 14:38:27 +01:00
let list = orig_list ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_hourly = Some ( 2 ) ;
2019-12-07 11:23:33 +01:00
let remove_list = get_prune_list ( list , true , & options ) ;
let expect : Vec < PathBuf > = vec! [
PathBuf ::from ( " host/elsa/2019-11-15T10:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-11-15T11:59:15Z " ) ,
] ;
assert_eq! ( remove_list , expect ) ;
Ok ( ( ) )
}
2021-09-10 09:21:27 +02:00
#[ test ]
2019-12-05 19:01:51 +01:00
fn test_prune_simple2 ( ) -> Result < ( ) , Error > {
let mut orig_list = Vec ::new ( ) ;
orig_list . push ( create_info ( " host/elsa/2018-11-15T11:59:15Z " , false ) ) ;
orig_list . push ( create_info ( " host/elsa/2019-11-15T11:59:15Z " , false ) ) ;
orig_list . push ( create_info ( " host/elsa/2019-11-21T11:59:15Z " , false ) ) ;
orig_list . push ( create_info ( " host/elsa/2019-11-22T11:59:15Z " , false ) ) ;
orig_list . push ( create_info ( " host/elsa/2019-11-29T11:59:15Z " , false ) ) ;
orig_list . push ( create_info ( " host/elsa/2019-12-01T11:59:15Z " , false ) ) ;
orig_list . push ( create_info ( " host/elsa/2019-12-02T11:59:15Z " , false ) ) ;
orig_list . push ( create_info ( " host/elsa/2019-12-03T11:59:15Z " , false ) ) ;
orig_list . push ( create_info ( " host/elsa/2019-12-04T11:59:15Z " , false ) ) ;
let list = orig_list . clone ( ) ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_daily = Some ( 1 ) ;
2019-12-06 08:56:27 +01:00
let remove_list = get_prune_list ( list , true , & options ) ;
2022-04-10 17:49:26 +02:00
let expect : Vec < PathBuf > = vec! [ PathBuf ::from ( " host/elsa/2019-12-04T11:59:15Z " ) ] ;
2019-12-05 19:01:51 +01:00
assert_eq! ( remove_list , expect ) ;
let list = orig_list . clone ( ) ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_last = Some ( 1 ) ;
options . keep_daily = Some ( 1 ) ;
2019-12-06 08:56:27 +01:00
let remove_list = get_prune_list ( list , true , & options ) ;
2019-12-05 19:01:51 +01:00
let expect : Vec < PathBuf > = vec! [
PathBuf ::from ( " host/elsa/2019-12-03T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-04T11:59:15Z " ) ,
] ;
assert_eq! ( remove_list , expect ) ;
let list = orig_list . clone ( ) ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_daily = Some ( 1 ) ;
options . keep_weekly = Some ( 1 ) ;
2019-12-06 08:56:27 +01:00
let remove_list = get_prune_list ( list , true , & options ) ;
2019-12-05 19:01:51 +01:00
let expect : Vec < PathBuf > = vec! [
PathBuf ::from ( " host/elsa/2019-12-01T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-04T11:59:15Z " ) ,
] ;
assert_eq! ( remove_list , expect ) ;
let list = orig_list . clone ( ) ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_daily = Some ( 1 ) ;
options . keep_weekly = Some ( 1 ) ;
options . keep_monthly = Some ( 1 ) ;
2019-12-06 08:56:27 +01:00
let remove_list = get_prune_list ( list , true , & options ) ;
2019-12-05 19:01:51 +01:00
let expect : Vec < PathBuf > = vec! [
PathBuf ::from ( " host/elsa/2019-11-22T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-01T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-04T11:59:15Z " ) ,
] ;
assert_eq! ( remove_list , expect ) ;
2021-01-15 14:38:27 +01:00
let list = orig_list ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_monthly = Some ( 1 ) ;
options . keep_yearly = Some ( 1 ) ;
2019-12-06 08:56:27 +01:00
let remove_list = get_prune_list ( list , true , & options ) ;
2019-12-05 19:01:51 +01:00
let expect : Vec < PathBuf > = vec! [
PathBuf ::from ( " host/elsa/2018-11-15T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-04T11:59:15Z " ) ,
] ;
assert_eq! ( remove_list , expect ) ;
Ok ( ( ) )
}
2019-12-05 16:47:08 +01:00
2019-12-04 16:08:03 +01:00
#[ test ]
fn test_prune_simple ( ) -> Result < ( ) , Error > {
2019-12-05 16:47:08 +01:00
let mut orig_list = Vec ::new ( ) ;
2019-12-04 16:08:03 +01:00
2019-12-05 16:47:08 +01:00
orig_list . push ( create_info ( " host/elsa/2019-12-02T11:59:15Z " , false ) ) ;
orig_list . push ( create_info ( " host/elsa/2019-12-03T11:59:15Z " , false ) ) ;
orig_list . push ( create_info ( " host/elsa/2019-12-04T11:59:15Z " , false ) ) ;
orig_list . push ( create_info ( " host/elsa/2019-12-04T12:59:15Z " , false ) ) ;
2019-12-04 16:08:03 +01:00
// keep-last tests
let list = orig_list . clone ( ) ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_last = Some ( 4 ) ;
2019-12-06 08:56:27 +01:00
let remove_list = get_prune_list ( list , false , & options ) ;
2019-12-04 16:08:03 +01:00
let expect : Vec < PathBuf > = Vec ::new ( ) ;
assert_eq! ( remove_list , expect ) ;
let list = orig_list . clone ( ) ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_last = Some ( 3 ) ;
2019-12-06 08:56:27 +01:00
let remove_list = get_prune_list ( list , false , & options ) ;
2022-04-10 17:49:26 +02:00
let expect : Vec < PathBuf > = vec! [ PathBuf ::from ( " host/elsa/2019-12-02T11:59:15Z " ) ] ;
2019-12-04 16:08:03 +01:00
assert_eq! ( remove_list , expect ) ;
let list = orig_list . clone ( ) ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_last = Some ( 2 ) ;
2019-12-06 08:56:27 +01:00
let remove_list = get_prune_list ( list , false , & options ) ;
2019-12-04 16:08:03 +01:00
let expect : Vec < PathBuf > = vec! [
PathBuf ::from ( " host/elsa/2019-12-02T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-03T11:59:15Z " ) ,
] ;
assert_eq! ( remove_list , expect ) ;
let list = orig_list . clone ( ) ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_last = Some ( 1 ) ;
2019-12-06 08:56:27 +01:00
let remove_list = get_prune_list ( list , false , & options ) ;
2019-12-04 16:08:03 +01:00
let expect : Vec < PathBuf > = vec! [
PathBuf ::from ( " host/elsa/2019-12-02T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-03T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-04T11:59:15Z " ) ,
] ;
assert_eq! ( remove_list , expect ) ;
let list = orig_list . clone ( ) ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_last = Some ( 0 ) ;
2019-12-06 08:56:27 +01:00
let remove_list = get_prune_list ( list , false , & options ) ;
2019-12-04 16:08:03 +01:00
let expect : Vec < PathBuf > = vec! [
PathBuf ::from ( " host/elsa/2019-12-02T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-03T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-04T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-04T12:59:15Z " ) ,
] ;
assert_eq! ( remove_list , expect ) ;
// keep-last, keep-daily mixed
let list = orig_list . clone ( ) ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_last = Some ( 2 ) ;
options . keep_daily = Some ( 2 ) ;
2019-12-06 08:56:27 +01:00
let remove_list = get_prune_list ( list , false , & options ) ;
2019-12-05 08:55:19 +01:00
let expect : Vec < PathBuf > = vec! [ ] ;
2019-12-04 16:08:03 +01:00
assert_eq! ( remove_list , expect ) ;
// keep-daily test
let list = orig_list . clone ( ) ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_daily = Some ( 3 ) ;
2019-12-06 08:56:27 +01:00
let remove_list = get_prune_list ( list , false , & options ) ;
2019-12-04 16:08:03 +01:00
let expect : Vec < PathBuf > = vec! [ PathBuf ::from ( " host/elsa/2019-12-04T11:59:15Z " ) ] ;
assert_eq! ( remove_list , expect ) ;
// keep-daily test
let list = orig_list . clone ( ) ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_daily = Some ( 2 ) ;
2019-12-06 08:56:27 +01:00
let remove_list = get_prune_list ( list , false , & options ) ;
2019-12-04 16:08:03 +01:00
let expect : Vec < PathBuf > = vec! [
PathBuf ::from ( " host/elsa/2019-12-02T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-04T11:59:15Z " ) ,
] ;
assert_eq! ( remove_list , expect ) ;
// keep-weekly
let list = orig_list . clone ( ) ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_weekly = Some ( 5 ) ;
2019-12-06 08:56:27 +01:00
let remove_list = get_prune_list ( list , false , & options ) ;
2019-12-05 08:55:19 +01:00
// all backup are within the same week, so we only keep a single file
2019-12-04 16:08:03 +01:00
let expect : Vec < PathBuf > = vec! [
PathBuf ::from ( " host/elsa/2019-12-02T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-03T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-04T11:59:15Z " ) ,
] ;
assert_eq! ( remove_list , expect ) ;
2019-12-05 08:55:19 +01:00
// keep-daily + keep-weekly
let list = orig_list . clone ( ) ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_daily = Some ( 1 ) ;
options . keep_weekly = Some ( 5 ) ;
2019-12-06 08:56:27 +01:00
let remove_list = get_prune_list ( list , false , & options ) ;
2019-12-05 08:55:19 +01:00
let expect : Vec < PathBuf > = vec! [
PathBuf ::from ( " host/elsa/2019-12-02T11:59:15Z " ) ,
2019-12-05 18:41:28 +01:00
PathBuf ::from ( " host/elsa/2019-12-03T11:59:15Z " ) ,
2019-12-05 08:55:19 +01:00
PathBuf ::from ( " host/elsa/2019-12-04T11:59:15Z " ) ,
] ;
assert_eq! ( remove_list , expect ) ;
// keep-monthly
2019-12-04 16:08:03 +01:00
let list = orig_list . clone ( ) ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_monthly = Some ( 6 ) ;
2019-12-06 08:56:27 +01:00
let remove_list = get_prune_list ( list , false , & options ) ;
2019-12-05 08:55:19 +01:00
// all backup are within the same month, so we only keep a single file
2019-12-04 16:08:03 +01:00
let expect : Vec < PathBuf > = vec! [
PathBuf ::from ( " host/elsa/2019-12-02T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-03T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-04T11:59:15Z " ) ,
] ;
assert_eq! ( remove_list , expect ) ;
2019-12-05 08:55:19 +01:00
// keep-yearly
2019-12-04 16:08:03 +01:00
let list = orig_list . clone ( ) ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_yearly = Some ( 7 ) ;
2019-12-06 08:56:27 +01:00
let remove_list = get_prune_list ( list , false , & options ) ;
2019-12-05 08:55:19 +01:00
// all backup are within the same year, so we only keep a single file
let expect : Vec < PathBuf > = vec! [
PathBuf ::from ( " host/elsa/2019-12-02T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-03T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-04T11:59:15Z " ) ,
] ;
assert_eq! ( remove_list , expect ) ;
// keep-weekly + keep-monthly + keep-yearly
2021-01-15 14:38:27 +01:00
let list = orig_list ;
2021-09-10 09:21:27 +02:00
let mut options = PruneOptions ::default ( ) ;
options . keep_weekly = Some ( 5 ) ;
options . keep_monthly = Some ( 6 ) ;
options . keep_yearly = Some ( 7 ) ;
2019-12-06 08:56:27 +01:00
let remove_list = get_prune_list ( list , false , & options ) ;
2019-12-05 08:55:19 +01:00
// all backup are within one week, so we only keep a single file
2019-12-04 16:08:03 +01:00
let expect : Vec < PathBuf > = vec! [
PathBuf ::from ( " host/elsa/2019-12-02T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-03T11:59:15Z " ) ,
PathBuf ::from ( " host/elsa/2019-12-04T11:59:15Z " ) ,
] ;
assert_eq! ( remove_list , expect ) ;
Ok ( ( ) )
}