def test_merge_local_user_manifest_changes_placeholder(gen_date, alice): d1, d2, d3, d4 = [gen_date() for _ in range(4)] w1 = WorkspaceEntry.new(name="w1") w2 = WorkspaceEntry.new(name="w2") w3 = WorkspaceEntry.new(name="w3") diverged = LocalUserManifest.new_placeholder(alice.device_id, id=alice.user_manifest_id, now=d4).evolve( last_processed_message=30, workspaces=(w1, w3)) target = UserManifest( author=alice.device_id, timestamp=d2, id=alice.user_manifest_id, version=3, created=d1, updated=d3, last_processed_message=20, workspaces=(w1, w2), ) expected_merged = LocalUserManifest(base=target, updated=d4, last_processed_message=30, workspaces=(w1, w2, w3), need_sync=True) merged = merge_local_user_manifests(diverged, target) assert merged == expected_merged
async def test_sync_placeholder(running_backend, backend_data_binder, local_device_factory, user_fs_factory, with_workspace): device = local_device_factory() await backend_data_binder.bind_device(device, initial_user_manifest_in_v0=True) async with user_fs_factory(device, initialize_in_v0=True) as user_fs: um_v0 = user_fs.get_user_manifest() expected_um = LocalUserManifest.new_placeholder( device.device_id, id=device.user_manifest_id, now=um_v0.created) assert um_v0 == expected_um if with_workspace: with freeze_time("2000-01-02"): wid = await user_fs.workspace_create("w1") um = user_fs.get_user_manifest() expected_um = um_v0.evolve( updated=datetime(2000, 1, 2), workspaces=(WorkspaceEntry( name="w1", id=wid, key=ANY, encryption_revision=1, encrypted_on=datetime(2000, 1, 2), role_cached_on=datetime(2000, 1, 2), role=WorkspaceRole.OWNER, ), ), ) assert um == expected_um with freeze_time("2000-01-02"): await user_fs.sync() um = user_fs.get_user_manifest() expected_base_um = UserManifest( author=device.device_id, timestamp=datetime(2000, 1, 2), id=device.user_manifest_id, version=1, created=expected_um.created, updated=expected_um.updated, last_processed_message=0, workspaces=expected_um.workspaces, ) expected_um = LocalUserManifest( base=expected_base_um, need_sync=False, updated=expected_um.updated, last_processed_message=0, workspaces=expected_base_um.workspaces, ) assert um == expected_um
async def _load_user_manifest(self) -> None: try: await self.manifest_storage.get_manifest(self.user_manifest_id) except FSLocalMissError: # In the unlikely event the user manifest is not present in # local (e.g. device just created or during tests), we fall # back on an empty manifest which is a good aproximation of # the very first version of the manifest (field `created` is # invalid, but it will be corrected by the merge during sync). manifest = LocalUserManifest.new_placeholder( self.device.device_id, id=self.device.user_manifest_id) await self.manifest_storage.set_manifest(self.user_manifest_id, manifest)
def create_manifest(device, type=LocalWorkspaceManifest, use_legacy_none_author=False): author = device.device_id if type is LocalUserManifest: manifest = LocalUserManifest.new_placeholder(author) elif type is LocalWorkspaceManifest: manifest = type.new_placeholder(author) else: manifest = type.new_placeholder(author, parent=EntryID()) if use_legacy_none_author: base = manifest.base.evolve(author=None) manifest = manifest.evolve(base=base) return manifest
def user_manifest(alice): return LocalUserManifest.new_placeholder(alice.device_id, id=alice.user_manifest_id)