1
0
Fork 0
mirror of https://github.com/borgbackup/borg.git synced 2025-03-03 02:05:54 +00:00

Bring function tests back to life

This commit is contained in:
Jonas Borgström 2011-08-06 13:01:58 +02:00
parent 59e33ab29f
commit 1d0914177d
8 changed files with 52 additions and 35 deletions

View file

@ -54,6 +54,8 @@ def iter_items(self, callback):
unpacker = msgpack.Unpacker()
counter = Counter(0)
def cb(chunk, error, id):
if error:
raise error
assert not error
counter.dec()
data, items_hash = self.key.decrypt(chunk)
@ -220,9 +222,10 @@ def restore_attrs(self, path, item, symlink=False):
def verify_file(self, item, start, result):
def verify_chunk(chunk, error, (id, i, last)):
if error:
raise error
if i == 0:
start(item)
assert not error
data, hash = self.key.decrypt(chunk)
if self.key.id_hash(data) != id:
result(item, False)

View file

@ -10,7 +10,8 @@
from .cache import Cache
from .key import Key
from .helpers import location_validator, format_file_size, format_time,\
format_file_mode, IncludePattern, ExcludePattern, exclude_path, to_localtime
format_file_mode, IncludePattern, ExcludePattern, exclude_path, to_localtime, \
get_cache_dir
from .remote import StoreServer, RemoteStore
class Archiver(object):
@ -46,7 +47,9 @@ def do_serve(self, args):
def do_init(self, args):
store = self.open_store(args.store, create=True)
key = Key.create(store, args.store.to_key_filename())
key = Key.create(store, args.store.to_key_filename(),
password=args.password)
return self.exit_code
def do_create(self, args):
store = self.open_store(args.archive)
@ -63,7 +66,7 @@ def do_create(self, args):
# Add darc cache dir to inode_skip list
skip_inodes = set()
try:
st = os.stat(Cache.cache_dir_path())
st = os.stat(get_cache_dir())
skip_inodes.add((st.st_ino, st.st_dev))
except IOError:
pass
@ -232,7 +235,9 @@ def run(self, args=None):
subparser = subparsers.add_parser('init')
subparser.set_defaults(func=self.do_init)
subparser.add_argument('store', metavar='ARCHIVE',
subparser.add_argument('-p', '--password', dest='password',
help='Protect store key with password (Default: prompt)')
subparser.add_argument('store',
type=location_validator(archive=False),
help='Store to create')

View file

@ -6,7 +6,7 @@
import shutil
from . import NS_CHUNK, NS_ARCHIVE_METADATA
from .helpers import error_callback
from .helpers import error_callback, get_cache_dir
from .hashindex import ChunkIndex
@ -18,7 +18,7 @@ def __init__(self, store, key):
self.txn_active = False
self.store = store
self.key = key
self.path = os.path.join(Cache.cache_dir_path(), self.store.id.encode('hex'))
self.path = os.path.join(get_cache_dir(), self.store.id.encode('hex'))
if not os.path.exists(self.path):
self.create()
self.open()
@ -27,11 +27,6 @@ def __init__(self, store, key):
self.sync()
self.commit()
@staticmethod
def cache_dir_path():
"""Return path to directory used for storing users cache files"""
return os.path.join(os.path.expanduser('~'), '.darc', 'cache')
def create(self):
"""Create a new empty store at `path`
"""

View file

@ -30,15 +30,28 @@ def __repr__(self):
return '<Counter(%r)>' % self.v
def get_keys_dir():
"""Determine where to store keys and cache"""
return os.environ.get('DARC_KEYS_DIR',
os.path.join(os.path.expanduser('~'), '.darc', 'keys'))
def get_cache_dir():
"""Determine where to store keys and cache"""
return os.environ.get('DARC_CACHE_DIR',
os.path.join(os.path.expanduser('~'), '.darc', 'cache'))
def deferrable(f):
def wrapper(*args, **kw):
callback = kw.pop('callback', None)
if callback:
data = kw.pop('callback_data', None)
try:
callback(f(*args, **kw), None, data)
res = f(*args, **kw)
except Exception, e:
callback(None, e, data)
else:
callback(res, None, data)
else:
return f(*args, **kw)
return wrapper
@ -288,7 +301,7 @@ def to_key_filename(self):
name = re.sub('[^\w]', '_', self.path).strip('_')
if self.proto != 'file':
name = self.host + '__' + name
return os.path.join(os.path.expanduser('~'), '.darc', 'keys', name)
return os.path.join(get_keys_dir(), name)
def __repr__(self):
return "Location(%s)" % self

View file

@ -12,7 +12,7 @@
from Crypto.Util.number import bytes_to_long, long_to_bytes
from Crypto.Random import get_random_bytes
from .helpers import IntegrityError
from .helpers import IntegrityError, get_keys_dir
class Key(object):
@ -24,7 +24,7 @@ def __init__(self, store=None):
def find_key_file(self, store):
id = store.id.encode('hex')
keys_dir = os.path.join(os.path.expanduser('~'), '.darc', 'keys')
keys_dir = get_keys_dir()
for name in os.listdir(keys_dir):
filename = os.path.join(keys_dir, name)
with open(filename, 'rb') as fd:
@ -112,13 +112,16 @@ def chpass(self):
return 0
@staticmethod
def create(store, filename):
def create(store, filename, password=None):
i = 1
path = filename
while os.path.exists(path):
i += 1
path = filename + '.%d' % i
password, password2 = 1, 2
if password is not None:
password2 = password
else:
password, password2 = 1, 2
while password != password2:
password = getpass('Keychain password: ')
password2 = getpass('Keychain password again: ')

View file

@ -171,7 +171,6 @@ def get(self, ns, id, callback=None, callback_data=None):
try:
return self.cmd('get', (ns, id), callback, callback_data)
except self.RPCError, e:
print e.name
if e.name == 'DoesNotExist':
raise self.DoesNotExist
raise

View file

@ -270,9 +270,8 @@ def read(self, band, offset, ns, id):
fd.seek(offset)
data = fd.read(self.header_fmt.size)
size, magic, hash, ns_, id_ = self.header_fmt.unpack(data)
assert magic == 0
assert ns == ns_
assert id == id_
if magic != 0 or ns != ns_ or id != id_:
raise IntegrityError('Invalid band entry header')
data = fd.read(size - self.header_fmt.size)
if crc32(data) & 0xffffffff != hash:
raise IntegrityError('Band checksum mismatch')
@ -281,12 +280,14 @@ def read(self, band, offset, ns, id):
def iter_objects(self, band, lookup):
fd = self.get_fd(band)
fd.seek(0)
assert fd.read(8) == 'DARCBAND'
if fd.read(8) != 'DARCBAND':
raise IntegrityError('Invalid band header')
offset = 8
data = fd.read(self.header_fmt.size)
while data:
size, magic, hash, ns, key = self.header_fmt.unpack(data)
assert magic == 0
if magic != 0:
raise IntegrityError('Unknown band entry header')
offset += size
if lookup(ns, key):
data = fd.read(size - self.header_fmt.size)

View file

@ -24,19 +24,22 @@ def setUp(self):
self.store_path = os.path.join(self.tmpdir, 'store')
self.input_path = os.path.join(self.tmpdir, 'input')
self.output_path = os.path.join(self.tmpdir, 'output')
self.keys_path = os.path.join(self.tmpdir, 'keys')
self.cache_path = os.path.join(self.tmpdir, 'cache')
os.environ['DARC_KEYS_DIR'] = self.keys_path
os.environ['DARC_CACHE_DIR'] = self.cache_path
os.mkdir(self.input_path)
os.mkdir(self.output_path)
os.mkdir(self.keys_path)
os.mkdir(self.cache_path)
os.chdir(self.tmpdir)
self.keychain = '/tmp/_test_dedupstore.keychain'
if not os.path.exists(self.keychain):
self.darc('init-keychain')
def tearDown(self):
shutil.rmtree(self.tmpdir)
def darc(self, *args, **kwargs):
exit_code = kwargs.get('exit_code', 0)
args = ['--keychain', self.keychain] + list(args)
args = list(args)
try:
stdout, stderr = sys.stdout, sys.stderr
output = StringIO()
@ -52,6 +55,7 @@ def darc(self, *args, **kwargs):
def create_src_archive(self, name):
src_dir = os.path.join(os.getcwd(), os.path.dirname(__file__))
self.darc('init', '--password', '', self.store_path)
self.darc('create', self.store_path + '::' + name, src_dir)
def create_regual_file(self, name, size=0):
@ -96,6 +100,7 @@ def test_basic_functionality(self):
os.path.join(self.input_path, 'hardlink'))
os.symlink('somewhere', os.path.join(self.input_path, 'link1'))
os.mkfifo(os.path.join(self.input_path, 'fifo1'))
self.darc('init', '-p', '', self.store_path)
self.darc('create', self.store_path + '::test', 'input')
self.darc('create', self.store_path + '::test.2', 'input')
self.darc('extract', self.store_path + '::test', 'output')
@ -110,13 +115,6 @@ def test_corrupted_store(self):
fd.close()
self.darc('verify', self.store_path + '::test', exit_code=1)
def test_keychain(self):
keychain = os.path.join(self.tmpdir, 'keychain')
keychain2 = os.path.join(self.tmpdir, 'keychain2')
self.darc('-k', keychain, 'init-keychain')
self.darc('-k', keychain, 'change-password')
self.darc('-k', keychain, 'export-restricted', keychain2)
def suite():
suite = unittest.TestSuite()