def test_moved_href(): ''' Concrete application: ppl_ stores contact aliases in filenames, which means item's hrefs get changed. Vdirsyncer doesn't synchronize this data, but also shouldn't do things like deleting and re-uploading to the server. .. _ppl: http://ppladdressbook.org/ ''' a = MemoryStorage() b = MemoryStorage() status = {} href, etag = a.upload(Item(u'UID:haha')) sync(a, b, status) b.items['lol'] = b.items.pop('haha') # The sync algorithm should prefetch `lol`, see that it's the same ident # and not do anything else. a.get_multi = blow_up # Absolutely no prefetch on A # No actual sync actions a.delete = a.update = a.upload = b.delete = b.update = b.upload = blow_up sync(a, b, status) assert len(status) == 1 assert len(list(a.list())) == len(list(b.list())) == 1 assert status['haha'][1]['href'] == 'lol' old_status = deepcopy(status) # Further sync should be a noop. Not even prefetching should occur. b.get_multi = blow_up sync(a, b, status) assert old_status == status assert len(list(a.list())) == len(list(b.list())) == 1
def test_no_uids(): a = MemoryStorage() b = MemoryStorage() href_a, _ = a.upload(Item(u'ASDF')) href_b, _ = b.upload(Item(u'FOOBAR')) status = {} sync(a, b, status) a_items = set(a.get(href)[0].raw for href, etag in a.list()) b_items = set(b.get(href)[0].raw for href, etag in b.list()) assert a_items == b_items == {u'ASDF', u'FOOBAR'}
def test_updated_and_deleted(): a = MemoryStorage() b = MemoryStorage() href_a, etag_a = a.upload(Item(u'UID:1')) status = {} sync(a, b, status, force_delete=True) (href_b, etag_b), = b.list() b.delete(href_b, etag_b) a.update(href_a, Item(u'UID:1\nupdated'), etag_a) sync(a, b, status, force_delete=True) assert len(list(a.list())) == len(list(b.list())) == 1
def test_updated_and_deleted(): a = MemoryStorage() b = MemoryStorage() href_a, etag_a = a.upload(Item(u"UID:1")) status = {} sync(a, b, status, force_delete=True) (href_b, etag_b), = b.list() b.delete(href_b, etag_b) a.update(href_a, Item(u"UID:1\nupdated"), etag_a) sync(a, b, status, force_delete=True) assert len(list(a.list())) == len(list(b.list())) == 1
def test_repair_uids(uid): s = MemoryStorage() s.items = { 'one': ('asdf', Item(f'BEGIN:VCARD\nFN:Hans\nUID:{uid}\nEND:VCARD')), 'two': ('asdf', Item(f'BEGIN:VCARD\nFN:Peppi\nUID:{uid}\nEND:VCARD')) } uid1, uid2 = [s.get(href)[0].uid for href, etag in s.list()] assert uid1 == uid2 repair_storage(s, repair_unsafe_uid=False) uid1, uid2 = [s.get(href)[0].uid for href, etag in s.list()] assert uid1 != uid2
def test_repair_uids(): s = MemoryStorage() s.items = { 'one': ('asdf', Item(u'BEGIN:VCARD\nFN:Hans\nUID:asdf\nEND:VCARD')), 'two': ('asdf', Item(u'BEGIN:VCARD\nFN:Peppi\nUID:asdf\nEND:VCARD')) } uid1, uid2 = [s.get(href)[0].uid for href, etag in s.list()] assert uid1 == uid2 repair_storage(s) uid1, uid2 = [s.get(href)[0].uid for href, etag in s.list()] assert uid1 != uid2
def test_repair_uids(uid): s = MemoryStorage() s.items = { "one": ("asdf", Item(f"BEGIN:VCARD\nFN:Hans\nUID:{uid}\nEND:VCARD")), "two": ("asdf", Item(f"BEGIN:VCARD\nFN:Peppi\nUID:{uid}\nEND:VCARD")), } uid1, uid2 = [s.get(href)[0].uid for href, etag in s.list()] assert uid1 == uid2 repair_storage(s, repair_unsafe_uid=False) uid1, uid2 = [s.get(href)[0].uid for href, etag in s.list()] assert uid1 != uid2
def test_read_only_and_prefetch(): a = MemoryStorage() b = MemoryStorage() b.read_only = True status = {} item1 = Item(u"UID:1\nhaha") item2 = Item(u"UID:2\nhoho") a.upload(item1) a.upload(item2) sync(a, b, status, force_delete=True) sync(a, b, status, force_delete=True) assert list(a.list()) == list(b.list()) == []
def test_read_only_and_prefetch(): a = MemoryStorage() b = MemoryStorage() b.read_only = True status = {} item1 = Item(u'UID:1\nhaha') item2 = Item(u'UID:2\nhoho') a.upload(item1) a.upload(item2) sync(a, b, status, force_delete=True) sync(a, b, status, force_delete=True) assert list(a.list()) == list(b.list()) == []
def test_bogus_etag_change(): '''Assert that sync algorithm is resilient against etag changes if content didn\'t change. In this particular case we test a scenario where both etags have been updated, but only one side actually changed its item content. ''' a = MemoryStorage() b = MemoryStorage() status = {} item = format_item('ASDASD') href_a, etag_a = a.upload(item) sync(a, b, status) assert len(status) == 1 assert items(a) == items(b) == {item.raw} new_item = format_item('ASDASD') (href_b, etag_b), = b.list() a.update(href_a, item, etag_a) b.update(href_b, new_item, etag_b) b.delete = b.update = b.upload = blow_up sync(a, b, status) assert len(status) == 1 assert items(a) == items(b) == {new_item.raw}
def test_repair_uids(): s = MemoryStorage() s.upload(Item(u'BEGIN:VCARD\nEND:VCARD')) repair_storage(s) uid, = [s.get(href)[0].uid for href, etag in s.list()] s.upload(Item(u'BEGIN:VCARD\nUID:{}\nEND:VCARD'.format(uid))) uid1, uid2 = [s.get(href)[0].uid for href, etag in s.list()] assert uid1 == uid2 repair_storage(s) uid1, uid2 = [s.get(href)[0].uid for href, etag in s.list()] assert uid1 != uid2
def test_duplicate_hrefs(): a = MemoryStorage() b = MemoryStorage() a.list = lambda: [('a', 'a')] * 3 a.items['a'] = ('a', Item('UID:a')) status = {} sync(a, b, status) with pytest.raises(AssertionError): sync(a, b, status)
def test_duplicate_hrefs(): a = MemoryStorage() b = MemoryStorage() a.list = lambda: [("a", "a")] * 3 a.items["a"] = ("a", Item("UID:a")) status = {} sync(a, b, status) with pytest.raises(AssertionError): sync(a, b, status)
def test_repair_uids(uid): s = MemoryStorage() s.items = { 'one': ( 'asdf', Item(u'BEGIN:VCARD\nFN:Hans\nUID:{}\nEND:VCARD'.format(uid)) ), 'two': ( 'asdf', Item(u'BEGIN:VCARD\nFN:Peppi\nUID:{}\nEND:VCARD'.format(uid)) ) } uid1, uid2 = [s.get(href)[0].uid for href, etag in s.list()] assert uid1 == uid2 repair_storage(s, repair_unsafe_uid=False) uid1, uid2 = [s.get(href)[0].uid for href, etag in s.list()] assert uid1 != uid2
def test_moved_href(): """ Concrete application: ppl_ stores contact aliases in filenames, which means item's hrefs get changed. Vdirsyncer doesn't synchronize this data, but also shouldn't do things like deleting and re-uploading to the server. .. _ppl: http://ppladdressbook.org/ """ a = MemoryStorage() b = MemoryStorage() status = {} href, etag = a.upload(Item(u"UID:haha")) sync(a, b, status) b.items["lol"] = b.items.pop("haha") a.delete = a.update = a.upload = blow_up sync(a, b, status) assert len(status) == 1 assert len(list(a.list())) == len(list(b.list())) == 1 assert status["haha"][1]["href"] == "haha"
def test_moved_href(): ''' Concrete application: ppl_ stores contact aliases in filenames, which means item's hrefs get changed. Vdirsyncer doesn't synchronize this data, but also shouldn't do things like deleting and re-uploading to the server. .. _ppl: http://ppladdressbook.org/ ''' a = MemoryStorage() b = MemoryStorage() status = {} href, etag = a.upload(Item(u'UID:haha')) sync(a, b, status) b.items['lol'] = b.items.pop('haha') a.delete = a.update = a.upload = blow_up sync(a, b, status) assert len(status) == 1 assert len(list(a.list())) == len(list(b.list())) == 1 assert status['haha'][2] == 'haha'
def test_repair_unsafe_uids(uid): s = MemoryStorage() item = Item('BEGIN:VCARD\nUID:{}\nEND:VCARD'.format(uid)) href, etag = s.upload(item) assert s.get(href)[0].uid == uid assert not href_safe(uid) repair_storage(s, repair_unsafe_uid=True) new_href = list(s.list())[0][0] assert href_safe(new_href) newuid = s.get(new_href)[0].uid assert href_safe(newuid)
def test_repair_unsafe_uids(uid): s = MemoryStorage() item = Item(u'BEGIN:VCARD\nUID:123\nEND:VCARD').with_uid(uid) href, etag = s.upload(item) assert s.get(href)[0].uid == uid assert not href_safe(uid) repair_storage(s, repair_unsafe_uid=True) new_href = list(s.list())[0][0] assert href_safe(new_href) newuid = s.get(new_href)[0].uid assert href_safe(newuid)
def test_repair_unsafe_uids(uid): assert not href_safe(uid) s = MemoryStorage() href, etag = s.upload(Item(u'BEGIN:VCARD\nUID:{}\nEND:VCARD'.format(uid))) assert s.get(href)[0].uid == uid repair_storage(s) new_href = list(s.list())[0][0] assert href_safe(new_href) newuid = s.get(new_href)[0].uid assert href_safe(newuid)
def test_bogus_etag_change(): '''Assert that sync algorithm is resilient against etag changes if content didn\'t change. In this particular case we test a scenario where both etags have been updated, but only one side actually changed its item content. ''' a = MemoryStorage() b = MemoryStorage() status = {} href_a, etag_a = a.upload(Item('UID:ASDASD')) sync(a, b, status) assert len(status) == len(list(a.list())) == len(list(b.list())) == 1 (href_b, etag_b), = b.list() a.update(href_a, Item('UID:ASDASD'), etag_a) b.update(href_b, Item('UID:ASDASD\nACTUALCHANGE:YES'), etag_b) b.delete = b.update = b.upload = blow_up sync(a, b, status) assert len(status) == 1 assert items(a) == items(b) == {'UID:ASDASD\nACTUALCHANGE:YES'}
def test_updated_and_deleted(): a = MemoryStorage() b = MemoryStorage() href_a, etag_a = a.upload(Item('UID:1')) status = {} sync(a, b, status, force_delete=True) (href_b, etag_b), = b.list() b.delete(href_b, etag_b) updated = Item('UID:1\nupdated') a.update(href_a, updated, etag_a) sync(a, b, status, force_delete=True) assert items(a) == items(b) == {updated.raw}
def test_repair_unsafe_uids(uid): s = MemoryStorage() item = Item(u'BEGIN:VCARD\nUID:{}\nEND:VCARD'.format(uid)) print(repr(item.raw)) href, etag = s.upload(item) assert s.get(href)[0].uid == uid assert not href_safe(uid) repair_storage(s, repair_unsafe_uid=True) new_href = list(s.list())[0][0] assert href_safe(new_href) newuid = s.get(new_href)[0].uid assert href_safe(newuid)
def test_bogus_etag_change(): '''Assert that sync algorithm is resilient against etag changes if content didn\'t change. In this particular case we test a scenario where both etags have been updated, but only one side actually changed its item content. ''' a = MemoryStorage() b = MemoryStorage() status = {} href_a, etag_a = a.upload(Item(u'UID:ASDASD')) sync(a, b, status) assert len(status) == len(list(a.list())) == len(list(b.list())) == 1 (href_b, etag_b), = b.list() a.update(href_a, Item(u'UID:ASDASD'), etag_a) b.update(href_b, Item(u'UID:ASDASD\nACTUALCHANGE:YES'), etag_b) b.delete = b.update = b.upload = blow_up sync(a, b, status) assert len(status) == 1 assert items(a) == items(b) == {u'UID:ASDASD\nACTUALCHANGE:YES'}
def test_updated_and_deleted(): a = MemoryStorage() b = MemoryStorage() href_a, etag_a = a.upload(Item(u'UID:1')) status = {} sync(a, b, status, force_delete=True) (href_b, etag_b), = b.list() b.delete(href_b, etag_b) updated = Item(u'UID:1\nupdated') a.update(href_a, updated, etag_a) sync(a, b, status, force_delete=True) assert items(a) == items(b) == {updated.raw}