def test_mounted_device(btrfs_device) -> None:
    with dm.mounted_device(btrfs_device) as md:
        assert md.exists()
        assert md.is_dir()
        assert dm.is_mounted(btrfs_device)
        assert md in dm.get_mounted_devices()[str(btrfs_device)]
    assert not md.exists()
    assert not dm.is_mounted(btrfs_device)
    assert str(btrfs_device) not in dm.get_mounted_devices()
def test_mounted_device_takes_over_already_mounted_device(btrfs_device) -> None:
    with TemporaryDirectory() as td:
        dm.mount_btrfs_device(btrfs_device, Path(td))
        with dm.mounted_device(btrfs_device) as md:
            assert dm.is_mounted(btrfs_device)
            assert md in dm.get_mounted_devices()[str(btrfs_device)]
        assert not dm.is_mounted(btrfs_device)
def test_mounted_device_unmounts_in_case_of_exception(btrfs_device) -> None:
    with pytest.raises(MyCustomTestException):
        with dm.mounted_device(btrfs_device) as md:
            # That the device is mounted properly is guaranteed by a test
            # above.
            raise MyCustomTestException
    assert not md.exists()
    assert not dm.is_mounted(btrfs_device)
    assert str(btrfs_device) not in dm.get_mounted_devices()
def test_mounted_device_fails_on_not_unmountable_device() -> None:
    for device, mount_points in dm.get_mounted_devices().items():
        if Path("/") in mount_points:
            root = Path(device)
            break
    else:
        assert False, "Device of / not found!"  # noqa: B011
    with pytest.raises(subprocess.CalledProcessError):
        with dm.mounted_device(root):
            pass
Example #5
0
def close(config: Path = CONFIG_OPTION):
    configurations = list(cp.load_configuration(config))
    mounted_devices = dm.get_mounted_devices()
    for cfg in configurations:
        mapped_device = f"/dev/mapper/{cfg.UUID}"
        if cfg.device().exists() and mapped_device in mounted_devices:
            mount_dirs = mounted_devices[mapped_device]
            if len(mount_dirs) != 1:
                # TODO introduce custom exception
                raise ValueError(
                    "Got several possible mount points. Expected exactly 1!")
            mount_dir = mount_dirs.pop()
            dm.unmount_device(mount_dir)
            dm.close_decrypted_device(Path(mapped_device))
            mount_dir.rmdir()
Example #6
0
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_get_mounted_devices_includes_root() -> None:
    assert any(Path("/") in dest_set for dest_set in dm.get_mounted_devices().values())
def test_get_mounted_devices_includes_correct_mountpoints(mounted_directories) -> None:
    src, dest = mounted_directories
    assert any(
        dest in mount_points for mount_points in dm.get_mounted_devices().values()
    )
def test_get_mounted_devices_raises_on_unknown_device() -> None:
    with pytest.raises(KeyError):
        dm.get_mounted_devices()["unknown-device"]
        with dm.mounted_device(root):
            pass


def test_mounted_device_unmounts_in_case_of_exception(btrfs_device) -> None:
    with pytest.raises(MyCustomTestException):
        with dm.mounted_device(btrfs_device) as md:
            # That the device is mounted properly is guaranteed by a test
            # above.
            raise MyCustomTestException
    assert not md.exists()
    assert not dm.is_mounted(btrfs_device)
    assert str(btrfs_device) not in dm.get_mounted_devices()


@pytest.mark.parametrize("device", dm.get_mounted_devices())
def test_is_mounted_detects(device: Path) -> None:
    assert dm.is_mounted(device)


def test_is_mounted_rejects() -> None:
    with TemporaryDirectory() as tempd:
        assert not dm.is_mounted(Path(tempd))


def test_get_mounted_devices_raises_on_unknown_device() -> None:
    with pytest.raises(KeyError):
        dm.get_mounted_devices()["unknown-device"]


def test_get_mounted_devices_includes_correct_mountpoints(mounted_directories) -> None: