[PATCH 17/23] Replace LocalRepo/RemoteRepo __del__ with context management

0 views
Skip to first unread message

Rob Browning

unread,
Nov 13, 2021, 12:59:43 PM11/13/21
to bup-...@googlegroups.com, Bas Stottelaar
Signed-off-by: Rob Browning <r...@defaultvalue.org>
Tested-by: Rob Browning <r...@defaultvalue.org>
---
lib/bup/cmd/cat_file.py | 52 ++++-----
lib/bup/cmd/ftp.py | 78 ++++++-------
lib/bup/cmd/fuse.py | 28 ++---
lib/bup/cmd/join.py | 32 +++---
lib/bup/cmd/prune_older.py | 5 +-
lib/bup/cmd/restore.py | 100 ++++++++---------
lib/bup/cmd/rm.py | 6 +-
lib/bup/cmd/server.py | 5 +-
lib/bup/cmd/web.py | 46 ++++----
lib/bup/ls.py | 5 +-
lib/bup/repo.py | 7 +-
test/int/test_metadata.py | 42 +++----
test/int/test_vfs.py | 220 ++++++++++++++++++-------------------
13 files changed, 312 insertions(+), 314 deletions(-)

diff --git a/lib/bup/cmd/cat_file.py b/lib/bup/cmd/cat_file.py
index 302d8e3d..e878e7ea 100755
--- a/lib/bup/cmd/cat_file.py
+++ b/lib/bup/cmd/cat_file.py
@@ -34,36 +34,36 @@ def main(argv):
if not re.match(br'/*[^/]+/[^/]+', target):
o.fatal("path %r doesn't include a branch and revision" % target)

- repo = LocalRepo()
- resolved = vfs.resolve(repo, target, follow=False)
- leaf_name, leaf_item = resolved[-1]
- if not leaf_item:
- log('error: cannot access %r in %r\n'
- % (b'/'.join(name for name, item in resolved), target))
- sys.exit(1)
+ with LocalRepo() as repo:
+ resolved = vfs.resolve(repo, target, follow=False)
+ leaf_name, leaf_item = resolved[-1]
+ if not leaf_item:
+ log('error: cannot access %r in %r\n'
+ % (b'/'.join(name for name, item in resolved), target))
+ sys.exit(1)

- mode = vfs.item_mode(leaf_item)
+ mode = vfs.item_mode(leaf_item)

- sys.stdout.flush()
- out = byte_stream(sys.stdout)
+ sys.stdout.flush()
+ out = byte_stream(sys.stdout)

- if opt.bupm:
- if not stat.S_ISDIR(mode):
- o.fatal('%r is not a directory' % target)
- _, bupm_oid = vfs.tree_data_and_bupm(repo, leaf_item.oid)
- if bupm_oid:
- with vfs.tree_data_reader(repo, bupm_oid) as meta_stream:
- out.write(meta_stream.read())
- elif opt.meta:
- augmented = vfs.augment_item_meta(repo, leaf_item, include_size=True)
- out.write(augmented.meta.encode())
- else:
- if stat.S_ISREG(mode):
- with vfs.fopen(repo, leaf_item) as f:
- for b in chunkyreader(f):
- out.write(b)
+ if opt.bupm:
+ if not stat.S_ISDIR(mode):
+ o.fatal('%r is not a directory' % target)
+ _, bupm_oid = vfs.tree_data_and_bupm(repo, leaf_item.oid)
+ if bupm_oid:
+ with vfs.tree_data_reader(repo, bupm_oid) as meta_stream:
+ out.write(meta_stream.read())
+ elif opt.meta:
+ augmented = vfs.augment_item_meta(repo, leaf_item, include_size=True)
+ out.write(augmented.meta.encode())
else:
- o.fatal('%r is not a plain file' % target)
+ if stat.S_ISREG(mode):
+ with vfs.fopen(repo, leaf_item) as f:
+ for b in chunkyreader(f):
+ out.write(b)
+ else:
+ o.fatal('%r is not a plain file' % target)

if saved_errors:
log('warning: %d errors encountered\n' % len(saved_errors))
diff --git a/lib/bup/cmd/ftp.py b/lib/bup/cmd/ftp.py
index 86392301..9a33754c 100755
--- a/lib/bup/cmd/ftp.py
+++ b/lib/bup/cmd/ftp.py
@@ -9,7 +9,7 @@ import os, fnmatch, stat, sys, traceback

from bup import _helpers, options, git, shquote, ls, vfs
from bup.compat import argv_bytes
-from bup.helpers import chunkyreader, log
+from bup.helpers import chunkyreader, log, saved_errors
from bup.io import byte_stream, path_msg
from bup.repo import LocalRepo

@@ -94,43 +94,32 @@ optspec = """
bup ftp [commands...]
"""

-def main(argv):
- o = options.Options(optspec)
- opt, flags, extra = o.parse_bytes(argv[1:])

- git.check_repo_or_die()
+def inputiter(f, pwd, out):
+ if os.isatty(f.fileno()):
+ while 1:
+ prompt = b'bup %s> ' % (b'/'.join(name for name, item in pwd) or b'/', )
+ if hasattr(_helpers, 'readline'):
+ try:
+ yield _helpers.readline(prompt)
+ except EOFError:
+ print() # Clear the line for the terminal's next prompt
+ break
+ else:
+ out.write(prompt)
+ out.flush()
+ read_line = f.readline()
+ if not read_line:
+ print('')
+ break
+ yield read_line
+ else:
+ for line in f:
+ yield line

- global repo

- sys.stdout.flush()
- out = byte_stream(sys.stdout)
- stdin = byte_stream(sys.stdin)
- repo = LocalRepo()
+def present_interface(stdin, out, extra, repo):
pwd = vfs.resolve(repo, b'/')
- rv = 0
-
- def inputiter(f):
- if os.isatty(f.fileno()):
- while 1:
- prompt = b'bup %s> ' % (b'/'.join(name for name, item in pwd) or b'/', )
- if hasattr(_helpers, 'readline'):
- try:
- yield _helpers.readline(prompt)
- except EOFError:
- print() # Clear the line for the terminal's next prompt
- break
- else:
- out.write(prompt)
- out.flush()
- read_line = f.readline()
- if not read_line:
- print('')
- break
- yield read_line
- else:
- for line in f:
- yield line
-

if extra:
lines = (argv_bytes(arg) for arg in extra)
@@ -143,7 +132,7 @@ def main(argv):
# MacOS uses a slightly incompatible clone of libreadline
_helpers.parse_and_bind(b'bind ^I rl_complete')
_helpers.parse_and_bind(b'tab: complete')
- lines = inputiter(stdin)
+ lines = inputiter(stdin, pwd, out)

for line in lines:
if not line.strip():
@@ -186,7 +175,6 @@ def main(argv):
out.flush()
elif cmd == b'get':
if len(words) not in [2,3]:
- rv = 1
raise Exception('Usage: get <filename> [localname]')
rname = words[1]
(dir,base) = os.path.split(rname)
@@ -230,11 +218,23 @@ def main(argv):
elif cmd in (b'quit', b'exit', b'bye'):
break
else:
- rv = 1
raise Exception('no such command %r' % cmd)
except Exception as e:
- rv = 1
log('error: %s\n' % e)
raise

- sys.exit(rv)
+def main(argv):
+ global repo
+
+ o = options.Options(optspec)
+ opt, flags, extra = o.parse_bytes(argv[1:])
+
+ git.check_repo_or_die()
+ sys.stdout.flush()
+ out = byte_stream(sys.stdout)
+ stdin = byte_stream(sys.stdin)
+ with LocalRepo() as repo:
+ present_interface(stdin, out, extra, repo)
+ if saved_errors:
+ log('warning: %d errors encountered\n' % len(saved_errors))
+ sys.exit(1)
diff --git a/lib/bup/cmd/fuse.py b/lib/bup/cmd/fuse.py
index 385bea9f..27937123 100755
--- a/lib/bup/cmd/fuse.py
+++ b/lib/bup/cmd/fuse.py
@@ -147,17 +147,17 @@ def main(argv):
o.fatal('only one mount point argument expected')

git.check_repo_or_die()
- repo = LocalRepo()
- f = BupFs(repo=repo, verbose=opt.verbose, fake_metadata=(not opt.meta))
-
- # This is likely wrong, but the fuse module doesn't currently accept bytes
- f.fuse_args.mountpoint = extra[0]
-
- if opt.debug:
- f.fuse_args.add('debug')
- if opt.foreground:
- f.fuse_args.setmod('foreground')
- f.multithreaded = False
- if opt.allow_other:
- f.fuse_args.add('allow_other')
- f.main()
+ with LocalRepo() as repo:
+ f = BupFs(repo=repo, verbose=opt.verbose, fake_metadata=(not opt.meta))
+
+ # This is likely wrong, but the fuse module doesn't currently accept bytes
+ f.fuse_args.mountpoint = extra[0]
+
+ if opt.debug:
+ f.fuse_args.add('debug')
+ if opt.foreground:
+ f.fuse_args.setmod('foreground')
+ f.multithreaded = False
+ if opt.allow_other:
+ f.fuse_args.add('allow_other')
+ f.main()
diff --git a/lib/bup/cmd/join.py b/lib/bup/cmd/join.py
index caf524a6..bb66585a 100755
--- a/lib/bup/cmd/join.py
+++ b/lib/bup/cmd/join.py
@@ -31,21 +31,21 @@ def main(argv):
extra = linereader(stdin)

ret = 0
- repo = RemoteRepo(opt.remote) if opt.remote else LocalRepo()
-
- if opt.o:
- outfile = open(opt.o, 'wb')
- else:
- sys.stdout.flush()
- outfile = byte_stream(sys.stdout)
-
- for ref in [argv_bytes(x) for x in extra]:
- try:
- for blob in repo.join(ref):
- outfile.write(blob)
- except KeyError as e:
- outfile.flush()
- log('error: %s\n' % e)
- ret = 1
+ with RemoteRepo(opt.remote) if opt.remote else LocalRepo() as repo:
+
+ if opt.o:
+ outfile = open(opt.o, 'wb')
+ else:
+ sys.stdout.flush()
+ outfile = byte_stream(sys.stdout)
+
+ for ref in [argv_bytes(x) for x in extra]:
+ try:
+ for blob in repo.join(ref):
+ outfile.write(blob)
+ except KeyError as e:
+ outfile.flush()
+ log('error: %s\n' % e)
+ ret = 1

sys.exit(ret)
diff --git a/lib/bup/cmd/prune_older.py b/lib/bup/cmd/prune_older.py
index e0f8545f..d5a8f1cf 100755
--- a/lib/bup/cmd/prune_older.py
+++ b/lib/bup/cmd/prune_older.py
@@ -153,8 +153,9 @@ def main(argv):

if not opt.pretend:
die_if_errors()
- repo = LocalRepo()
- bup_rm(repo, removals, compression=opt.compress, verbosity=opt.verbose)
+ with LocalRepo() as repo:
+ bup_rm(repo, removals, compression=opt.compress,
+ verbosity=opt.verbose)
if opt.gc:
die_if_errors()
bup_gc(threshold=opt.gc_threshold,
diff --git a/lib/bup/cmd/restore.py b/lib/bup/cmd/restore.py
index ee403b6c..0dcee264 100755
--- a/lib/bup/cmd/restore.py
+++ b/lib/bup/cmd/restore.py
@@ -242,61 +242,61 @@ def main(argv):
mkdirp(opt.outdir)
os.chdir(opt.outdir)

- repo = RemoteRepo(opt.remote) if opt.remote else LocalRepo()
- top = fsencode(os.getcwd())
- hardlinks = {}
- for path in [argv_bytes(x) for x in extra]:
- if not valid_restore_path(path):
- add_error("path %r doesn't include a branch and revision" % path)
- continue
- try:
- resolved = vfs.resolve(repo, path, want_meta=True, follow=False)
- except vfs.IOError as e:
- add_error(e)
- continue
- if len(resolved) == 3 and resolved[2][0] == b'latest':
- # Follow latest symlink to the actual save
+ with RemoteRepo(opt.remote) if opt.remote else LocalRepo() as repo:
+ top = fsencode(os.getcwd())
+ hardlinks = {}
+ for path in [argv_bytes(x) for x in extra]:
+ if not valid_restore_path(path):
+ add_error("path %r doesn't include a branch and revision" % path)
+ continue
try:
- resolved = vfs.resolve(repo, b'latest', parent=resolved[:-1],
- want_meta=True)
+ resolved = vfs.resolve(repo, path, want_meta=True, follow=False)
except vfs.IOError as e:
add_error(e)
continue
- # Rename it back to 'latest'
- resolved = tuple(elt if i != 2 else (b'latest',) + elt[1:]
- for i, elt in enumerate(resolved))
- path_parent, path_name = os.path.split(path)
- leaf_name, leaf_item = resolved[-1]
- if not leaf_item:
- add_error('error: cannot access %r in %r'
- % (b'/'.join(name for name, item in resolved),
- path))
- continue
- if not path_name or path_name == b'.':
- # Source is /foo/what/ever/ or /foo/what/ever/. -- extract
- # what/ever/* to the current directory, and if name == '.'
- # (i.e. /foo/what/ever/.), then also restore what/ever's
- # metadata to the current directory.
- treeish = vfs.item_mode(leaf_item)
- if not treeish:
- add_error('%r cannot be restored as a directory' % path)
+ if len(resolved) == 3 and resolved[2][0] == b'latest':
+ # Follow latest symlink to the actual save
+ try:
+ resolved = vfs.resolve(repo, b'latest', parent=resolved[:-1],
+ want_meta=True)
+ except vfs.IOError as e:
+ add_error(e)
+ continue
+ # Rename it back to 'latest'
+ resolved = tuple(elt if i != 2 else (b'latest',) + elt[1:]
+ for i, elt in enumerate(resolved))
+ path_parent, path_name = os.path.split(path)
+ leaf_name, leaf_item = resolved[-1]
+ if not leaf_item:
+ add_error('error: cannot access %r in %r'
+ % (b'/'.join(name for name, item in resolved),
+ path))
+ continue
+ if not path_name or path_name == b'.':
+ # Source is /foo/what/ever/ or /foo/what/ever/. -- extract
+ # what/ever/* to the current directory, and if name == '.'
+ # (i.e. /foo/what/ever/.), then also restore what/ever's
+ # metadata to the current directory.
+ treeish = vfs.item_mode(leaf_item)
+ if not treeish:
+ add_error('%r cannot be restored as a directory' % path)
+ else:
+ items = vfs.contents(repo, leaf_item, want_meta=True)
+ dot, leaf_item = next(items, None)
+ assert dot == b'.'
+ for sub_name, sub_item in items:
+ restore(repo, b'', sub_name, sub_item, top,
+ opt.sparse, opt.numeric_ids, owner_map,
+ exclude_rxs, verbosity, hardlinks)
+ if path_name == b'.':
+ leaf_item = vfs.augment_item_meta(repo, leaf_item,
+ include_size=True)
+ apply_metadata(leaf_item.meta, b'.',
+ opt.numeric_ids, owner_map)
else:
- items = vfs.contents(repo, leaf_item, want_meta=True)
- dot, leaf_item = next(items, None)
- assert dot == b'.'
- for sub_name, sub_item in items:
- restore(repo, b'', sub_name, sub_item, top,
- opt.sparse, opt.numeric_ids, owner_map,
- exclude_rxs, verbosity, hardlinks)
- if path_name == b'.':
- leaf_item = vfs.augment_item_meta(repo, leaf_item,
- include_size=True)
- apply_metadata(leaf_item.meta, b'.',
- opt.numeric_ids, owner_map)
- else:
- restore(repo, b'', leaf_name, leaf_item, top,
- opt.sparse, opt.numeric_ids, owner_map,
- exclude_rxs, verbosity, hardlinks)
+ restore(repo, b'', leaf_name, leaf_item, top,
+ opt.sparse, opt.numeric_ids, owner_map,
+ exclude_rxs, verbosity, hardlinks)

if verbosity >= 0:
progress('Restoring: %d, done.\n' % total_restored)
diff --git a/lib/bup/cmd/rm.py b/lib/bup/cmd/rm.py
index 2867657f..4c4a0f03 100755
--- a/lib/bup/cmd/rm.py
+++ b/lib/bup/cmd/rm.py
@@ -27,7 +27,7 @@ def main(argv):
o.fatal('no paths specified')

check_repo_or_die()
- repo = LocalRepo()
- bup_rm(repo, [argv_bytes(x) for x in extra],
- compression=opt.compress, verbosity=opt.verbose)
+ with LocalRepo() as repo:
+ bup_rm(repo, [argv_bytes(x) for x in extra],
+ compression=opt.compress, verbosity=opt.verbose)
die_if_errors()
diff --git a/lib/bup/cmd/server.py b/lib/bup/cmd/server.py
index 56b6d445..5e2b6af6 100755
--- a/lib/bup/cmd/server.py
+++ b/lib/bup/cmd/server.py
@@ -289,7 +289,7 @@ commands = {
}

def main(argv):
- global suspended_w
+ global repo, suspended_w

o = options.Options(optspec)
opt, flags, extra = o.parse_bytes(argv[1:])
@@ -303,7 +303,8 @@ def main(argv):
sys.stdout.flush()
conn = Conn(byte_stream(sys.stdin), byte_stream(sys.stdout))
lr = linereader(conn)
- with finalized(None, lambda _: suspended_w and suspended_w.close()):
+ with finalized(None, lambda _: repo and repo.close()), \
+ finalized(None, lambda _: suspended_w and suspended_w.close()):
for _line in lr:
line = _line.strip()
if not line:
diff --git a/lib/bup/cmd/web.py b/lib/bup/cmd/web.py
index 20333cbb..c609d872 100755
--- a/lib/bup/cmd/web.py
+++ b/lib/bup/cmd/web.py
@@ -290,30 +290,30 @@ def main(argv):
except AttributeError:
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

- application = tornado.web.Application([
- (r"(?P<path>/.*)", BupRequestHandler, dict(repo=LocalRepo())),
- ], **settings)
-
- http_server = HTTPServer(application)
- io_loop_pending = IOLoop.instance()
-
- if isinstance(address, InetAddress):
- sockets = tornado.netutil.bind_sockets(address.port, address.host)
- http_server.add_sockets(sockets)
- print('Serving HTTP on %s:%d...' % sockets[0].getsockname()[0:2])
- if opt.browser:
- browser_addr = 'http://' + address[0] + ':' + str(address[1])
- io_loop_pending.add_callback(lambda : webbrowser.open(browser_addr))
- elif isinstance(address, UnixAddress):
- unix_socket = bind_unix_socket(address.path)
- http_server.add_socket(unix_socket)
- print('Serving HTTP on filesystem socket %r' % address.path)
- else:
- log('error: unexpected address %r', address)
- sys.exit(1)
+ with LocalRepo() as repo:
+ handlers = [ (r"(?P<path>/.*)", BupRequestHandler, dict(repo=repo))]
+ application = tornado.web.Application(handlers, **settings)
+
+ http_server = HTTPServer(application)
+ io_loop_pending = IOLoop.instance()
+
+ if isinstance(address, InetAddress):
+ sockets = tornado.netutil.bind_sockets(address.port, address.host)
+ http_server.add_sockets(sockets)
+ print('Serving HTTP on %s:%d...' % sockets[0].getsockname()[0:2])
+ if opt.browser:
+ browser_addr = 'http://' + address[0] + ':' + str(address[1])
+ io_loop_pending.add_callback(lambda : webbrowser.open(browser_addr))
+ elif isinstance(address, UnixAddress):
+ unix_socket = bind_unix_socket(address.path)
+ http_server.add_socket(unix_socket)
+ print('Serving HTTP on filesystem socket %r' % address.path)
+ else:
+ log('error: unexpected address %r', address)
+ sys.exit(1)

- io_loop = io_loop_pending
- io_loop.start()
+ io_loop = io_loop_pending
+ io_loop.start()

if saved_errors:
log('WARNING: %d errors encountered while saving.\n' % len(saved_errors))
diff --git a/lib/bup/ls.py b/lib/bup/ls.py
index 755c9981..c70fa4e7 100644
--- a/lib/bup/ls.py
+++ b/lib/bup/ls.py
@@ -193,5 +193,6 @@ def via_cmdline(args, out=None, onabort=None):
"""
assert out
opt = opts_from_cmdline(args, onabort=onabort)
- repo = RemoteRepo(argv_bytes(opt.remote)) if opt.remote else LocalRepo()
- return within_repo(repo, opt, out)
+ with RemoteRepo(argv_bytes(opt.remote)) if opt.remote \
+ else LocalRepo() as repo:
+ return within_repo(repo, opt, out)
diff --git a/lib/bup/repo.py b/lib/bup/repo.py
index d52aa0bd..64feeb70 100644
--- a/lib/bup/repo.py
+++ b/lib/bup/repo.py
@@ -6,6 +6,7 @@ from functools import partial
from bup import client, git, vfs
from bup.compat import pending_raise

+
_next_repo_id = 0
_repo_ids = {}

@@ -29,9 +30,6 @@ class LocalRepo:
def close(self):
pass

- def __del__(self):
- self.close()
-
def __enter__(self):
return self

@@ -100,9 +98,6 @@ class RemoteRepo:
self.client.close()
self.client = None

- def __del__(self):
- self.close()
-
def __enter__(self):
return self

diff --git a/test/int/test_metadata.py b/test/int/test_metadata.py
index fd3a00c5..b3ff3a5e 100644
--- a/test/int/test_metadata.py
+++ b/test/int/test_metadata.py
@@ -138,27 +138,27 @@ def test_metadata_method(tmpdir):
ex(bup_path, b'-d', bup_dir, b'index', b'-v', data_path)
ex(bup_path, b'-d', bup_dir, b'save', b'-tvvn', b'test', data_path)
git.check_repo_or_die(bup_dir)
- repo = LocalRepo()
- resolved = vfs.resolve(repo,
- b'/test/latest' + resolve_parent(data_path),
- follow=False)
- leaf_name, leaf_item = resolved[-1]
- m = leaf_item.meta
- WVPASS(m.mtime == test_time2)
- WVPASS(leaf_name == b'foo')
- contents = tuple(vfs.contents(repo, leaf_item))
- WVPASS(len(contents) == 3)
- WVPASSEQ(frozenset(name for name, item in contents),
- frozenset((b'.', b'file', b'symlink')))
- for name, item in contents:
- if name == b'file':
- m = item.meta
- WVPASS(m.mtime == test_time1)
- elif name == b'symlink':
- m = item.meta
- WVPASSEQ(m.symlink_target, b'file')
- WVPASSEQ(m.size, 4)
- WVPASSEQ(m.mtime, 0)
+ with LocalRepo() as repo:
+ resolved = vfs.resolve(repo,
+ b'/test/latest' + resolve_parent(data_path),
+ follow=False)
+ leaf_name, leaf_item = resolved[-1]
+ m = leaf_item.meta
+ WVPASS(m.mtime == test_time2)
+ WVPASS(leaf_name == b'foo')
+ contents = tuple(vfs.contents(repo, leaf_item))
+ WVPASS(len(contents) == 3)
+ WVPASSEQ(frozenset(name for name, item in contents),
+ frozenset((b'.', b'file', b'symlink')))
+ for name, item in contents:
+ if name == b'file':
+ m = item.meta
+ WVPASS(m.mtime == test_time1)
+ elif name == b'symlink':
+ m = item.meta
+ WVPASSEQ(m.symlink_target, b'file')
+ WVPASSEQ(m.size, 4)
+ WVPASSEQ(m.mtime, 0)


def _first_err():
diff --git a/test/int/test_vfs.py b/test/int/test_vfs.py
index f9b3f65c..010b39ec 100644
--- a/test/int/test_vfs.py
+++ b/test/int/test_vfs.py
@@ -161,45 +161,45 @@ def test_misc(tmpdir):
ex((bup_path, b'index', b'-v', data_path))
ex((bup_path, b'save', b'-d', b'100000', b'-tvvn', b'test',
b'--strip', data_path))
- repo = LocalRepo()
-
- ls_tree = exo((b'git', b'ls-tree', b'test', b'symlink')).out
- mode, typ, oidx, name = ls_tree.strip().split(None, 3)
- assert name == b'symlink'
- link_item = vfs.Item(oid=unhexlify(oidx), meta=int(mode, 8))
- wvpasseq(b'file', vfs.readlink(repo, link_item))
-
- ls_tree = exo((b'git', b'ls-tree', b'test', b'file')).out
- mode, typ, oidx, name = ls_tree.strip().split(None, 3)
- assert name == b'file'
- file_item = vfs.Item(oid=unhexlify(oidx), meta=int(mode, 8))
- wvexcept(Exception, vfs.readlink, repo, file_item)
-
- wvpasseq(4, vfs.item_size(repo, link_item))
- wvpasseq(7, vfs.item_size(repo, file_item))
- meta = metadata.from_path(fsencode(__file__))
- meta.size = 42
- fake_item = file_item._replace(meta=meta)
- wvpasseq(42, vfs.item_size(repo, fake_item))
-
- _, fakelink_item = vfs.resolve(repo, b'/test/latest', follow=False)[-1]
- wvpasseq(17, vfs.item_size(repo, fakelink_item))
-
- run_augment_item_meta_tests(repo,
- b'/test/latest/file', 7,
- b'/test/latest/symlink', b'file')
-
- # FIXME: this caused StopIteration
- #_, file_item = vfs.resolve(repo, '/file')[-1]
- _, file_item = vfs.resolve(repo, b'/test/latest/file')[-1]
- file_copy = vfs.copy_item(file_item)
- wvpass(file_copy is not file_item)
- wvpass(file_copy.meta is not file_item.meta)
- wvpass(isinstance(file_copy, tuple))
- wvpass(file_item.meta.user)
- wvpass(file_copy.meta.user)
- file_copy.meta.user = None
- wvpass(file_item.meta.user)
+
+ with LocalRepo() as repo:
+ ls_tree = exo((b'git', b'ls-tree', b'test', b'symlink')).out
+ mode, typ, oidx, name = ls_tree.strip().split(None, 3)
+ assert name == b'symlink'
+ link_item = vfs.Item(oid=unhexlify(oidx), meta=int(mode, 8))
+ wvpasseq(b'file', vfs.readlink(repo, link_item))
+
+ ls_tree = exo((b'git', b'ls-tree', b'test', b'file')).out
+ mode, typ, oidx, name = ls_tree.strip().split(None, 3)
+ assert name == b'file'
+ file_item = vfs.Item(oid=unhexlify(oidx), meta=int(mode, 8))
+ wvexcept(Exception, vfs.readlink, repo, file_item)
+
+ wvpasseq(4, vfs.item_size(repo, link_item))
+ wvpasseq(7, vfs.item_size(repo, file_item))
+ meta = metadata.from_path(fsencode(__file__))
+ meta.size = 42
+ fake_item = file_item._replace(meta=meta)
+ wvpasseq(42, vfs.item_size(repo, fake_item))
+
+ _, fakelink_item = vfs.resolve(repo, b'/test/latest', follow=False)[-1]
+ wvpasseq(17, vfs.item_size(repo, fakelink_item))
+
+ run_augment_item_meta_tests(repo,
+ b'/test/latest/file', 7,
+ b'/test/latest/symlink', b'file')
+
+ # FIXME: this caused StopIteration
+ #_, file_item = vfs.resolve(repo, '/file')[-1]
+ _, file_item = vfs.resolve(repo, b'/test/latest/file')[-1]
+ file_copy = vfs.copy_item(file_item)
+ wvpass(file_copy is not file_item)
+ wvpass(file_copy.meta is not file_item.meta)
+ wvpass(isinstance(file_copy, tuple))
+ wvpass(file_item.meta.user)
+ wvpass(file_copy.meta.user)
+ file_copy.meta.user = None
+ wvpass(file_item.meta.user)

def write_sized_random_content(parent_dir, size, seed):
verbose = 0
@@ -261,38 +261,38 @@ def test_read_and_seek(tmpdir):
environ[b'GIT_DIR'] = bup_dir
environ[b'BUP_DIR'] = bup_dir
git.repodir = bup_dir
- repo = LocalRepo()
- data_path = tmpdir + b'/src'
- os.mkdir(data_path)
- seed = randint(-(1 << 31), (1 << 31) - 1)
- rand = Random()
- rand.seed(seed)
- print('test_read seed:', seed, file=sys.stderr)
- max_size = 2 * 1024 * 1024
- sizes = set((rand.randint(1, max_size) for _ in range(5)))
- sizes.add(1)
- sizes.add(max_size)
- for size in sizes:
- write_sized_random_content(data_path, size, seed)
- ex((bup_path, b'init'))
- ex((bup_path, b'index', b'-v', data_path))
- ex((bup_path, b'save', b'-d', b'100000', b'-tvvn', b'test',
- b'--strip', data_path))
- read_sizes = set((rand.randint(1, max_size) for _ in range(10)))
- sizes.add(1)
- sizes.add(max_size)
- print('test_read src sizes:', sizes, file=sys.stderr)
- print('test_read read sizes:', read_sizes, file=sys.stderr)
- for size in sizes:
- res = resolve(repo, b'/test/latest/' + str(size).encode('ascii'))
- _, item = res[-1]
- wvpasseq(size, vfs.item_size(repo, res[-1][1]))
- validate_vfs_streaming_read(repo, item,
- b'%s/%d' % (data_path, size),
- read_sizes)
- validate_vfs_seeking_read(repo, item,
- b'%s/%d' % (data_path, size),
- read_sizes)
+ with LocalRepo() as repo:
+ data_path = tmpdir + b'/src'
+ os.mkdir(data_path)
+ seed = randint(-(1 << 31), (1 << 31) - 1)
+ rand = Random()
+ rand.seed(seed)
+ print('test_read seed:', seed, file=sys.stderr)
+ max_size = 2 * 1024 * 1024
+ sizes = set((rand.randint(1, max_size) for _ in range(5)))
+ sizes.add(1)
+ sizes.add(max_size)
+ for size in sizes:
+ write_sized_random_content(data_path, size, seed)
+ ex((bup_path, b'init'))
+ ex((bup_path, b'index', b'-v', data_path))
+ ex((bup_path, b'save', b'-d', b'100000', b'-tvvn', b'test',
+ b'--strip', data_path))
+ read_sizes = set((rand.randint(1, max_size) for _ in range(10)))
+ sizes.add(1)
+ sizes.add(max_size)
+ print('test_read src sizes:', sizes, file=sys.stderr)
+ print('test_read read sizes:', read_sizes, file=sys.stderr)
+ for size in sizes:
+ res = resolve(repo, b'/test/latest/' + str(size).encode('ascii'))
+ _, item = res[-1]
+ wvpasseq(size, vfs.item_size(repo, res[-1][1]))
+ validate_vfs_streaming_read(repo, item,
+ b'%s/%d' % (data_path, size),
+ read_sizes)
+ validate_vfs_seeking_read(repo, item,
+ b'%s/%d' % (data_path, size),
+ read_sizes)

def test_contents_with_mismatched_bupm_git_ordering(tmpdir):
bup_dir = tmpdir + b'/bup'
@@ -310,26 +310,26 @@ def test_contents_with_mismatched_bupm_git_ordering(tmpdir):
save_name = strftime('%Y-%m-%d-%H%M%S', localtime(save_utc)).encode('ascii')
ex((bup_path, b'save', b'-tvvn', b'test', b'-d', b'%d' % save_utc,
b'--strip', data_path))
- repo = LocalRepo()
- tip_sref = exo((b'git', b'show-ref', b'refs/heads/test')).out
- tip_oidx = tip_sref.strip().split()[0]
- tip_tree_oidx = exo((b'git', b'log', b'--pretty=%T', b'-n1',
- tip_oidx)).out.strip()
- tip_tree_oid = unhexlify(tip_tree_oidx)
- tip_tree = tree_dict(repo, tip_tree_oid)
-
- name, item = vfs.resolve(repo, b'/test/latest')[2]
- wvpasseq(save_name, name)
- expected = frozenset((x.name, vfs.Item(oid=x.oid, meta=x.meta))
- for x in (tip_tree[name]
- for name in (b'.', b'foo', b'foo.')))
- contents = tuple(vfs.contents(repo, item))
- wvpasseq(expected, frozenset(contents))
- # Spot check, in case tree_dict shares too much code with the vfs
- name, item = next(((n, i) for n, i in contents if n == b'foo'))
- wvpass(S_ISDIR(item.meta))
- name, item = next(((n, i) for n, i in contents if n == b'foo.'))
- wvpass(S_ISREG(item.meta.mode))
+ with LocalRepo() as repo:
+ tip_sref = exo((b'git', b'show-ref', b'refs/heads/test')).out
+ tip_oidx = tip_sref.strip().split()[0]
+ tip_tree_oidx = exo((b'git', b'log', b'--pretty=%T', b'-n1',
+ tip_oidx)).out.strip()
+ tip_tree_oid = unhexlify(tip_tree_oidx)
+ tip_tree = tree_dict(repo, tip_tree_oid)
+
+ name, item = vfs.resolve(repo, b'/test/latest')[2]
+ wvpasseq(save_name, name)
+ expected = frozenset((x.name, vfs.Item(oid=x.oid, meta=x.meta))
+ for x in (tip_tree[name]
+ for name in (b'.', b'foo', b'foo.')))
+ contents = tuple(vfs.contents(repo, item))
+ wvpasseq(expected, frozenset(contents))
+ # Spot check, in case tree_dict shares too much code with the vfs
+ name, item = next(((n, i) for n, i in contents if n == b'foo'))
+ wvpass(S_ISDIR(item.meta))
+ name, item = next(((n, i) for n, i in contents if n == b'foo.'))
+ wvpass(S_ISREG(item.meta.mode))

def test_duplicate_save_dates(tmpdir):
bup_dir = tmpdir + b'/bup'
@@ -348,25 +348,25 @@ def test_duplicate_save_dates(tmpdir):
for i in range(11):
ex((bup_path, b'save', b'-d', b'100000', b'-n', b'test',
data_path))
- repo = LocalRepo()
- res = vfs.resolve(repo, b'/test')
- wvpasseq(2, len(res))
- name, revlist = res[-1]
- wvpasseq(b'test', name)
- wvpasseq((b'.',
- b'1970-01-02-034640-00',
- b'1970-01-02-034640-01',
- b'1970-01-02-034640-02',
- b'1970-01-02-034640-03',
- b'1970-01-02-034640-04',
- b'1970-01-02-034640-05',
- b'1970-01-02-034640-06',
- b'1970-01-02-034640-07',
- b'1970-01-02-034640-08',
- b'1970-01-02-034640-09',
- b'1970-01-02-034640-10',
- b'latest'),
- tuple(sorted(x[0] for x in vfs.contents(repo, revlist))))
+ with LocalRepo() as repo:
+ res = vfs.resolve(repo, b'/test')
+ wvpasseq(2, len(res))
+ name, revlist = res[-1]
+ wvpasseq(b'test', name)
+ wvpasseq((b'.',
+ b'1970-01-02-034640-00',
+ b'1970-01-02-034640-01',
+ b'1970-01-02-034640-02',
+ b'1970-01-02-034640-03',
+ b'1970-01-02-034640-04',
+ b'1970-01-02-034640-05',
+ b'1970-01-02-034640-06',
+ b'1970-01-02-034640-07',
+ b'1970-01-02-034640-08',
+ b'1970-01-02-034640-09',
+ b'1970-01-02-034640-10',
+ b'latest'),
+ tuple(sorted(x[0] for x in vfs.contents(repo, revlist))))

def test_item_read_write():
x = vfs.Root(meta=13)
--
2.30.2

Reply all
Reply to author
Forward
0 new messages