mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-04-27 14:57:41 +00:00
Tests for metasync
This commit is contained in:
parent
b44db992e7
commit
d35cb1bc50
5 changed files with 84 additions and 4 deletions
|
|
@ -236,6 +236,8 @@ class StorageTests(object):
|
||||||
|
|
||||||
def test_metadata(self, requires_metadata, s):
|
def test_metadata(self, requires_metadata, s):
|
||||||
try:
|
try:
|
||||||
|
s.set_meta('color', None)
|
||||||
|
assert s.get_meta('color') is None
|
||||||
s.set_meta('color', u'#ff0000')
|
s.set_meta('color', u'#ff0000')
|
||||||
assert s.get_meta('color') == u'#ff0000'
|
assert s.get_meta('color') == u'#ff0000'
|
||||||
except exceptions.UnsupportedMetadataError:
|
except exceptions.UnsupportedMetadataError:
|
||||||
|
|
|
||||||
77
tests/test_metasync.py
Normal file
77
tests/test_metasync.py
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
import vdirsyncer.exceptions as exceptions
|
||||||
|
from vdirsyncer.storage.base import Item
|
||||||
|
from vdirsyncer.storage.memory import MemoryStorage
|
||||||
|
from vdirsyncer.metasync import metasync, MetaSyncConflict
|
||||||
|
|
||||||
|
from . import assert_item_equals, blow_up, normalize_item
|
||||||
|
|
||||||
|
def test_irrelevant_status():
|
||||||
|
a = MemoryStorage()
|
||||||
|
b = MemoryStorage()
|
||||||
|
status = {'foo': 'bar'}
|
||||||
|
|
||||||
|
metasync(a, b, status, keys=())
|
||||||
|
assert not status
|
||||||
|
|
||||||
|
def test_basic():
|
||||||
|
a = MemoryStorage()
|
||||||
|
b = MemoryStorage()
|
||||||
|
status = {}
|
||||||
|
|
||||||
|
a.set_meta('foo', 'bar')
|
||||||
|
metasync(a, b, status, keys=['foo'])
|
||||||
|
assert a.get_meta('foo') == b.get_meta('foo') == 'bar'
|
||||||
|
|
||||||
|
a.set_meta('foo', 'baz')
|
||||||
|
metasync(a, b, status, keys=['foo'])
|
||||||
|
assert a.get_meta('foo') == b.get_meta('foo') == 'baz'
|
||||||
|
|
||||||
|
b.set_meta('foo', None)
|
||||||
|
metasync(a, b, status, keys=['foo'])
|
||||||
|
assert a.get_meta('foo') is b.get_meta('foo') is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_conflict():
|
||||||
|
a = MemoryStorage()
|
||||||
|
b = MemoryStorage()
|
||||||
|
status = {}
|
||||||
|
a.set_meta('foo', 'bar')
|
||||||
|
b.set_meta('foo', 'baz')
|
||||||
|
|
||||||
|
with pytest.raises(MetaSyncConflict):
|
||||||
|
metasync(a, b, status, keys=['foo'])
|
||||||
|
|
||||||
|
assert a.get_meta('foo') == 'bar'
|
||||||
|
assert b.get_meta('foo') == 'baz'
|
||||||
|
assert not status
|
||||||
|
|
||||||
|
|
||||||
|
def test_conflict_same_content():
|
||||||
|
a = MemoryStorage()
|
||||||
|
b = MemoryStorage()
|
||||||
|
status = {}
|
||||||
|
a.set_meta('foo', 'bar')
|
||||||
|
b.set_meta('foo', 'bar')
|
||||||
|
|
||||||
|
metasync(a, b, status, keys=['foo'])
|
||||||
|
assert a.get_meta('foo') == b.get_meta('foo') == status['foo'] == 'bar'
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('wins', 'ab')
|
||||||
|
def test_conflict_x_wins(wins):
|
||||||
|
a = MemoryStorage()
|
||||||
|
b = MemoryStorage()
|
||||||
|
status = {}
|
||||||
|
a.set_meta('foo', 'bar')
|
||||||
|
b.set_meta('foo', 'baz')
|
||||||
|
|
||||||
|
metasync(a, b, status, keys=['foo'],
|
||||||
|
conflict_resolution='a wins' if wins == 'a' else 'b wins')
|
||||||
|
|
||||||
|
assert a.get_meta('foo') == b.get_meta('foo') == status['foo'] == (
|
||||||
|
'bar' if wins == 'a' else 'baz'
|
||||||
|
)
|
||||||
|
|
@ -11,7 +11,7 @@ class MetaSyncConflict(MetaSyncError):
|
||||||
key = None
|
key = None
|
||||||
|
|
||||||
|
|
||||||
def metasync(storage_a, storage_b, status, keys, conflict_resolution):
|
def metasync(storage_a, storage_b, status, keys, conflict_resolution=None):
|
||||||
def _a_to_b():
|
def _a_to_b():
|
||||||
logger.info(u'Copying {} to {}'.format(key, storage_b))
|
logger.info(u'Copying {} to {}'.format(key, storage_b))
|
||||||
storage_b.set_meta(key, a)
|
storage_b.set_meta(key, a)
|
||||||
|
|
@ -24,7 +24,7 @@ def metasync(storage_a, storage_b, status, keys, conflict_resolution):
|
||||||
|
|
||||||
def _resolve_conflict():
|
def _resolve_conflict():
|
||||||
if a == b:
|
if a == b:
|
||||||
pass
|
status[key] = a
|
||||||
elif conflict_resolution is None:
|
elif conflict_resolution is None:
|
||||||
raise MetaSyncConflict(key=key)
|
raise MetaSyncConflict(key=key)
|
||||||
elif conflict_resolution == 'a wins':
|
elif conflict_resolution == 'a wins':
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,7 @@ class FilesystemStorage(Storage):
|
||||||
fpath = os.path.join(self.path, key)
|
fpath = os.path.join(self.path, key)
|
||||||
try:
|
try:
|
||||||
with open(fpath, 'rb') as f:
|
with open(fpath, 'rb') as f:
|
||||||
return f.read().decode(self.encoding)
|
return f.read().decode(self.encoding) or None
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
if e.errno == errno.ENOENT:
|
if e.errno == errno.ENOENT:
|
||||||
return None
|
return None
|
||||||
|
|
@ -193,6 +193,7 @@ class FilesystemStorage(Storage):
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def set_meta(self, key, value):
|
def set_meta(self, key, value):
|
||||||
|
value = value or u''
|
||||||
assert isinstance(value, text_type)
|
assert isinstance(value, text_type)
|
||||||
fpath = os.path.join(self.path, key)
|
fpath = os.path.join(self.path, key)
|
||||||
with atomic_write(fpath, mode='wb', overwrite=True) as f:
|
with atomic_write(fpath, mode='wb', overwrite=True) as f:
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ class MemoryStorage(Storage):
|
||||||
del self.items[href]
|
del self.items[href]
|
||||||
|
|
||||||
def get_meta(self, key):
|
def get_meta(self, key):
|
||||||
return self.metadata[key]
|
return self.metadata.get(key)
|
||||||
|
|
||||||
def set_meta(self, key, value):
|
def set_meta(self, key, value):
|
||||||
self.metadata[key] = value
|
self.metadata[key] = value
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue