def test_symbolic_link_does_not_crash_in_case_of_vanished_link() -> None: content = "some arbitrary content" with NamedTemporaryFile() as named_file: source = Path(named_file.name) source.write_text(content) in_dest = Path(get_random_filename()) with dm.symbolic_link(src=source, dest=in_dest) as out_dest: sh.run_cmd(cmd=["sudo", "rm", out_dest])
def test_symbolic_link_rejects_missing_src() -> None: with NamedTemporaryFile() as named_file: src = Path(named_file.name) with NamedTemporaryFile() as named_file: dest = Path(named_file.name) with pytest.raises(FileNotFoundError): with dm.symbolic_link(src=src, dest=dest): pass
def test_symbolic_link_removes_link_in_case_of_exception() -> None: with pytest.raises(MyCustomTestException): with NamedTemporaryFile() as src_f: source = Path(src_f.name) dest_p = Path(get_random_filename()) assert not os.path.lexists(dest_p) with dm.symbolic_link(src=source, dest=dest_p): assert os.path.lexists(dest_p) raise MyCustomTestException assert not os.path.lexists(dest_p)
def test_symbolic_link() -> None: content = "some arbitrary content" with NamedTemporaryFile() as named_file: source = Path(named_file.name) source.write_text(content) in_dest = Path(get_random_filename()) with dm.symbolic_link(src=source, dest=in_dest) as out_dest: assert in_dest == out_dest assert out_dest.is_symlink() assert out_dest.read_bytes() == source.read_bytes() assert not out_dest.exists()
def encrypted_restic_device(big_file): """ Prepare device for Restic on BtrFS and return its config Returns ------- config: ResticConfig configuration allowing to interact with the returned device """ config = dm.prepare_device_for_resticbackend(big_file) with dm.symbolic_link(big_file, config.device()): yield config
def encrypted_btrfs_device(big_file): """ Prepare device for ButterBackup and return its config Returns ------- config: BtrfsConfig configuration allowing to interact with the returned device """ config = dm.prepare_device_for_butterbackend(big_file) with dm.symbolic_link(big_file, config.device()): yield config
def test_open_close_roundtrip(runner, encrypted_btrfs_device, config_cls) -> None: def get_empty_config(config_cls, password, device_id): if config_cls == cp.BtrfsConfig: return config_cls( DevicePassCmd=f"echo {password}", Files=set(), FilesDest="files-destination", Folders={}, UUID=device_id, ) if config_cls == cp.ResticConfig: return config_cls( DevicePassCmd=f"echo {password}", RepositoryPassCmd="false", FilesAndFolders=set(), UUID=device_id, ) raise ValueError password, device = encrypted_btrfs_device device_id = uuid.uuid4() expected_cryptsetup_map = Path(f"/dev/mapper/{device_id}") config = get_empty_config(config_cls, password, device_id) with NamedTemporaryFile() as tempf: config_file = Path(tempf.name) config_file.write_text(f"[{config.json()}]") device_by_uuid = Path("/dev/disk/by-uuid/") / str(device_id) with dm.symbolic_link(src=device, dest=device_by_uuid): open_result = runner.invoke( app, ["open", "--config", str(config_file)]) expected_msg = ( f"Gerät {device_id} wurde in (?P<mount_dest>/[^ ]+) geöffnet.") match = re.fullmatch(expected_msg, open_result.stdout.strip()) assert match is not None mount_dest = Path(match.group("mount_dest")) assert any(mount_dest in destinations for destinations in dm.get_mounted_devices().values()) assert expected_cryptsetup_map.exists() runner.invoke(app, ["close", "--config", str(config_file)]) assert not expected_cryptsetup_map.exists() assert not dm.is_mounted(mount_dest) assert not mount_dest.exists()
def test_close_does_not_close_unopened_device(runner, encrypted_btrfs_device) -> None: password, device = encrypted_btrfs_device device_id = uuid.uuid4() config = cp.BtrfsConfig( DevicePassCmd=f"echo {password}", Files=set(), FilesDest="files-destination", Folders={}, UUID=device_id, ) with NamedTemporaryFile() as tempf: config_file = Path(tempf.name) config_file.write_text(f"[{config.json()}]") device_by_uuid = Path("/dev/disk/by-uuid/") / str(device_id) with dm.symbolic_link(src=device, dest=device_by_uuid): close_result = runner.invoke( app, ["close", "--config", str(config_file)]) assert close_result.stdout == "" assert close_result.exit_code == 0
def test_symbolic_link_rejects_missing_src() -> None: src = Path(get_random_filename()) dest = Path(get_random_filename()) with pytest.raises(FileNotFoundError): with dm.symbolic_link(src=src, dest=dest): pass
def test_symbolic_link_rejects_existing_dest(tmp_path: Path) -> None: with NamedTemporaryFile() as named_file: source = Path(named_file.name) with pytest.raises(FileExistsError): with dm.symbolic_link(source, dest=tmp_path): pass