11import datetime as dt
22import itertools
33import os
4+ import typing as t
45from collections import Counter
56from pathlib import Path
67from tempfile import TemporaryDirectory
@@ -26,6 +27,20 @@ def list_files_recursively(path: Path) -> Iterable[Path]:
2627 yield file_or_folder
2728
2829
30+ def run_backup_cycle (
31+ base_config : cp .Configuration ,
32+ source_dir : Path ,
33+ device : Path ,
34+ config_extension : dict [str , t .Any ] | None = None ,
35+ ) -> cp .Configuration :
36+ config = complement_configuration (base_config , source_dir )
37+ if config_extension is not None :
38+ config = config .model_copy (update = config_extension )
39+ backend = bb .BackupBackend .from_config (config )
40+ backend .do_backup (device )
41+ return config
42+
43+
2944@overload
3045def get_expected_content (
3146 config : cp .BtrFSRsyncConfig , exclude_to_ignore_file : bool
@@ -167,9 +182,7 @@ def get_result_content_for_restic(
167182def test_do_backup (source_directories , mounted_device ) -> None :
168183 empty_config , device = mounted_device
169184 for source_dir in source_directories :
170- config = complement_configuration (empty_config , source_dir )
171- backend = bb .BackupBackend .from_config (config )
172- backend .do_backup (device )
185+ config = run_backup_cycle (empty_config , source_dir , device )
173186 result_content = get_result_content (config , device )
174187 expected_content = get_expected_content (config , exclude_to_ignore_file = False )
175188 assert result_content .keys () == expected_content .keys ()
@@ -183,11 +196,12 @@ def test_do_backup(source_directories, mounted_device) -> None:
183196def test_do_backup_handles_exclude_list (source_directories , mounted_device ) -> None :
184197 empty_config , device = mounted_device
185198 for source_dir in source_directories :
186- config = complement_configuration (empty_config , source_dir ).model_copy (
187- update = {"ExcludePatternsFile" : EXCLUDE_FILE }
199+ config = run_backup_cycle (
200+ empty_config ,
201+ source_dir ,
202+ device ,
203+ config_extension = {"ExcludePatternsFile" : EXCLUDE_FILE },
188204 )
189- backend = bb .BackupBackend .from_config (config )
190- backend .do_backup (device )
191205 result_content = get_result_content (config , device )
192206 expected_content = get_expected_content (config , exclude_to_ignore_file = True )
193207 assert result_content == expected_content
@@ -216,16 +230,13 @@ def test_do_backup_removes_existing_files_in_exclude_list(
216230
217231 empty_config , device = mounted_device
218232
219- first_config = complement_configuration (empty_config , first_source )
220- first_backend = bb . BackupBackend . from_config ( first_config )
221- first_backend . do_backup ( device )
222-
223- second_config = complement_configuration ( empty_config , second_source ). model_copy (
224- update = {"ExcludePatternsFile" : EXCLUDE_FILE }
233+ run_backup_cycle (empty_config , first_source , device )
234+ second_config = run_backup_cycle (
235+ empty_config ,
236+ second_source ,
237+ device ,
238+ config_extension = {"ExcludePatternsFile" : EXCLUDE_FILE },
225239 )
226- second_backend = bb .BackupBackend .from_config (second_config )
227- second_backend .do_backup (device )
228-
229240 result_content = get_result_content (second_config , device )
230241 expected_content = get_expected_content (second_config , exclude_to_ignore_file = True )
231242 assert result_content == expected_content
@@ -254,9 +265,8 @@ def test_btrfs_backend_gracefully_handles_existing_snapshots_owned_by_root(
254265 # tradeoff to short-circuit the test here.
255266 return
256267
257- first_config = complement_configuration (empty_config , first_source )
258- first_backend = bb .BackupBackend .from_config (first_config )
259- first_backend .do_backup (device )
268+ first_config = run_backup_cycle (empty_config , first_source , device )
269+ assert isinstance (first_config , cp .BtrFSRsyncConfig ) # for mypy
260270
261271 snapshot_root = device / first_config .BackupRepositoryFolder
262272 latest_snapshot = sorted (snapshot_root .iterdir ())[- 1 ]
@@ -265,12 +275,7 @@ def test_btrfs_backend_gracefully_handles_existing_snapshots_owned_by_root(
265275 sh .run_cmd (cmd = ["sudo" , "chown" , "root:root" , cur ])
266276 sh .run_cmd (cmd = ["sudo" , "rm" , "-rf" , latest_snapshot / first_config .FilesDest ])
267277
268- second_config = complement_configuration (empty_config , second_source ).model_copy (
269- update = {"ExcludePatternsFile" : EXCLUDE_FILE }
270- )
271- second_backend = bb .BackupBackend .from_config (second_config )
272- second_backend .do_backup (device )
273-
278+ second_config = run_backup_cycle (empty_config , second_source , device )
274279 result_content = get_result_content (second_config , device )
275280 expected_content = get_expected_content (second_config , exclude_to_ignore_file = True )
276281 assert result_content == expected_content
@@ -313,9 +318,7 @@ def test_do_backup_for_restic_adapts_ownership(
313318 # tradeoff to short-circuit the test here.
314319 return
315320 for source_dir in source_directories :
316- config = complement_configuration (empty_config , source_dir )
317- backend = bb .BackupBackend .from_config (config )
318- backend .do_backup (device )
321+ config = run_backup_cycle (empty_config , source_dir , device )
319322
320323 expected_user = sh .get_user ()
321324 expected_group = sh .get_group (expected_user )
0 commit comments