]>
Commit | Line | Data |
---|---|---|
1 | use anyhow::{Error}; | |
2 | use std::path::PathBuf; | |
3 | ||
4 | use proxmox_backup::backup::*; | |
5 | ||
6 | fn get_prune_list( | |
7 | list: Vec<BackupInfo>, | |
8 | return_kept: bool, | |
9 | options: &PruneOptions, | |
10 | ) -> Vec<PathBuf> { | |
11 | ||
12 | let mut prune_info = compute_prune_info(list, options).unwrap(); | |
13 | ||
14 | prune_info.reverse(); | |
15 | ||
16 | prune_info | |
17 | .iter() | |
18 | .filter_map(|(info, keep)| { | |
19 | if *keep != return_kept { | |
20 | None | |
21 | } else { | |
22 | Some(info.backup_dir.relative_path()) | |
23 | } | |
24 | }) | |
25 | .collect() | |
26 | } | |
27 | ||
28 | fn create_info( | |
29 | snapshot: &str, | |
30 | partial: bool, | |
31 | ) -> BackupInfo { | |
32 | ||
33 | let backup_dir: BackupDir = snapshot.parse().unwrap(); | |
34 | ||
35 | let mut files = Vec::new(); | |
36 | ||
37 | if !partial { | |
38 | files.push(String::from(MANIFEST_BLOB_NAME)); | |
39 | } | |
40 | ||
41 | BackupInfo { backup_dir, files } | |
42 | } | |
43 | ||
44 | #[test] | |
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] | |
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(); | |
94 | let options = PruneOptions::new().keep_daily(Some(1)); | |
95 | let remove_list = get_prune_list(list, true, &options); | |
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(); | |
102 | let options = PruneOptions::new().keep_last(Some(1)).keep_daily(Some(1)); | |
103 | let remove_list = get_prune_list(list, true, &options); | |
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(); | |
111 | let options = PruneOptions::new().keep_daily(Some(1)).keep_weekly(Some(1)); | |
112 | let remove_list = get_prune_list(list, true, &options); | |
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(); | |
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); | |
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(); | |
130 | let options = PruneOptions::new().keep_monthly(Some(1)).keep_yearly(Some(1)); | |
131 | let remove_list = get_prune_list(list, true, &options); | |
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 | } | |
140 | ||
141 | #[test] | |
142 | fn test_prune_simple() -> Result<(), Error> { | |
143 | ||
144 | let mut orig_list = Vec::new(); | |
145 | ||
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 | ||
151 | // keep-last tests | |
152 | ||
153 | let list = orig_list.clone(); | |
154 | let options = PruneOptions::new().keep_last(Some(4)); | |
155 | let remove_list = get_prune_list(list, false, &options); | |
156 | let expect: Vec<PathBuf> = Vec::new(); | |
157 | assert_eq!(remove_list, expect); | |
158 | ||
159 | let list = orig_list.clone(); | |
160 | let options = PruneOptions::new().keep_last(Some(3)); | |
161 | let remove_list = get_prune_list(list, false, &options); | |
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(); | |
168 | let options = PruneOptions::new().keep_last(Some(2)); | |
169 | let remove_list = get_prune_list(list, false, &options); | |
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(); | |
177 | let options = PruneOptions::new().keep_last(Some(1)); | |
178 | let remove_list = get_prune_list(list, false, &options); | |
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(); | |
187 | let options = PruneOptions::new().keep_last(Some(0)); | |
188 | let remove_list = get_prune_list(list, false, &options); | |
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(); | |
199 | let options = PruneOptions::new().keep_last(Some(2)).keep_daily(Some(2)); | |
200 | let remove_list = get_prune_list(list, false, &options); | |
201 | let expect: Vec<PathBuf> = vec![]; | |
202 | assert_eq!(remove_list, expect); | |
203 | ||
204 | // keep-daily test | |
205 | let list = orig_list.clone(); | |
206 | let options = PruneOptions::new().keep_daily(Some(3)); | |
207 | let remove_list = get_prune_list(list, false, &options); | |
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 | |
212 | let list = orig_list.clone(); | |
213 | let options = PruneOptions::new().keep_daily(Some(2)); | |
214 | let remove_list = get_prune_list(list, false, &options); | |
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(); | |
223 | let options = PruneOptions::new().keep_weekly(Some(5)); | |
224 | let remove_list = get_prune_list(list, false, &options); | |
225 | // all backup are within the same week, so we only keep a single file | |
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 | ||
233 | // keep-daily + keep-weekly | |
234 | let list = orig_list.clone(); | |
235 | let options = PruneOptions::new().keep_daily(Some(1)).keep_weekly(Some(5)); | |
236 | let remove_list = get_prune_list(list, false, &options); | |
237 | let expect: Vec<PathBuf> = vec![ | |
238 | PathBuf::from("host/elsa/2019-12-02T11:59:15Z"), | |
239 | PathBuf::from("host/elsa/2019-12-03T11:59:15Z"), | |
240 | PathBuf::from("host/elsa/2019-12-04T11:59:15Z"), | |
241 | ]; | |
242 | assert_eq!(remove_list, expect); | |
243 | ||
244 | // keep-monthly | |
245 | let list = orig_list.clone(); | |
246 | let options = PruneOptions::new().keep_monthly(Some(6)); | |
247 | let remove_list = get_prune_list(list, false, &options); | |
248 | // all backup are within the same month, so we only keep a single file | |
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 | ||
256 | // keep-yearly | |
257 | let list = orig_list.clone(); | |
258 | let options = PruneOptions::new().keep_yearly(Some(7)); | |
259 | let remove_list = get_prune_list(list, false, &options); | |
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(); | |
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); | |
272 | // all backup are within one week, so we only keep a single file | |
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 | } |