def test_misc(): with no_lingering_errors(): with test_tempdir(b'bup-tvfs-') as tmpdir: bup_dir = tmpdir + b'/bup' environ[b'GIT_DIR'] = bup_dir environ[b'BUP_DIR'] = bup_dir git.repodir = bup_dir data_path = tmpdir + b'/src' os.mkdir(data_path) with open(data_path + b'/file', 'wb+') as tmpfile: tmpfile.write(b'canary\n') symlink(b'file', data_path + b'/symlink') 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)) repo = LocalRepo() wvstart('readlink') 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) wvstart('item_size') 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)) wvstart('augment_item_meta') run_augment_item_meta_tests(repo, b'/test/latest/file', 7, b'/test/latest/symlink', b'file') wvstart('copy_item') # 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 main(argv): o = options.Options(optspec) opt, flags, extra = o.parse_bytes(argv[1:]) verbosity = (opt.verbose or 0) if not opt.quiet else -1 if opt.remote: opt.remote = argv_bytes(opt.remote) if opt.outdir: opt.outdir = argv_bytes(opt.outdir) git.check_repo_or_die() if not extra: o.fatal('must specify at least one filename to restore') exclude_rxs = parse_rx_excludes(flags, o.fatal) owner_map = {} for map_type in ('user', 'group', 'uid', 'gid'): owner_map[map_type] = parse_owner_mappings(map_type, flags, o.fatal) if opt.outdir: 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 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: 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) die_if_errors()
from __future__ import absolute_import, print_function import os, time from wvpytest import * from bup import index, metadata from bup.compat import fsencode from bup.helpers import mkdirp, resolve_parent import bup.xstat as xstat lib_t_dir = os.path.dirname(fsencode(__file__)) def test_index_basic(): cd = os.path.realpath(os.path.join(lib_t_dir, b'../')) WVPASS(cd) sd = os.path.realpath(cd + b'/sampledata') WVPASSEQ(resolve_parent(cd + b'/sampledata'), sd) WVPASSEQ(os.path.realpath(cd + b'/sampledata/x'), sd + b'/x') WVPASSEQ(os.path.realpath(cd + b'/sampledata/var/abs-symlink'), sd + b'/var/abs-symlink-target') WVPASSEQ(resolve_parent(cd + b'/sampledata/var/abs-symlink'), sd + b'/var/abs-symlink') def test_index_writer(tmpdir): orig_cwd = os.getcwd() try: os.chdir(tmpdir)
src_file, src_line, src_func, src_txt = bt[-4] msg = 'saved_errors ' + repr(helpers.saved_errors) print('! %-70s %s' % ('%s:%-4d %s' % (basename(src_file), src_line, msg), 'FAILED')) sys.stdout.flush() fail_if_errors() helpers.clear_errors() yield fail_if_errors() helpers.clear_errors() # Assumes (of course) this file is at the top-level of the source tree _bup_tmp = realpath(dirname(fsencode(__file__))) + b'/t/tmp' try: os.makedirs(_bup_tmp) except OSError as e: if e.errno != errno.EEXIST: raise @contextmanager def test_tempdir(prefix): initial_failures = wvfailure_count() tmpdir = tempfile.mkdtemp(dir=_bup_tmp, prefix=prefix) yield tmpdir if wvfailure_count() == initial_failures: subprocess.call(['chmod', '-R', 'u+rwX', tmpdir]) subprocess.call(['rm', '-rf', tmpdir])