fix local repo / upgrader tests

This commit is contained in:
Thomas Waldmann 2016-07-23 16:16:56 +02:00
parent d3d51e12ea
commit 1e739fd52d
4 changed files with 45 additions and 24 deletions

View File

@ -134,7 +134,7 @@ class Archiver:
pass
return self.exit_code
@with_repository(exclusive='repair', manifest=False)
@with_repository(exclusive=True, manifest=False)
def do_check(self, args, repository):
"""Check repository consistency"""
if args.repair:
@ -174,7 +174,7 @@ class Archiver:
key_new.change_passphrase() # option to change key protection passphrase, save
return EXIT_SUCCESS
@with_repository(fake='dry_run')
@with_repository(fake='dry_run', exclusive=True)
def do_create(self, args, repository, manifest=None, key=None):
"""Create new archive"""
matcher = PatternMatcher(fallback=True)
@ -595,7 +595,7 @@ class Archiver:
print(str(cache))
return self.exit_code
@with_repository()
@with_repository(exclusive=True)
def do_prune(self, args, repository, manifest, key):
"""Prune repository archives according to specified rules"""
if not any((args.hourly, args.daily,
@ -722,7 +722,7 @@ class Archiver:
print("object %s fetched." % hex_id)
return EXIT_SUCCESS
@with_repository(manifest=False)
@with_repository(manifest=False, exclusive=True)
def do_debug_put_obj(self, args, repository):
"""put file(s) contents into the repository"""
for path in args.paths:
@ -734,7 +734,7 @@ class Archiver:
repository.commit()
return EXIT_SUCCESS
@with_repository(manifest=False)
@with_repository(manifest=False, exclusive=True)
def do_debug_delete_obj(self, args, repository):
"""delete the objects with the given IDs from the repo"""
modified = False

View File

@ -236,7 +236,7 @@ class ArchiverTestCaseBase(BaseTestCase):
self.cmd('create', self.repository_location + '::' + name, src_dir)
def open_archive(self, name):
repository = Repository(self.repository_path)
repository = Repository(self.repository_path, exclusive=True)
with repository:
manifest, key = Manifest.load(repository)
archive = Archive(repository, key, manifest, name)
@ -1288,7 +1288,7 @@ class ArchiverCheckTestCase(ArchiverTestCaseBase):
def test_extra_chunks(self):
self.cmd('check', self.repository_location, exit_code=0)
with Repository(self.repository_location) as repository:
with Repository(self.repository_location, exclusive=True) as repository:
repository.put(b'01234567890123456789012345678901', b'xxxx')
repository.commit()
self.cmd('check', self.repository_location, exit_code=1)

View File

@ -12,11 +12,17 @@ from ..repository import Repository, LoggedIO, TAG_COMMIT
from . import BaseTestCase
UNSPECIFIED = object() # for default values where we can't use None
class RepositoryTestCaseBase(BaseTestCase):
key_size = 32
exclusive = True
def open(self, create=False):
return Repository(os.path.join(self.tmppath, 'repository'), create=create)
def open(self, create=False, exclusive=UNSPECIFIED):
if exclusive is UNSPECIFIED:
exclusive = self.exclusive
return Repository(os.path.join(self.tmppath, 'repository'), exclusive=exclusive, create=create)
def setUp(self):
self.tmppath = tempfile.mkdtemp()
@ -27,10 +33,10 @@ class RepositoryTestCaseBase(BaseTestCase):
self.repository.close()
shutil.rmtree(self.tmppath)
def reopen(self):
def reopen(self, exclusive=UNSPECIFIED):
if self.repository:
self.repository.close()
self.repository = self.open()
self.repository = self.open(exclusive=exclusive)
class RepositoryTestCase(RepositoryTestCaseBase):
@ -156,17 +162,6 @@ class RepositoryCommitTestCase(RepositoryTestCaseBase):
self.assert_equal(len(self.repository), 3)
self.assert_equal(self.repository.check(), True)
def test_replay_of_readonly_repository(self):
self.add_keys()
for name in os.listdir(self.repository.path):
if name.startswith('index.'):
os.unlink(os.path.join(self.repository.path, name))
with patch.object(UpgradableLock, 'upgrade', side_effect=LockFailed) as upgrade:
self.reopen()
with self.repository:
self.assert_raises(LockFailed, lambda: len(self.repository))
upgrade.assert_called_once_with()
def test_crash_before_write_index(self):
self.add_keys()
self.repository.write_index = None
@ -179,6 +174,32 @@ class RepositoryCommitTestCase(RepositoryTestCaseBase):
self.assert_equal(len(self.repository), 3)
self.assert_equal(self.repository.check(), True)
def test_replay_lock_upgrade_old(self):
self.add_keys()
for name in os.listdir(self.repository.path):
if name.startswith('index.'):
os.unlink(os.path.join(self.repository.path, name))
with patch.object(Lock, 'upgrade', side_effect=LockFailed) as upgrade:
self.reopen(exclusive=None) # simulate old client that always does lock upgrades
with self.repository:
# the repo is only locked by a shared read lock, but to replay segments,
# we need an exclusive write lock - check if the lock gets upgraded.
self.assert_raises(LockFailed, lambda: len(self.repository))
upgrade.assert_called_once_with()
def test_replay_lock_upgrade(self):
self.add_keys()
for name in os.listdir(self.repository.path):
if name.startswith('index.'):
os.unlink(os.path.join(self.repository.path, name))
with patch.object(Lock, 'upgrade', side_effect=LockFailed) as upgrade:
self.reopen(exclusive=False) # current client usually does not do lock upgrade, except for replay
with self.repository:
# the repo is only locked by a shared read lock, but to replay segments,
# we need an exclusive write lock - check if the lock gets upgraded.
self.assert_raises(LockFailed, lambda: len(self.repository))
upgrade.assert_called_once_with()
def test_crash_before_deleting_compacted_segments(self):
self.add_keys()
self.repository.io.delete_segment = None
@ -202,7 +223,7 @@ class RepositoryCommitTestCase(RepositoryTestCaseBase):
class RepositoryAppendOnlyTestCase(RepositoryTestCaseBase):
def open(self, create=False):
return Repository(os.path.join(self.tmppath, 'repository'), create=create, append_only=True)
return Repository(os.path.join(self.tmppath, 'repository'), exclusive=True, create=create, append_only=True)
def test_destroy_append_only(self):
# Can't destroy append only repo (via the API)

View File

@ -23,7 +23,7 @@ def repo_valid(path):
:param path: the path to the repository
:returns: if borg can check the repository
"""
with Repository(str(path), create=False) as repository:
with Repository(str(path), exclusive=True, create=False) as repository:
# can't check raises() because check() handles the error
return repository.check()