コード例 #1
0
async def test_mountpoint_remote_error_event(aqtbot, running_backend, logged_gui, snackbar_catcher):
    c_w = logged_gui.test_get_central_widget()

    async with aqtbot.wait_signal(c_w.new_notification):
        c_w.event_bus.send(
            CoreEvent.MOUNTPOINT_REMOTE_ERROR,
            exc=FSWorkspaceNoReadAccess("Cannot get workspace roles: no read access"),
            path=FsPath("/bar"),
            mountpoint=Path("/foo"),
            operation="open",
            workspace_id=EntryID.new(),
            timestamp=None,
        )

    assert "Read access to " in snackbar_catcher.snackbars[0][1]
    snackbar_catcher.reset()

    async with aqtbot.wait_signal(c_w.new_notification):
        c_w.event_bus.send(
            CoreEvent.MOUNTPOINT_UNHANDLED_ERROR,
            exc=RuntimeError("D'Oh !"),
            path=FsPath("/bar"),
            mountpoint=Path("/foo"),
            operation="unlink",
            workspace_id=EntryID.new(),
        )

    assert "Error with the mountpoint " in snackbar_catcher.snackbars[0][1]
    snackbar_catcher.reset()
コード例 #2
0
ファイル: test_rsync.py プロジェクト: Scille/parsec-cloud
async def test_upsert_file(alice_workspace):

    _update_file_mock = AsyncMock(spec=mock.Mock())
    _create_path_mock = AsyncMock(spec=mock.Mock())

    path = FsPath("/test")
    workspace_path = FsPath("/path_in_workspace")
    entry_id = EntryID.new()

    with mock.patch("parsec.core.cli.rsync._create_path", _create_path_mock):
        with mock.patch("parsec.core.cli.rsync._update_file",
                        _update_file_mock):
            await rsync._upsert_file(entry_id, alice_workspace, path,
                                     workspace_path)
            _update_file_mock.assert_called_once_with(alice_workspace,
                                                      entry_id, path,
                                                      workspace_path)
            _create_path_mock.assert_not_called()

    _update_file_mock.reset_mock()
    entry_id = None

    with mock.patch("parsec.core.cli.rsync._create_path", _create_path_mock):
        with mock.patch("parsec.core.cli.rsync._update_file",
                        _update_file_mock):
            await rsync._upsert_file(None, alice_workspace, path,
                                     workspace_path)
            _update_file_mock.assert_not_called()
            _create_path_mock.assert_called_once_with(alice_workspace, False,
                                                      path, workspace_path)
コード例 #3
0
ファイル: test_rsync.py プロジェクト: Scille/parsec-cloud
async def test_get_or_create_directory(alice_workspace):
    manifest1 = mock.Mock(spec=FolderManifest)
    manifest2 = mock.Mock(spec=FolderManifest)

    load_manifest_mock = AsyncMock(spec=mock.Mock(),
                                   side_effect=lambda x: manifest1)
    alice_workspace.remote_loader.load_manifest = load_manifest_mock

    _create_path_mock = AsyncMock(spec=mock.Mock(),
                                  side_effect=lambda *x: manifest2)
    with mock.patch("parsec.core.cli.rsync._create_path", _create_path_mock):
        entry_id = EntryID.new()
        res = await rsync._get_or_create_directory(
            entry_id, alice_workspace, FsPath("/test_directory"),
            FsPath("/path_in_workspace"))
        load_manifest_mock.assert_called_once_with(entry_id)
        _create_path_mock.assert_not_called()
        assert res is manifest1

    load_manifest_mock.reset_mock()

    with mock.patch("parsec.core.cli.rsync._create_path", _create_path_mock):
        res = await rsync._get_or_create_directory(
            None, alice_workspace, FsPath("/test_directory"),
            FsPath("/path_in_workspace"))
        load_manifest_mock.assert_not_called()
        _create_path_mock.assert_called_once_with(alice_workspace, True,
                                                  FsPath("/test_directory"),
                                                  FsPath("/path_in_workspace"))
        assert res is manifest2
コード例 #4
0
ファイル: manifest.py プロジェクト: Scille/parsec-cloud
 def new_placeholder(
     cls,
     author: DeviceID,
     parent: EntryID,
     timestamp: DateTime,
     blocksize: int = DEFAULT_BLOCK_SIZE,
 ) -> "LocalFileManifest":
     id = EntryID.new()
     blocks = ()
     return cls(
         base=RemoteFileManifest(
             author=author,
             timestamp=timestamp,
             id=id,
             parent=parent,
             version=0,
             created=timestamp,
             updated=timestamp,
             blocksize=blocksize,
             size=0,
             blocks=blocks,
         ),
         need_sync=True,
         updated=timestamp,
         blocksize=blocksize,
         size=0,
         blocks=blocks,
     )
コード例 #5
0
 def new_placeholder(
     cls,
     author: DeviceID,
     parent: EntryID,
     id: Optional[EntryID] = None,
     now: DateTime = None,
     blocksize=DEFAULT_BLOCK_SIZE,
 ) -> "LocalFileManifest":
     now = now or pendulum_now()
     blocks = ()
     return cls(
         base=RemoteFileManifest(
             author=author,
             timestamp=now,
             id=id or EntryID.new(),
             parent=parent,
             version=0,
             created=now,
             updated=now,
             blocksize=blocksize,
             size=0,
             blocks=blocks,
         ),
         need_sync=True,
         updated=now,
         blocksize=blocksize,
         size=0,
         blocks=blocks,
     )
コード例 #6
0
async def test_mount_unknown_workspace(base_mountpoint, alice_user_fs,
                                       event_bus):
    async with mountpoint_manager_factory(
            alice_user_fs, event_bus, base_mountpoint) as mountpoint_manager:
        wid = EntryID.new()
        with pytest.raises(MountpointConfigurationError) as exc:
            await mountpoint_manager.mount_workspace(wid)

        assert exc.value.args == (f"Workspace `{wid}` doesn't exist", )
コード例 #7
0
def test_workspace_entry():
    from parsec.api.data.manifest import _RsWorkspaceEntry, WorkspaceEntry, _PyWorkspaceEntry
    from parsec.api.data import EntryName

    assert WorkspaceEntry is _RsWorkspaceEntry

    def _assert_workspace_entry_eq(py, rs):
        assert isinstance(py, _PyWorkspaceEntry)
        assert isinstance(rs, _RsWorkspaceEntry)
        assert py.is_revoked() == rs.is_revoked()
        assert py.name == rs.name
        assert py.id == rs.id
        assert py.key == rs.key
        assert py.encryption_revision == rs.encryption_revision
        assert py.encrypted_on == rs.encrypted_on
        assert py.role_cached_on == rs.role_cached_on
        assert py.role == rs.role

    kwargs = {
        "name": EntryName("name"),
        "id": EntryID.new(),
        "key": SecretKey.generate(),
        "encryption_revision": 1,
        "encrypted_on": pendulum.now(),
        "role_cached_on": pendulum.now(),
        "role": RealmRole.OWNER,
    }

    py_we = _PyWorkspaceEntry(**kwargs)
    rs_we = WorkspaceEntry(**kwargs)
    _assert_workspace_entry_eq(py_we, rs_we)

    kwargs = {
        "name": EntryName("new_name"),
        "id": EntryID.new(),
        "key": SecretKey.generate(),
        "encryption_revision": 42,
        "encrypted_on": pendulum.now(),
        "role_cached_on": pendulum.now(),
        "role": None,
    }
    py_we = py_we.evolve(**kwargs)
    rs_we = rs_we.evolve(**kwargs)
    _assert_workspace_entry_eq(py_we, rs_we)
コード例 #8
0
 async def rename_workspace(self, workspace, new_name):
     wid, workspace = workspace
     src = f"/{workspace}"
     dst = f"/{new_name}"
     expected_status = self.oracle_fs.rename_workspace(src, dst)
     if expected_status == "ok":
         await self.user_fs.workspace_rename(wid, EntryName(new_name))
     else:
         with pytest.raises(FSWorkspaceNotFoundError):
             await self.user_fs.workspace_rename(
                 EntryID.new(), EntryName(new_name))
     return wid, new_name
コード例 #9
0
ファイル: test_rsync.py プロジェクト: Scille/parsec-cloud
async def test_sync_directory(alice_workspace):

    _get_or_create_directory_mock = AsyncMock(
        spec=mock.Mock(), side_effect=lambda *x: "folder_manifest_mock")
    _sync_directory_content_mock = AsyncMock(spec=mock.Mock())
    _clear_directory_mock = AsyncMock(spec=mock.Mock())

    entry_id = EntryID.new()
    path = FsPath("/test")
    workspace_path = FsPath("/path_in_workspace")

    with mock.patch("parsec.core.cli.rsync._get_or_create_directory",
                    _get_or_create_directory_mock):
        with mock.patch("parsec.core.cli.rsync._sync_directory_content",
                        _sync_directory_content_mock):
            with mock.patch("parsec.core.cli.rsync._clear_directory",
                            _clear_directory_mock):
                await rsync._sync_directory(entry_id, alice_workspace, path,
                                            workspace_path)
                _get_or_create_directory_mock.assert_called_once_with(
                    entry_id, alice_workspace, path, workspace_path)
                _sync_directory_content_mock.assert_called_once_with(
                    workspace_path, path, alice_workspace,
                    "folder_manifest_mock")
                _clear_directory_mock.assert_called_once_with(
                    workspace_path, path, alice_workspace,
                    "folder_manifest_mock")

    _get_or_create_directory_mock.reset_mock()
    _sync_directory_content_mock.reset_mock()
    _clear_directory_mock.reset_mock()

    with mock.patch("parsec.core.cli.rsync._get_or_create_directory",
                    _get_or_create_directory_mock):
        with mock.patch("parsec.core.cli.rsync._sync_directory_content",
                        _sync_directory_content_mock):
            with mock.patch("parsec.core.cli.rsync._clear_directory",
                            _clear_directory_mock):
                await rsync._sync_directory(None, alice_workspace, path,
                                            workspace_path)
                _get_or_create_directory_mock.assert_called_once_with(
                    None, alice_workspace, path, workspace_path)
                _sync_directory_content_mock.assert_called_once_with(
                    workspace_path, path, alice_workspace,
                    "folder_manifest_mock")
                _clear_directory_mock.assert_not_called()
コード例 #10
0
def test_folder_manifest():
    from parsec.api.data.manifest import _RsFolderManifest, FolderManifest, _PyFolderManifest

    assert FolderManifest is _RsFolderManifest

    def _assert_folder_manifest_eq(py, rs):
        assert isinstance(py, _PyFolderManifest)
        assert isinstance(rs, _RsFolderManifest)

        assert py.author == rs.author
        assert py.parent == rs.parent
        assert py.id == rs.id
        assert py.version == rs.version
        assert py.timestamp == rs.timestamp
        assert py.created == rs.created
        assert py.updated == rs.updated
        assert py.children == rs.children

    kwargs = {
        "author": DeviceID("user@device"),
        "id": EntryID.new(),
        "parent": EntryID.new(),
        "version": 42,
        "timestamp": pendulum.now(),
        "created": pendulum.now(),
        "updated": pendulum.now(),
        "children": {
            EntryName("file1.txt"): EntryID.new()
        },
    }
    py_wm = _PyFolderManifest(**kwargs)
    rs_wm = FolderManifest(**kwargs)
    _assert_folder_manifest_eq(py_wm, rs_wm)

    kwargs = {
        "author": DeviceID("a@b"),
        "id": EntryID.new(),
        "parent": EntryID.new(),
        "version": 1337,
        "timestamp": pendulum.now(),
        "created": pendulum.now(),
        "updated": pendulum.now(),
        "children": {
            EntryName("file2.mp4"): EntryID.new()
        },
    }

    py_wm = py_wm.evolve(**kwargs)
    rs_wm = rs_wm.evolve(**kwargs)
    _assert_folder_manifest_eq(py_wm, rs_wm)
コード例 #11
0
ファイル: manifest.py プロジェクト: Scille/parsec-cloud
 def new_placeholder(cls, author: DeviceID, parent: EntryID,
                     timestamp: DateTime) -> "LocalFolderManifest":
     id = EntryID.new()
     children = FrozenDict()
     return cls(
         base=RemoteFolderManifest(
             author=author,
             timestamp=timestamp,
             id=id,
             parent=parent,
             version=0,
             created=timestamp,
             updated=timestamp,
             children=children,
         ),
         need_sync=True,
         updated=timestamp,
         children=children,
         local_confinement_points=frozenset(),
         remote_confinement_points=frozenset(),
     )
コード例 #12
0
 def new_placeholder(cls,
                     author: DeviceID,
                     id: EntryID = None,
                     now: DateTime = None) -> "LocalUserManifest":
     workspaces = ()
     now = now or pendulum_now()
     return cls(
         base=RemoteUserManifest(
             author=author,
             timestamp=now,
             id=id or EntryID.new(),
             version=0,
             created=now,
             updated=now,
             last_processed_message=0,
             workspaces=workspaces,
         ),
         need_sync=True,
         updated=now,
         last_processed_message=0,
         workspaces=workspaces,
     )
コード例 #13
0
 def new_placeholder(cls,
                     author: DeviceID,
                     id: EntryID = None,
                     now: DateTime = None) -> "LocalWorkspaceManifest":
     now = now or pendulum_now()
     children = FrozenDict()
     return cls(
         base=RemoteWorkspaceManifest(
             author=author,
             timestamp=now,
             id=id or EntryID.new(),
             version=0,
             created=now,
             updated=now,
             children=children,
         ),
         need_sync=True,
         updated=now,
         children=children,
         local_confinement_points=frozenset(),
         remote_confinement_points=frozenset(),
     )
コード例 #14
0
ファイル: manifest.py プロジェクト: Scille/parsec-cloud
 def new_placeholder(cls,
                     author: DeviceID,
                     timestamp: DateTime,
                     id: EntryID = None,
                     speculative: bool = False) -> "LocalUserManifest":
     return cls(
         base=RemoteUserManifest(
             author=author,
             timestamp=timestamp,
             id=id or EntryID.new(),
             version=0,
             created=timestamp,
             updated=timestamp,
             last_processed_message=0,
             workspaces=(),
         ),
         need_sync=True,
         updated=timestamp,
         last_processed_message=0,
         workspaces=(),
         speculative=speculative,
     )
コード例 #15
0
ファイル: manifest.py プロジェクト: Scille/parsec-cloud
 def new_placeholder(cls,
                     author: DeviceID,
                     timestamp: DateTime,
                     id: EntryID = None,
                     speculative: bool = False) -> "LocalWorkspaceManifest":
     children = FrozenDict()
     return cls(
         base=RemoteWorkspaceManifest(
             author=author,
             timestamp=timestamp,
             id=id or EntryID.new(),
             version=0,
             created=timestamp,
             updated=timestamp,
             children=children,
         ),
         need_sync=True,
         updated=timestamp,
         children=children,
         local_confinement_points=frozenset(),
         remote_confinement_points=frozenset(),
         speculative=speculative,
     )
コード例 #16
0
def test_user_manifest():
    from parsec.api.data.manifest import (
        _RsUserManifest,
        UserManifest,
        _PyUserManifest,
        WorkspaceEntry,
    )

    assert UserManifest is _RsUserManifest

    def _assert_user_manifest_eq(py, rs):
        assert isinstance(py, _PyUserManifest)
        assert isinstance(rs, _RsUserManifest)

        assert py.author == rs.author
        assert py.version == rs.version
        assert py.id == rs.id
        assert py.timestamp == rs.timestamp
        assert py.created == rs.created
        assert py.updated == rs.updated
        assert py.last_processed_message == rs.last_processed_message
        assert py.workspaces == rs.workspaces

    kwargs = {
        "author":
        DeviceID("user@device"),
        "id":
        EntryID.new(),
        "version":
        42,
        "timestamp":
        pendulum.now(),
        "created":
        pendulum.now(),
        "updated":
        pendulum.now(),
        "last_processed_message":
        4,
        "workspaces": [
            WorkspaceEntry(
                name=EntryName("name"),
                id=EntryID.new(),
                key=SecretKey.generate(),
                encryption_revision=1,
                encrypted_on=pendulum.now(),
                role_cached_on=pendulum.now(),
                role=RealmRole.OWNER,
            )
        ],
    }

    py_um = _PyUserManifest(**kwargs)
    rs_um = UserManifest(**kwargs)
    _assert_user_manifest_eq(py_um, rs_um)

    kwargs = {
        "author":
        DeviceID("a@b"),
        "id":
        EntryID.new(),
        "version":
        1337,
        "timestamp":
        pendulum.now(),
        "created":
        pendulum.now(),
        "updated":
        pendulum.now(),
        "last_processed_message":
        7,
        "workspaces": [
            WorkspaceEntry(
                name=EntryName("name"),
                id=EntryID.new(),
                key=SecretKey.generate(),
                encryption_revision=1,
                encrypted_on=pendulum.now(),
                role_cached_on=pendulum.now(),
                role=RealmRole.OWNER,
            ),
            WorkspaceEntry(
                name=EntryName("other_name"),
                id=EntryID.new(),
                key=SecretKey.generate(),
                encryption_revision=2,
                encrypted_on=pendulum.now(),
                role_cached_on=pendulum.now(),
                role=RealmRole.CONTRIBUTOR,
            ),
        ],
    }

    py_wm = py_um.evolve(**kwargs)
    rs_wm = rs_um.evolve(**kwargs)
    _assert_user_manifest_eq(py_wm, rs_wm)
コード例 #17
0
def test_local_file_manifest():
    from parsec.api.data.manifest import BlockAccess
    from parsec.core.types.manifest import (
        _RsLocalFileManifest,
        LocalFileManifest,
        _PyLocalFileManifest,
        Chunk,
    )

    assert LocalFileManifest is _RsLocalFileManifest

    def _assert_local_file_manifest_eq(py,
                                       rs,
                                       exclude_base=False,
                                       exclude_id=False):
        assert isinstance(py, _PyLocalFileManifest)
        assert isinstance(rs, _RsLocalFileManifest)
        if not exclude_base:
            assert py.base == rs.base
        assert py.need_sync == rs.need_sync
        assert py.updated == rs.updated
        assert py.size == rs.size
        assert py.blocksize == rs.blocksize
        assert len(py.blocks) == len(rs.blocks)
        assert isinstance(rs.blocks, type(py.blocks))
        if len(py.blocks):
            assert isinstance(rs.blocks[0], type(py.blocks[0]))
        if not exclude_id:
            assert py.id == rs.id
        assert py.created == rs.created
        assert py.base_version == rs.base_version
        assert py.is_placeholder == rs.is_placeholder
        assert py.is_reshaped() == rs.is_reshaped()
        for (b1, b2) in zip(sorted(py.blocks), sorted(rs.blocks)):
            assert len(b1) == len(b2)
            assert all(
                isinstance(c2, Chunk) and c1.id == c2.id and c1.start == c2.
                start and c1.stop == c2.stop and c1.raw_offset == c2.raw_offset
                and c1.raw_size == c2.raw_size and c1.access == c2.access
                for (c1, c2) in zip(b1, b2))

    def _assert_file_manifest_eq(py, rs):
        assert py.author == rs.author
        assert py.parent == rs.parent
        assert py.version == rs.version
        assert py.size == rs.size
        assert py.blocksize == rs.blocksize
        assert py.timestamp == rs.timestamp
        assert py.created == rs.created
        assert py.updated == rs.updated
        assert len(py.blocks) == len(rs.blocks)
        assert isinstance(rs.blocks, type(py.blocks))
        assert all(
            isinstance(b2, BlockAccess) and b1.id == b2.id
            and b1.offset == b2.offset and b1.size == b2.size
            for (b1, b2) in zip(sorted(py.blocks), sorted(rs.blocks)))

    kwargs = {
        "base":
        FileManifest(
            author=DeviceID("user@device"),
            id=EntryID.new(),
            parent=EntryID.new(),
            version=42,
            size=1337,
            blocksize=85,
            timestamp=pendulum.now(),
            created=pendulum.now(),
            updated=pendulum.now(),
            blocks=(BlockAccess(
                id=BlockID.new(),
                key=SecretKey.generate(),
                offset=0,
                size=1024,
                digest=HashDigest.from_data(b"a"),
            ), ),
        ),
        "need_sync":
        True,
        "updated":
        pendulum.now(),
        "size":
        42,
        "blocksize":
        64,
        "blocks": ((
            Chunk(
                id=ChunkID.new(),
                start=0,
                stop=250,
                raw_offset=0,
                raw_size=512,
                access=BlockAccess(
                    id=BlockID.new(),
                    key=SecretKey.generate(),
                    offset=0,
                    size=512,
                    digest=HashDigest.from_data(b"aa"),
                ),
            ),
            Chunk(id=ChunkID.new(),
                  start=0,
                  stop=250,
                  raw_offset=250,
                  raw_size=250,
                  access=None),
        ), ),
    }

    py_lfm = _PyLocalFileManifest(**kwargs)
    rs_lfm = LocalFileManifest(**kwargs)
    _assert_local_file_manifest_eq(py_lfm, rs_lfm)

    kwargs = {
        "base":
        kwargs["base"].evolve(
            **{
                "author":
                DeviceID("a@b"),
                "id":
                EntryID.new(),
                "parent":
                EntryID.new(),
                "version":
                1337,
                "size":
                4096,
                "blocksize":
                512,
                "timestamp":
                pendulum.now(),
                "created":
                pendulum.now(),
                "updated":
                pendulum.now(),
                "blocks": (BlockAccess(
                    id=BlockID.new(),
                    key=SecretKey.generate(),
                    offset=64,
                    size=2048,
                    digest=HashDigest.from_data(b"b"),
                ), ),
            }),
        "need_sync":
        False,
        "updated":
        pendulum.now(),
        "size":
        2048,
        "blocksize":
        1024,
        "blocks": ((
            Chunk(
                id=ChunkID.new(),
                start=0,
                stop=1024,
                raw_offset=0,
                raw_size=1024,
                access=BlockAccess(
                    id=BlockID.new(),
                    key=SecretKey.generate(),
                    offset=0,
                    size=1024,
                    digest=HashDigest.from_data(b"bb"),
                ),
            ),
            Chunk(
                id=ChunkID.new(),
                start=1024,
                stop=2048,
                raw_offset=1024,
                raw_size=1024,
                access=None,
            ),
        ), ),
    }

    py_lfm = py_lfm.evolve(**kwargs)
    rs_lfm = rs_lfm.evolve(**kwargs)
    _assert_local_file_manifest_eq(py_lfm, rs_lfm)

    sk = SecretKey.generate()

    py_enc = py_lfm.dump_and_encrypt(sk)
    rs_enc = rs_lfm.dump_and_encrypt(sk)

    # Decrypt rust encrypted with Python and vice versa
    lfm1 = _PyLocalFileManifest.decrypt_and_load(rs_enc, sk)
    lfm2 = LocalFileManifest.decrypt_and_load(py_enc, sk)
    assert isinstance(lfm1, LocalFileManifest)
    assert isinstance(lfm2, LocalFileManifest)
    assert lfm1 == lfm2

    py_lfm = py_lfm.evolve(**{"size": 1337})
    rs_lfm = rs_lfm.evolve(**{"size": 1337})
    _assert_local_file_manifest_eq(py_lfm, rs_lfm)

    with pytest.raises(AssertionError):
        py_lfm.assert_integrity()
    with pytest.raises(AssertionError):
        rs_lfm.assert_integrity()

    assert py_lfm.to_stats() == rs_lfm.to_stats()
    assert py_lfm.parent == rs_lfm.parent
    assert py_lfm.get_chunks(0) == rs_lfm.get_chunks(0)
    assert py_lfm.get_chunks(1000) == rs_lfm.get_chunks(1000)
    assert py_lfm.asdict() == rs_lfm.asdict()

    di = DeviceID("a@b")
    ts = pendulum.now()

    kwargs = {
        "size":
        1024,
        "blocksize":
        1024,
        "blocks": ((Chunk(
            id=ChunkID.new(),
            start=0,
            stop=1024,
            raw_offset=0,
            raw_size=1024,
            access=BlockAccess(
                id=BlockID.new(),
                key=SecretKey.generate(),
                offset=0,
                size=1024,
                digest=HashDigest.from_data(b"bb"),
            ),
        ), ), ),
    }

    py_lfm = py_lfm.evolve(**kwargs)
    rs_lfm = rs_lfm.evolve(**kwargs)
    _assert_local_file_manifest_eq(py_lfm, rs_lfm)

    py_rfm = py_lfm.to_remote(author=di, timestamp=ts)
    rs_rfm = rs_lfm.to_remote(author=di, timestamp=ts)
    _assert_file_manifest_eq(py_rfm, rs_rfm)

    py_lfm2 = _PyLocalFileManifest.from_remote(py_rfm)
    rs_lfm2 = LocalFileManifest.from_remote(rs_rfm)
    _assert_local_file_manifest_eq(py_lfm2,
                                   rs_lfm2,
                                   exclude_base=True,
                                   exclude_id=True)

    py_lfm2 = _PyLocalFileManifest.from_remote_with_local_context(
        remote=py_rfm,
        prevent_sync_pattern=r".+",
        local_manifest=py_lfm2,
        timestamp=ts)
    rs_lfm2 = LocalFileManifest.from_remote_with_local_context(
        remote=rs_rfm,
        prevent_sync_pattern=r".+",
        local_manifest=rs_lfm2,
        timestamp=ts)

    assert py_lfm.match_remote(py_rfm) == rs_lfm.match_remote(rs_rfm)

    py_lfm = py_lfm.evolve_and_mark_updated(timestamp=ts, size=4096)
    rs_lfm = rs_lfm.evolve_and_mark_updated(timestamp=ts, size=4096)

    _assert_local_file_manifest_eq(py_lfm,
                                   rs_lfm,
                                   exclude_base=True,
                                   exclude_id=True)

    with pytest.raises(TypeError) as excinfo:
        py_lfm.evolve_and_mark_updated(timestamp=ts, need_sync=True)
    assert str(excinfo.value) == "Unexpected keyword argument `need_sync`"
    with pytest.raises(TypeError) as excinfo:
        rs_lfm.evolve_and_mark_updated(timestamp=ts, need_sync=True)
    assert str(excinfo.value) == "Unexpected keyword argument `need_sync`"

    ei = EntryID.new()

    # Without blocksize
    py_lfm = _PyLocalFileManifest.new_placeholder(author=di,
                                                  parent=ei,
                                                  timestamp=ts)
    rs_lfm = LocalFileManifest.new_placeholder(author=di,
                                               parent=ei,
                                               timestamp=ts)
    _assert_local_file_manifest_eq(py_lfm,
                                   rs_lfm,
                                   exclude_base=True,
                                   exclude_id=True)
    # With blocksize
    py_lfm = _PyLocalFileManifest.new_placeholder(author=di,
                                                  parent=ei,
                                                  timestamp=ts,
                                                  blocksize=1024)
    rs_lfm = LocalFileManifest.new_placeholder(author=di,
                                               parent=ei,
                                               timestamp=ts,
                                               blocksize=1024)
    _assert_local_file_manifest_eq(py_lfm,
                                   rs_lfm,
                                   exclude_base=True,
                                   exclude_id=True)
コード例 #18
0
ファイル: test_invite.py プロジェクト: Scille/parsec-cloud
def test_invite_device_confirmation():
    from parsec.api.data.invite import (
        _RsInviteDeviceConfirmation,
        InviteDeviceConfirmation,
        _PyInviteDeviceConfirmation,
    )

    assert InviteDeviceConfirmation is _RsInviteDeviceConfirmation

    di = DeviceID("a@b")
    dl = DeviceLabel("label")
    hh = HumanHandle("*****@*****.**",
                     "Hubert Farnsworth")
    profile = UserProfile.STANDARD
    pk = PrivateKey.generate()
    umi = EntryID.new()
    umk = SecretKey.generate()
    sk = SigningKey.generate()
    vk = sk.verify_key
    sek = SecretKey.generate()

    py_idc = _PyInviteDeviceConfirmation(
        device_id=di,
        device_label=dl,
        human_handle=hh,
        profile=profile,
        private_key=pk,
        user_manifest_id=umi,
        user_manifest_key=umk,
        root_verify_key=vk,
    )
    rs_idc = InviteDeviceConfirmation(
        device_id=di,
        device_label=dl,
        human_handle=hh,
        profile=profile,
        private_key=pk,
        user_manifest_id=umi,
        user_manifest_key=umk,
        root_verify_key=vk,
    )

    assert rs_idc.device_label.str == py_idc.device_label.str
    assert str(rs_idc.human_handle) == str(py_idc.human_handle)
    assert rs_idc.device_id.str == py_idc.device_id.str
    assert rs_idc.profile == py_idc.profile
    assert rs_idc.user_manifest_id.hex == py_idc.user_manifest_id.hex

    rs_encrypted = rs_idc.dump_and_encrypt(key=sek)
    py_encrypted = py_idc.dump_and_encrypt(key=sek)

    # Decrypt Rust-encrypted with Rust
    rs_idc2 = InviteDeviceConfirmation.decrypt_and_load(rs_encrypted, sek)
    assert rs_idc.device_label.str == rs_idc2.device_label.str
    assert str(rs_idc.human_handle) == str(rs_idc2.human_handle)
    assert rs_idc.device_id.str == rs_idc2.device_id.str
    assert rs_idc.profile == rs_idc2.profile
    assert rs_idc.user_manifest_id.hex == rs_idc2.user_manifest_id.hex

    # Decrypt Python-encrypted with Python
    rs_idc3 = InviteDeviceConfirmation.decrypt_and_load(py_encrypted, sek)
    assert rs_idc.device_label.str == rs_idc3.device_label.str
    assert str(rs_idc.human_handle) == str(rs_idc3.human_handle)
    assert rs_idc.device_id.str == rs_idc3.device_id.str
    assert rs_idc.profile == rs_idc3.profile
    assert rs_idc.user_manifest_id.hex == rs_idc3.user_manifest_id.hex

    # Decrypt Rust-encrypted with Python
    py_idc2 = _PyInviteDeviceConfirmation.decrypt_and_load(rs_encrypted, sek)
    assert rs_idc.device_label.str == py_idc2.device_label.str
    assert str(rs_idc.human_handle) == str(py_idc2.human_handle)
    assert rs_idc.device_id.str == py_idc2.device_id.str
    assert rs_idc.profile == py_idc2.profile
    assert rs_idc.user_manifest_id.hex == rs_idc2.user_manifest_id.hex

    # With human_handle and device_label as None
    py_idc = _PyInviteDeviceConfirmation(
        device_id=di,
        device_label=None,
        human_handle=None,
        profile=profile,
        private_key=pk,
        user_manifest_id=umi,
        user_manifest_key=umk,
        root_verify_key=vk,
    )
    rs_idc = InviteDeviceConfirmation(
        device_id=di,
        device_label=None,
        human_handle=None,
        profile=profile,
        private_key=pk,
        user_manifest_id=umi,
        user_manifest_key=umk,
        root_verify_key=vk,
    )

    assert py_idc.device_label is None
    assert rs_idc.device_label is None
    assert py_idc.human_handle is None
    assert rs_idc.human_handle is None
コード例 #19
0
def test_file_table_sort(qtbot, core_config):
    switch_language(core_config, "en")

    w = FileTable(parent=None)
    qtbot.add_widget(w)
    w.add_parent_workspace()
    w.add_folder(EntryName("Dir1"), EntryID.new(), True, False)
    w.add_file(
        EntryName("File1.txt"),
        EntryID.new(),
        100,
        pendulum.datetime(2000, 1, 15),
        pendulum.datetime(2000, 1, 20),
        True,
        False,
    )
    w.add_file(
        EntryName("AnotherFile.txt"),
        EntryID.new(),
        80,
        pendulum.datetime(2000, 1, 10),
        pendulum.datetime(2000, 1, 25),
        True,
        False,
    )
    assert w.rowCount() == 4
    assert w.item(0, 1).text() == "Workspaces list"
    assert w.item(1, 1).text() == "Dir1"
    assert w.item(2, 1).text() == "File1.txt"
    assert w.item(3, 1).text() == "AnotherFile.txt"

    # Name
    w.sortByColumn(1, QtCore.Qt.AscendingOrder)
    assert w.item(0, 1).text() == "Workspaces list"
    assert w.item(1, 1).text() == "AnotherFile.txt"
    assert w.item(2, 1).text() == "Dir1"
    assert w.item(3, 1).text() == "File1.txt"

    w.sortByColumn(1, QtCore.Qt.DescendingOrder)
    assert w.item(0, 1).text() == "Workspaces list"
    assert w.item(1, 1).text() == "File1.txt"
    assert w.item(2, 1).text() == "Dir1"
    assert w.item(3, 1).text() == "AnotherFile.txt"

    # Created
    w.sortByColumn(2, QtCore.Qt.AscendingOrder)
    assert w.item(0, 1).text() == "Workspaces list"
    assert w.item(1, 1).text() == "Dir1"
    assert w.item(2, 1).text() == "AnotherFile.txt"
    assert w.item(3, 1).text() == "File1.txt"

    w.sortByColumn(2, QtCore.Qt.DescendingOrder)
    assert w.item(0, 1).text() == "Workspaces list"
    assert w.item(1, 1).text() == "File1.txt"
    assert w.item(2, 1).text() == "AnotherFile.txt"
    assert w.item(3, 1).text() == "Dir1"

    # Updated
    w.sortByColumn(3, QtCore.Qt.AscendingOrder)
    assert w.item(0, 1).text() == "Workspaces list"
    assert w.item(1, 1).text() == "Dir1"
    assert w.item(2, 1).text() == "File1.txt"
    assert w.item(3, 1).text() == "AnotherFile.txt"

    w.sortByColumn(3, QtCore.Qt.DescendingOrder)
    assert w.item(0, 1).text() == "Workspaces list"
    assert w.item(1, 1).text() == "AnotherFile.txt"
    assert w.item(2, 1).text() == "File1.txt"
    assert w.item(3, 1).text() == "Dir1"

    # Size
    w.sortByColumn(4, QtCore.Qt.AscendingOrder)
    assert w.item(0, 1).text() == "Workspaces list"
    assert w.item(1, 1).text() == "Dir1"
    assert w.item(2, 1).text() == "AnotherFile.txt"
    assert w.item(3, 1).text() == "File1.txt"

    w.sortByColumn(4, QtCore.Qt.DescendingOrder)
    assert w.item(0, 1).text() == "Workspaces list"
    assert w.item(1, 1).text() == "File1.txt"
    assert w.item(2, 1).text() == "AnotherFile.txt"
    assert w.item(3, 1).text() == "Dir1"
コード例 #20
0
def test_local_workspace_manifest():
    from parsec.core.types.manifest import (
        _RsLocalWorkspaceManifest,
        LocalWorkspaceManifest,
        _PyLocalWorkspaceManifest,
    )

    assert LocalWorkspaceManifest is _RsLocalWorkspaceManifest

    def _assert_local_workspace_manifest_eq(py,
                                            rs,
                                            exclude_base=False,
                                            exclude_id=False):
        assert isinstance(py, _PyLocalWorkspaceManifest)
        assert isinstance(rs, _RsLocalWorkspaceManifest)

        if not exclude_base:
            assert py.base == rs.base
        if not exclude_id:
            assert py.id == rs.id
        assert py.need_sync == rs.need_sync
        assert py.updated == rs.updated
        assert py.speculative == rs.speculative
        assert len(py.children) == len(rs.children)
        assert isinstance(rs.children, type(
            py.children)), "Rust type is {}, should be {}".format(
                type(rs.children), type(py.children))
        assert all(
            isinstance(name1, EntryName) and isinstance(id1, EntryID)
            and name1 == name2 and id1 == id2
            for ((name1, id1), (name2, id2)) in zip(
                sorted(py.children.items()), sorted(rs.children.items())))
        assert len(py.local_confinement_points) == len(
            rs.local_confinement_points)
        assert py.local_confinement_points == rs.local_confinement_points
        assert len(py.remote_confinement_points) == len(
            rs.remote_confinement_points)
        assert py.remote_confinement_points == rs.remote_confinement_points

    def _assert_workspace_manifest_eq(py, rs):
        assert py.author == rs.author
        assert py.version == rs.version
        assert py.timestamp == rs.timestamp
        assert py.created == rs.created
        assert py.updated == rs.updated
        assert py.children == rs.children

    kwargs = {
        "base":
        WorkspaceManifest(
            author=DeviceID("user@device"),
            id=EntryID.new(),
            version=42,
            timestamp=pendulum.now(),
            created=pendulum.now(),
            updated=pendulum.now(),
            children={EntryName("file1.txt"): EntryID.new()},
        ),
        "need_sync":
        True,
        "updated":
        pendulum.now(),
        "children": {
            EntryName("wksp2"): EntryID.new()
        },
        "local_confinement_points":
        frozenset({EntryID.new()}),
        "remote_confinement_points":
        frozenset({EntryID.new()}),
        "speculative":
        True,
    }

    py_lwm = _PyLocalWorkspaceManifest(**kwargs)
    rs_lwm = LocalWorkspaceManifest(**kwargs)
    _assert_local_workspace_manifest_eq(py_lwm, rs_lwm)

    kwargs = {
        "base":
        kwargs["base"].evolve(
            **{
                "author": DeviceID("a@b"),
                "id": EntryID.new(),
                "version": 1337,
                "timestamp": pendulum.now(),
                "created": pendulum.now(),
                "updated": pendulum.now(),
                "children": {
                    EntryName("file2.mp4"): EntryID.new()
                },
            }),
        "need_sync":
        False,
        "updated":
        pendulum.now(),
        "children": {
            EntryName("wksp1"): EntryID.new()
        },
        "local_confinement_points":
        frozenset({EntryID.new()}),
        "remote_confinement_points":
        frozenset({EntryID.new()}),
        "speculative":
        False,
    }

    py_lwm = py_lwm.evolve(**kwargs)
    rs_lwm = rs_lwm.evolve(**kwargs)
    _assert_local_workspace_manifest_eq(py_lwm, rs_lwm)

    sk = SecretKey.generate()

    py_enc = py_lwm.dump_and_encrypt(sk)
    rs_enc = py_lwm.dump_and_encrypt(sk)

    # Decrypt rust encrypted with Python and vice versa
    lwm1 = _PyLocalWorkspaceManifest.decrypt_and_load(rs_enc, sk)
    lwm2 = LocalWorkspaceManifest.decrypt_and_load(py_enc, sk)
    assert isinstance(lwm1, LocalWorkspaceManifest)
    assert isinstance(lwm2, LocalWorkspaceManifest)
    assert lwm1 == lwm2

    assert py_lwm.to_stats() == rs_lwm.to_stats()
    assert py_lwm.asdict() == rs_lwm.asdict()

    ts = pendulum.now()
    ei = EntryID.new()
    di = DeviceID("a@b")

    # With optional parameters
    py_lwm = _PyLocalWorkspaceManifest.new_placeholder(author=di,
                                                       id=ei,
                                                       timestamp=ts,
                                                       speculative=True)
    rs_lwm = LocalWorkspaceManifest.new_placeholder(author=di,
                                                    id=ei,
                                                    timestamp=ts,
                                                    speculative=True)
    _assert_local_workspace_manifest_eq(py_lwm,
                                        rs_lwm,
                                        exclude_base=True,
                                        exclude_id=True)

    # Without optional parameters
    py_lwm = _PyLocalWorkspaceManifest.new_placeholder(author=di, timestamp=ts)
    rs_lwm = LocalWorkspaceManifest.new_placeholder(author=di, timestamp=ts)
    _assert_local_workspace_manifest_eq(py_lwm,
                                        rs_lwm,
                                        exclude_base=True,
                                        exclude_id=True)

    py_rwm = py_lwm.to_remote(author=di, timestamp=ts)
    rs_rwm = rs_lwm.to_remote(author=di, timestamp=ts)
    _assert_workspace_manifest_eq(py_rwm, rs_rwm)

    children = {EntryName("wksp1"): EntryID.new()}
    py_lwm = py_lwm.evolve_and_mark_updated(timestamp=ts, children=children)
    rs_lwm = rs_lwm.evolve_and_mark_updated(timestamp=ts, children=children)

    _assert_local_workspace_manifest_eq(py_lwm,
                                        rs_lwm,
                                        exclude_base=True,
                                        exclude_id=True)

    with pytest.raises(TypeError) as excinfo:
        py_lwm.evolve_and_mark_updated(timestamp=ts, need_sync=True)
    assert str(excinfo.value) == "Unexpected keyword argument `need_sync`"
    with pytest.raises(TypeError) as excinfo:
        rs_lwm.evolve_and_mark_updated(timestamp=ts, need_sync=True)
    assert str(excinfo.value) == "Unexpected keyword argument `need_sync`"

    py_lwm2 = _PyLocalWorkspaceManifest.from_remote(py_rwm, r".+")
    rs_lwm2 = LocalWorkspaceManifest.from_remote(rs_rwm, r".+")
    _assert_local_workspace_manifest_eq(py_lwm2,
                                        rs_lwm2,
                                        exclude_base=True,
                                        exclude_id=True)

    py_lwm2 = _PyLocalWorkspaceManifest.from_remote_with_local_context(
        remote=py_rwm,
        prevent_sync_pattern=r".+",
        local_manifest=py_lwm2,
        timestamp=ts)
    rs_lwm2 = LocalWorkspaceManifest.from_remote_with_local_context(
        remote=rs_rwm,
        prevent_sync_pattern=r".+",
        local_manifest=rs_lwm2,
        timestamp=ts)

    assert py_lwm.match_remote(py_rwm) == rs_lwm.match_remote(rs_rwm)
コード例 #21
0
def test_local_user_manifest():
    from parsec.core.types.manifest import (
        _RsLocalUserManifest,
        LocalUserManifest,
        _PyLocalUserManifest,
    )

    assert LocalUserManifest is _RsLocalUserManifest

    def _assert_local_user_manifest_eq(py,
                                       rs,
                                       exclude_base=False,
                                       exclude_id=False):
        assert isinstance(py, _PyLocalUserManifest)
        assert isinstance(rs, _RsLocalUserManifest)

        if not exclude_base:
            assert py.base == rs.base
        if not exclude_id:
            assert py.id == rs.id
        assert py.need_sync == rs.need_sync
        assert py.updated == rs.updated
        assert py.last_processed_message == rs.last_processed_message
        assert len(py.workspaces) == len(rs.workspaces)
        assert isinstance(rs.workspaces, type(py.workspaces))
        assert py.workspaces == rs.workspaces
        assert py.speculative == rs.speculative

    def _assert_user_manifest_eq(py, rs):
        assert py.author == rs.author
        assert py.version == rs.version
        assert py.timestamp == rs.timestamp
        assert py.created == rs.created
        assert py.updated == rs.updated
        assert py.last_processed_message == rs.last_processed_message
        assert py.workspaces == rs.workspaces
        assert isinstance(rs.workspaces, type(py.workspaces))

    kwargs = {
        "base":
        UserManifest(
            author=DeviceID("user@device"),
            id=EntryID.new(),
            version=42,
            timestamp=pendulum.now(),
            created=pendulum.now(),
            updated=pendulum.now(),
            last_processed_message=0,
            workspaces=(WorkspaceEntry.new(EntryName("user"),
                                           pendulum.now()), ),
        ),
        "need_sync":
        True,
        "updated":
        pendulum.now(),
        "last_processed_message":
        0,
        "workspaces": (),
        "speculative":
        True,
    }

    py_lum = _PyLocalUserManifest(**kwargs)
    rs_lum = LocalUserManifest(**kwargs)
    _assert_local_user_manifest_eq(py_lum, rs_lum)

    kwargs = {
        "base":
        kwargs["base"].evolve(
            **{
                "author":
                DeviceID("a@b"),
                "id":
                EntryID.new(),
                "version":
                1337,
                "timestamp":
                pendulum.now(),
                "created":
                pendulum.now(),
                "updated":
                pendulum.now(),
                "last_processed_message":
                1,
                "workspaces": (
                    WorkspaceEntry.new(EntryName("user"), pendulum.now()), ),
            }),
        "need_sync":
        False,
        "updated":
        pendulum.now(),
        "last_processed_message":
        1,
        "workspaces": (WorkspaceEntry.new(EntryName("wk"), pendulum.now()), ),
        "speculative":
        False,
    }

    py_lum = py_lum.evolve(**kwargs)
    rs_lum = rs_lum.evolve(**kwargs)
    _assert_local_user_manifest_eq(py_lum, rs_lum)

    sk = SecretKey.generate()

    py_enc = py_lum.dump_and_encrypt(sk)
    rs_enc = py_lum.dump_and_encrypt(sk)

    # Decrypt rust encrypted with Python and vice versa
    lum1 = _PyLocalUserManifest.decrypt_and_load(rs_enc, sk)
    lum2 = LocalUserManifest.decrypt_and_load(py_enc, sk)
    assert isinstance(lum1, LocalUserManifest)
    assert isinstance(lum2, LocalUserManifest)
    assert lum1 == lum2

    assert py_lum.to_stats() == rs_lum.to_stats()
    assert py_lum.asdict() == rs_lum.asdict()

    ts = pendulum.now()
    ei = EntryID.new()
    di = DeviceID("a@b")

    # With optional parameters
    py_lum = _PyLocalUserManifest.new_placeholder(author=di,
                                                  id=ei,
                                                  timestamp=ts,
                                                  speculative=True)
    rs_lum = LocalUserManifest.new_placeholder(author=di,
                                               id=ei,
                                               timestamp=ts,
                                               speculative=True)
    _assert_local_user_manifest_eq(py_lum,
                                   rs_lum,
                                   exclude_base=True,
                                   exclude_id=True)

    # Without optional parameters
    py_lum = _PyLocalUserManifest.new_placeholder(author=di, timestamp=ts)
    rs_lum = LocalUserManifest.new_placeholder(author=di, timestamp=ts)
    _assert_local_user_manifest_eq(py_lum,
                                   rs_lum,
                                   exclude_base=True,
                                   exclude_id=True)

    py_rum = py_lum.to_remote(author=di, timestamp=ts)
    rs_rum = rs_lum.to_remote(author=di, timestamp=ts)
    _assert_user_manifest_eq(py_rum, rs_rum)

    assert py_lum.match_remote(py_rum) == rs_lum.match_remote(rs_rum)

    py_lum2 = _PyLocalUserManifest.from_remote(py_rum)
    rs_lum2 = LocalUserManifest.from_remote(rs_rum)
    _assert_local_user_manifest_eq(py_lum2,
                                   rs_lum2,
                                   exclude_base=True,
                                   exclude_id=True)

    _PyLocalUserManifest.from_remote_with_local_context(
        remote=py_rum,
        prevent_sync_pattern=r".+",
        local_manifest=py_lum2,
        timestamp=ts)
    LocalUserManifest.from_remote_with_local_context(
        remote=rs_rum,
        prevent_sync_pattern=r".+",
        local_manifest=rs_lum2,
        timestamp=ts)
コード例 #22
0
async def test_rename_unknown_workspace(alice_user_fs):
    dummy_id = EntryID.new()
    with pytest.raises(FSWorkspaceNotFoundError):
        await alice_user_fs.workspace_rename(dummy_id, EntryName("whatever"))
コード例 #23
0
ファイル: test_rsync.py プロジェクト: Scille/parsec-cloud
async def test_update_file(alice_workspace, monkeypatch):
    block_mock1 = mock.Mock()
    block_mock1.digest = b"block1"
    block_mock2 = mock.Mock()
    block_mock2.digest = b"block2"

    manifest_mock = mock.Mock(spec=FolderManifest)
    manifest_mock.blocks = [block_mock1, block_mock2]

    load_manifest_mock = AsyncMock(spec=mock.Mock,
                                   side_effect=lambda x: manifest_mock)
    alice_workspace.remote_loader.load_manifest = load_manifest_mock

    write_bytes_mock = AsyncMock(spec=mock.Mock)
    alice_workspace.write_bytes = write_bytes_mock

    sync_by_id_mock = AsyncMock(spec=mock.Mock)
    alice_workspace.sync_by_id = sync_by_id_mock
    monkeypatch.setattr(HashDigest, "from_data",
                        mock.Mock(side_effect=lambda x: x))

    with mock.patch(
            "parsec.core.cli.rsync._chunks_from_path",
            AsyncMock(spec=mock.Mock, side_effect=[[b"block1", b"block2"]]),
    ):
        entry_id = EntryID.new()
        await rsync._update_file(alice_workspace, entry_id,
                                 FsPath("/src_file"),
                                 FsPath("/path_in_workspace"))
        rsync._chunks_from_path.assert_called_once_with(FsPath("/src_file"))
        load_manifest_mock.assert_called_once_with(entry_id)
        write_bytes_mock.assert_not_called()
        sync_by_id_mock.assert_called_once_with(entry_id,
                                                remote_changed=False,
                                                recursive=False)

    load_manifest_mock.reset_mock()
    sync_by_id_mock.reset_mock()

    with mock.patch(
            "parsec.core.cli.rsync._chunks_from_path",
            AsyncMock(spec=mock.Mock, side_effect=[[b"block1", b"block3"]]),
    ):

        await rsync._update_file(alice_workspace, entry_id,
                                 FsPath("/src_file"),
                                 FsPath("/path_in_workspace"))
        rsync._chunks_from_path.assert_called_once_with(FsPath("/src_file"))
        load_manifest_mock.assert_called_once_with(entry_id)
        write_bytes_mock.assert_called_once_with(FsPath("/path_in_workspace"),
                                                 b"block3", len("block1"))
        sync_by_id_mock.assert_called_once_with(entry_id,
                                                remote_changed=False,
                                                recursive=False)

    load_manifest_mock.reset_mock()
    sync_by_id_mock.reset_mock()
    write_bytes_mock.reset_mock()

    with mock.patch(
            "parsec.core.cli.rsync._chunks_from_path",
            AsyncMock(spec=mock.Mock, side_effect=[[b"block3", b"block4"]]),
    ):
        await rsync._update_file(alice_workspace, entry_id,
                                 FsPath("/src_file"),
                                 FsPath("/path_in_workspace"))
        rsync._chunks_from_path.assert_called_once_with(FsPath("/src_file"))
        alice_workspace.remote_loader.load_manifest.assert_called_once_with(
            entry_id)
        write_bytes_mock.assert_has_calls([
            mock.call(FsPath("/path_in_workspace"), b"block3", 0),
            mock.call(FsPath("/path_in_workspace"), b"block4", len("block3")),
        ])
        sync_by_id_mock.assert_called_once_with(entry_id,
                                                remote_changed=False,
                                                recursive=False)
コード例 #24
0
def test_file_manifest():
    from parsec.api.data.manifest import _RsFileManifest, FileManifest, _PyFileManifest, BlockAccess

    assert FileManifest is _RsFileManifest

    def _assert_file_manifest_eq(py, rs):
        assert isinstance(py, _PyFileManifest)
        assert isinstance(rs, _RsFileManifest)

        assert py.author == rs.author
        assert py.id == rs.id
        assert py.parent == rs.parent
        assert py.version == rs.version
        assert py.size == rs.size
        assert py.blocksize == rs.blocksize
        assert py.timestamp == rs.timestamp
        assert py.created == rs.created
        assert py.updated == rs.updated
        assert len(py.blocks) == len(rs.blocks)
        assert all(
            isinstance(b2, BlockAccess) and b1.id == b2.id
            and b1.offset == b2.offset and b1.size == b2.size
            for (b1, b2) in zip(py.blocks, rs.blocks))

    kwargs = {
        "author":
        DeviceID("user@device"),
        "id":
        EntryID.new(),
        "parent":
        EntryID.new(),
        "version":
        42,
        "size":
        1337,
        "blocksize":
        64,
        "timestamp":
        pendulum.now(),
        "created":
        pendulum.now(),
        "updated":
        pendulum.now(),
        "blocks": (BlockAccess(
            id=BlockID.new(),
            key=SecretKey.generate(),
            offset=0,
            size=1024,
            digest=HashDigest.from_data(b"a"),
        ), ),
    }

    py_fm = _PyFileManifest(**kwargs)
    rs_fm = FileManifest(**kwargs)
    _assert_file_manifest_eq(py_fm, rs_fm)

    kwargs = {
        "author":
        DeviceID("a@b"),
        "id":
        EntryID.new(),
        "parent":
        EntryID.new(),
        "version":
        1337,
        "timestamp":
        pendulum.now(),
        "created":
        pendulum.now(),
        "updated":
        pendulum.now(),
        "blocks": (BlockAccess(
            id=BlockID.new(),
            key=SecretKey.generate(),
            offset=64,
            size=2048,
            digest=HashDigest.from_data(b"b"),
        ), ),
    }

    py_fm = py_fm.evolve(**kwargs)
    rs_fm = rs_fm.evolve(**kwargs)
    _assert_file_manifest_eq(py_fm, rs_fm)
コード例 #25
0
def test_workspace_manifest():
    from parsec.api.data.manifest import (
        _RsWorkspaceManifest,
        WorkspaceManifest,
        _PyWorkspaceManifest,
    )

    assert WorkspaceManifest is _RsWorkspaceManifest

    def _assert_workspace_manifest_eq(py, rs):
        assert isinstance(py, _PyWorkspaceManifest)
        assert isinstance(rs, _RsWorkspaceManifest)

        assert py.author == rs.author
        assert py.id == rs.id
        assert py.version == rs.version
        assert py.timestamp == rs.timestamp
        assert py.created == rs.created
        assert py.updated == rs.updated
        assert py.children == rs.children

    kwargs = {
        "author": DeviceID("user@device"),
        "id": EntryID.new(),
        "version": 42,
        "timestamp": pendulum.now(),
        "created": pendulum.now(),
        "updated": pendulum.now(),
        "children": {
            EntryName("file1.txt"): EntryID.new()
        },
    }
    py_wm = _PyWorkspaceManifest(**kwargs)
    rs_wm = WorkspaceManifest(**kwargs)
    _assert_workspace_manifest_eq(py_wm, rs_wm)

    kwargs = {
        "author": DeviceID("a@b"),
        "id": EntryID.new(),
        "version": 1337,
        "timestamp": pendulum.now(),
        "created": pendulum.now(),
        "updated": pendulum.now(),
        "children": {
            EntryName("file2.mp4"): EntryID.new()
        },
    }

    py_wm = py_wm.evolve(**kwargs)
    rs_wm = rs_wm.evolve(**kwargs)
    _assert_workspace_manifest_eq(py_wm, rs_wm)

    signing_key = SigningKey(b"a" * 32)
    secret_key = SecretKey.generate()

    py_signed_and_encrypted = py_wm.dump_sign_and_encrypt(
        signing_key, secret_key)
    rs_signed_and_encrypted = rs_wm.dump_sign_and_encrypt(
        signing_key, secret_key)

    wm1 = WorkspaceManifest.decrypt_verify_and_load(py_signed_and_encrypted,
                                                    secret_key,
                                                    signing_key.verify_key,
                                                    py_wm.author,
                                                    py_wm.timestamp)
    wm2 = _PyWorkspaceManifest.decrypt_verify_and_load(rs_signed_and_encrypted,
                                                       secret_key,
                                                       signing_key.verify_key,
                                                       py_wm.author,
                                                       py_wm.timestamp)
    assert isinstance(wm1, WorkspaceManifest)
    assert isinstance(wm2, WorkspaceManifest)
    assert wm1 == wm2