]>
Commit | Line | Data |
---|---|---|
f7d4e4b5 | 1 | use anyhow::{Error}; |
0c875cf3 DM |
2 | use std::path::PathBuf; |
3 | ||
4 | use proxmox_backup::backup::*; | |
5 | ||
0c875cf3 DM |
6 | fn get_prune_list( |
7 | list: Vec<BackupInfo>, | |
a096eecb | 8 | return_kept: bool, |
9b783521 | 9 | options: &PruneOptions, |
0c875cf3 DM |
10 | ) -> Vec<PathBuf> { |
11 | ||
9b783521 | 12 | let mut prune_info = compute_prune_info(list, options).unwrap(); |
0c875cf3 | 13 | |
8f0b4c1f | 14 | prune_info.reverse(); |
a096eecb | 15 | |
8f0b4c1f | 16 | prune_info |
0c875cf3 | 17 | .iter() |
8f0b4c1f | 18 | .filter_map(|(info, keep)| { |
a096eecb | 19 | if *keep != return_kept { |
8f0b4c1f DM |
20 | None |
21 | } else { | |
22 | Some(info.backup_dir.relative_path()) | |
23 | } | |
24 | }) | |
0c875cf3 DM |
25 | .collect() |
26 | } | |
27 | ||
659da6c9 DM |
28 | fn create_info( |
29 | snapshot: &str, | |
30 | partial: bool, | |
31 | ) -> BackupInfo { | |
32 | ||
0cf2b644 | 33 | let backup_dir: BackupDir = snapshot.parse().unwrap(); |
659da6c9 DM |
34 | |
35 | let mut files = Vec::new(); | |
36 | ||
37 | if !partial { | |
38 | files.push(String::from(MANIFEST_BLOB_NAME)); | |
39 | } | |
a096eecb | 40 | |
659da6c9 DM |
41 | BackupInfo { backup_dir, files } |
42 | } | |
9b783521 | 43 | |
a096eecb | 44 | #[test] |
102d8d41 DM |
45 | fn test_prune_hourly() -> Result<(), Error> { |
46 | ||
47 | let mut orig_list = Vec::new(); | |
48 | ||
49 | orig_list.push(create_info("host/elsa/2019-11-15T09:39:15Z", false)); | |
50 | orig_list.push(create_info("host/elsa/2019-11-15T10:49:15Z", false)); | |
51 | orig_list.push(create_info("host/elsa/2019-11-15T10:59:15Z", false)); | |
52 | orig_list.push(create_info("host/elsa/2019-11-15T11:39:15Z", false)); | |
53 | orig_list.push(create_info("host/elsa/2019-11-15T11:49:15Z", false)); | |
54 | orig_list.push(create_info("host/elsa/2019-11-15T11:59:15Z", false)); | |
55 | ||
56 | let list = orig_list.clone(); | |
57 | let options = PruneOptions::new().keep_hourly(Some(3)); | |
58 | let remove_list = get_prune_list(list, false, &options); | |
59 | let expect: Vec<PathBuf> = vec![ | |
60 | PathBuf::from("host/elsa/2019-11-15T10:49:15Z"), | |
61 | PathBuf::from("host/elsa/2019-11-15T11:39:15Z"), | |
62 | PathBuf::from("host/elsa/2019-11-15T11:49:15Z"), | |
63 | ]; | |
64 | assert_eq!(remove_list, expect); | |
65 | ||
66 | let list = orig_list.clone(); | |
67 | let options = PruneOptions::new().keep_hourly(Some(2)); | |
68 | let remove_list = get_prune_list(list, true, &options); | |
69 | let expect: Vec<PathBuf> = vec![ | |
70 | PathBuf::from("host/elsa/2019-11-15T10:59:15Z"), | |
71 | PathBuf::from("host/elsa/2019-11-15T11:59:15Z"), | |
72 | ]; | |
73 | assert_eq!(remove_list, expect); | |
74 | ||
75 | Ok(()) | |
76 | } | |
77 | ||
78 | #[test] | |
a096eecb DM |
79 | fn test_prune_simple2() -> Result<(), Error> { |
80 | ||
81 | let mut orig_list = Vec::new(); | |
82 | ||
83 | orig_list.push(create_info("host/elsa/2018-11-15T11:59:15Z", false)); | |
84 | orig_list.push(create_info("host/elsa/2019-11-15T11:59:15Z", false)); | |
85 | orig_list.push(create_info("host/elsa/2019-11-21T11:59:15Z", false)); | |
86 | orig_list.push(create_info("host/elsa/2019-11-22T11:59:15Z", false)); | |
87 | orig_list.push(create_info("host/elsa/2019-11-29T11:59:15Z", false)); | |
88 | orig_list.push(create_info("host/elsa/2019-12-01T11:59:15Z", false)); | |
89 | orig_list.push(create_info("host/elsa/2019-12-02T11:59:15Z", false)); | |
90 | orig_list.push(create_info("host/elsa/2019-12-03T11:59:15Z", false)); | |
91 | orig_list.push(create_info("host/elsa/2019-12-04T11:59:15Z", false)); | |
92 | ||
93 | let list = orig_list.clone(); | |
9b783521 DM |
94 | let options = PruneOptions::new().keep_daily(Some(1)); |
95 | let remove_list = get_prune_list(list, true, &options); | |
a096eecb DM |
96 | let expect: Vec<PathBuf> = vec![ |
97 | PathBuf::from("host/elsa/2019-12-04T11:59:15Z"), | |
98 | ]; | |
99 | assert_eq!(remove_list, expect); | |
100 | ||
101 | let list = orig_list.clone(); | |
9b783521 DM |
102 | let options = PruneOptions::new().keep_last(Some(1)).keep_daily(Some(1)); |
103 | let remove_list = get_prune_list(list, true, &options); | |
a096eecb DM |
104 | let expect: Vec<PathBuf> = vec![ |
105 | PathBuf::from("host/elsa/2019-12-03T11:59:15Z"), | |
106 | PathBuf::from("host/elsa/2019-12-04T11:59:15Z"), | |
107 | ]; | |
108 | assert_eq!(remove_list, expect); | |
109 | ||
110 | let list = orig_list.clone(); | |
9b783521 DM |
111 | let options = PruneOptions::new().keep_daily(Some(1)).keep_weekly(Some(1)); |
112 | let remove_list = get_prune_list(list, true, &options); | |
a096eecb DM |
113 | let expect: Vec<PathBuf> = vec![ |
114 | PathBuf::from("host/elsa/2019-12-01T11:59:15Z"), | |
115 | PathBuf::from("host/elsa/2019-12-04T11:59:15Z"), | |
116 | ]; | |
117 | assert_eq!(remove_list, expect); | |
118 | ||
119 | let list = orig_list.clone(); | |
9b783521 DM |
120 | let options = PruneOptions::new().keep_daily(Some(1)).keep_weekly(Some(1)).keep_monthly(Some(1)); |
121 | let remove_list = get_prune_list(list, true, &options); | |
a096eecb DM |
122 | let expect: Vec<PathBuf> = vec![ |
123 | PathBuf::from("host/elsa/2019-11-22T11:59:15Z"), | |
124 | PathBuf::from("host/elsa/2019-12-01T11:59:15Z"), | |
125 | PathBuf::from("host/elsa/2019-12-04T11:59:15Z"), | |
126 | ]; | |
127 | assert_eq!(remove_list, expect); | |
128 | ||
129 | let list = orig_list.clone(); | |
9b783521 DM |
130 | let options = PruneOptions::new().keep_monthly(Some(1)).keep_yearly(Some(1)); |
131 | let remove_list = get_prune_list(list, true, &options); | |
a096eecb DM |
132 | let expect: Vec<PathBuf> = vec![ |
133 | PathBuf::from("host/elsa/2018-11-15T11:59:15Z"), | |
134 | PathBuf::from("host/elsa/2019-12-04T11:59:15Z"), | |
135 | ]; | |
136 | assert_eq!(remove_list, expect); | |
137 | ||
138 | Ok(()) | |
139 | } | |
659da6c9 | 140 | |
0c875cf3 DM |
141 | #[test] |
142 | fn test_prune_simple() -> Result<(), Error> { | |
143 | ||
659da6c9 | 144 | let mut orig_list = Vec::new(); |
0c875cf3 | 145 | |
659da6c9 DM |
146 | orig_list.push(create_info("host/elsa/2019-12-02T11:59:15Z", false)); |
147 | orig_list.push(create_info("host/elsa/2019-12-03T11:59:15Z", false)); | |
148 | orig_list.push(create_info("host/elsa/2019-12-04T11:59:15Z", false)); | |
149 | orig_list.push(create_info("host/elsa/2019-12-04T12:59:15Z", false)); | |
150 | ||
0c875cf3 DM |
151 | // keep-last tests |
152 | ||
153 | let list = orig_list.clone(); | |
9b783521 DM |
154 | let options = PruneOptions::new().keep_last(Some(4)); |
155 | let remove_list = get_prune_list(list, false, &options); | |
0c875cf3 DM |
156 | let expect: Vec<PathBuf> = Vec::new(); |
157 | assert_eq!(remove_list, expect); | |
158 | ||
159 | let list = orig_list.clone(); | |
9b783521 DM |
160 | let options = PruneOptions::new().keep_last(Some(3)); |
161 | let remove_list = get_prune_list(list, false, &options); | |
0c875cf3 DM |
162 | let expect: Vec<PathBuf> = vec![ |
163 | PathBuf::from("host/elsa/2019-12-02T11:59:15Z"), | |
164 | ]; | |
165 | assert_eq!(remove_list, expect); | |
166 | ||
167 | let list = orig_list.clone(); | |
9b783521 DM |
168 | let options = PruneOptions::new().keep_last(Some(2)); |
169 | let remove_list = get_prune_list(list, false, &options); | |
0c875cf3 DM |
170 | let expect: Vec<PathBuf> = vec![ |
171 | PathBuf::from("host/elsa/2019-12-02T11:59:15Z"), | |
172 | PathBuf::from("host/elsa/2019-12-03T11:59:15Z"), | |
173 | ]; | |
174 | assert_eq!(remove_list, expect); | |
175 | ||
176 | let list = orig_list.clone(); | |
9b783521 DM |
177 | let options = PruneOptions::new().keep_last(Some(1)); |
178 | let remove_list = get_prune_list(list, false, &options); | |
0c875cf3 DM |
179 | let expect: Vec<PathBuf> = vec![ |
180 | PathBuf::from("host/elsa/2019-12-02T11:59:15Z"), | |
181 | PathBuf::from("host/elsa/2019-12-03T11:59:15Z"), | |
182 | PathBuf::from("host/elsa/2019-12-04T11:59:15Z"), | |
183 | ]; | |
184 | assert_eq!(remove_list, expect); | |
185 | ||
186 | let list = orig_list.clone(); | |
9b783521 DM |
187 | let options = PruneOptions::new().keep_last(Some(0)); |
188 | let remove_list = get_prune_list(list, false, &options); | |
0c875cf3 DM |
189 | let expect: Vec<PathBuf> = vec![ |
190 | PathBuf::from("host/elsa/2019-12-02T11:59:15Z"), | |
191 | PathBuf::from("host/elsa/2019-12-03T11:59:15Z"), | |
192 | PathBuf::from("host/elsa/2019-12-04T11:59:15Z"), | |
193 | PathBuf::from("host/elsa/2019-12-04T12:59:15Z"), | |
194 | ]; | |
195 | assert_eq!(remove_list, expect); | |
196 | ||
197 | // keep-last, keep-daily mixed | |
198 | let list = orig_list.clone(); | |
9b783521 DM |
199 | let options = PruneOptions::new().keep_last(Some(2)).keep_daily(Some(2)); |
200 | let remove_list = get_prune_list(list, false, &options); | |
2c034f8d | 201 | let expect: Vec<PathBuf> = vec![]; |
0c875cf3 DM |
202 | assert_eq!(remove_list, expect); |
203 | ||
204 | // keep-daily test | |
0c875cf3 | 205 | let list = orig_list.clone(); |
9b783521 DM |
206 | let options = PruneOptions::new().keep_daily(Some(3)); |
207 | let remove_list = get_prune_list(list, false, &options); | |
0c875cf3 DM |
208 | let expect: Vec<PathBuf> = vec![PathBuf::from("host/elsa/2019-12-04T11:59:15Z")]; |
209 | assert_eq!(remove_list, expect); | |
210 | ||
211 | // keep-daily test | |
0c875cf3 | 212 | let list = orig_list.clone(); |
9b783521 DM |
213 | let options = PruneOptions::new().keep_daily(Some(2)); |
214 | let remove_list = get_prune_list(list, false, &options); | |
0c875cf3 DM |
215 | let expect: Vec<PathBuf> = vec![ |
216 | PathBuf::from("host/elsa/2019-12-02T11:59:15Z"), | |
217 | PathBuf::from("host/elsa/2019-12-04T11:59:15Z"), | |
218 | ]; | |
219 | assert_eq!(remove_list, expect); | |
220 | ||
221 | // keep-weekly | |
222 | let list = orig_list.clone(); | |
9b783521 DM |
223 | let options = PruneOptions::new().keep_weekly(Some(5)); |
224 | let remove_list = get_prune_list(list, false, &options); | |
2c034f8d | 225 | // all backup are within the same week, so we only keep a single file |
0c875cf3 DM |
226 | let expect: Vec<PathBuf> = vec![ |
227 | PathBuf::from("host/elsa/2019-12-02T11:59:15Z"), | |
228 | PathBuf::from("host/elsa/2019-12-03T11:59:15Z"), | |
229 | PathBuf::from("host/elsa/2019-12-04T11:59:15Z"), | |
230 | ]; | |
231 | assert_eq!(remove_list, expect); | |
232 | ||
2c034f8d DM |
233 | // keep-daily + keep-weekly |
234 | let list = orig_list.clone(); | |
9b783521 DM |
235 | let options = PruneOptions::new().keep_daily(Some(1)).keep_weekly(Some(5)); |
236 | let remove_list = get_prune_list(list, false, &options); | |
2c034f8d DM |
237 | let expect: Vec<PathBuf> = vec![ |
238 | PathBuf::from("host/elsa/2019-12-02T11:59:15Z"), | |
6f47dd8a | 239 | PathBuf::from("host/elsa/2019-12-03T11:59:15Z"), |
2c034f8d DM |
240 | PathBuf::from("host/elsa/2019-12-04T11:59:15Z"), |
241 | ]; | |
242 | assert_eq!(remove_list, expect); | |
243 | ||
244 | // keep-monthly | |
0c875cf3 | 245 | let list = orig_list.clone(); |
9b783521 DM |
246 | let options = PruneOptions::new().keep_monthly(Some(6)); |
247 | let remove_list = get_prune_list(list, false, &options); | |
2c034f8d | 248 | // all backup are within the same month, so we only keep a single file |
0c875cf3 DM |
249 | let expect: Vec<PathBuf> = vec![ |
250 | PathBuf::from("host/elsa/2019-12-02T11:59:15Z"), | |
251 | PathBuf::from("host/elsa/2019-12-03T11:59:15Z"), | |
252 | PathBuf::from("host/elsa/2019-12-04T11:59:15Z"), | |
253 | ]; | |
254 | assert_eq!(remove_list, expect); | |
255 | ||
2c034f8d | 256 | // keep-yearly |
0c875cf3 | 257 | let list = orig_list.clone(); |
9b783521 DM |
258 | let options = PruneOptions::new().keep_yearly(Some(7)); |
259 | let remove_list = get_prune_list(list, false, &options); | |
2c034f8d DM |
260 | // all backup are within the same year, so we only keep a single file |
261 | let expect: Vec<PathBuf> = vec![ | |
262 | PathBuf::from("host/elsa/2019-12-02T11:59:15Z"), | |
263 | PathBuf::from("host/elsa/2019-12-03T11:59:15Z"), | |
264 | PathBuf::from("host/elsa/2019-12-04T11:59:15Z"), | |
265 | ]; | |
266 | assert_eq!(remove_list, expect); | |
267 | ||
268 | // keep-weekly + keep-monthly + keep-yearly | |
269 | let list = orig_list.clone(); | |
9b783521 DM |
270 | let options = PruneOptions::new().keep_weekly(Some(5)).keep_monthly(Some(6)).keep_yearly(Some(7)); |
271 | let remove_list = get_prune_list(list, false, &options); | |
2c034f8d | 272 | // all backup are within one week, so we only keep a single file |
0c875cf3 DM |
273 | let expect: Vec<PathBuf> = vec![ |
274 | PathBuf::from("host/elsa/2019-12-02T11:59:15Z"), | |
275 | PathBuf::from("host/elsa/2019-12-03T11:59:15Z"), | |
276 | PathBuf::from("host/elsa/2019-12-04T11:59:15Z"), | |
277 | ]; | |
278 | assert_eq!(remove_list, expect); | |
279 | ||
280 | Ok(()) | |
281 | } |